Class/Module Index [+]

Quicksearch

Rex::MachScan::Scanner::JmpRegScanner

Public Instance Methods

_build_byte_list(base, regnums) click to toggle source

build a list for regex of the possible bytes, based on a base byte and a list of register numbers..

# File lib/rex/machscan/scanner.rb, line 73
def _build_byte_list(base, regnums)
        regnums.collect { |regnum| Regexp.escape((base | regnum).chr) }.join('')
end
_parse_ret(data) click to toggle source
# File lib/rex/machscan/scanner.rb, line 87
def _parse_ret(data)
        if data.length == 1
                return "ret"
        else
                return "retn 0x%04x" % data[1, 2].unpack('v')[0]
        end
end
_ret_size(offset) click to toggle source
# File lib/rex/machscan/scanner.rb, line 77
def _ret_size(offset)
        case mach.read(offset, 1)
        when "\xc3"
                        return 1
        when "\xc2"
                        return 3
        end
        $stderr.puts("Invalid return instruction")
end
config(param) click to toggle source
# File lib/rex/machscan/scanner.rb, line 52
def config(param)
        regnums = param['args']

        # build a list of the call bytes
        calls  = _build_byte_list(0xd0, regnums - [4]) # note call esp's don't work..
        jmps   = _build_byte_list(0xe0, regnums)
        pushs1 = _build_byte_list(0x50, regnums)
        pushs2 = _build_byte_list(0xf0, regnums)

        regexstr = '('
        if !calls.empty?
                        regexstr += "\xff[#{calls}]|"
        end

        regexstr += "\xff[#{jmps}]|([#{pushs1}]|\xff[#{pushs2}])(\xc3|\xc2..))"

        self.regex = Regexp.new(regexstr, nil, 'n')
end
scan_segment(segment, param={}) click to toggle source
# File lib/rex/machscan/scanner.rb, line 95
def scan_segment(segment, param={})
        base_addr = segment.vmaddr
        segment_offset = segment.fileoff
        offset = segment_offset

        hits = []

        while (offset = mach.index(regex, offset)) != nil

                vaddr = base_addr + (offset - segment_offset)
                message = ''

                parse_ret = false

                byte1 = mach.read(offset, 1).unpack("C*")[0]

                if byte1 == 0xff
                        byte2   = mach.read(offset+1, 1).unpack("C*")[0]
                        regname = Rex::Arch::X86.reg_name32(byte2 & 0x7)

                        case byte2 & 0xf8
                        when 0xd0
                                        message = "call #{regname}"
                                        offset += 2
                        when 0xe0
                                        message = "jmp #{regname}"
                                        offset += 2
                        when 0xf0
                                        retsize = _ret_size(offset+2)
                                        message = "push #{regname}; " + _parse_ret(mach.read(offset+2, retsize))
                                        offset += 2 + retsize
                        else
                                        raise "wtf"
                        end
                else
                        regname = Rex::Arch::X86.reg_name32(byte1 & 0x7)
                        retsize = _ret_size(offset+1)
                        message = "push #{regname}; " + _parse_ret(mach.read(offset+1, retsize))
                        offset += 1 + retsize
                end

                hits << [ vaddr, message ]
        end

        return hits
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.