Class/Module Index [+]

Quicksearch

Rex::RopBuilder::RopCollect

Public Class Methods

new(file="") click to toggle source
# File lib/rex/ropbuilder/rop.rb, line 90
def initialize(file="")
        @stdio = Rex::Ui::Text::Output::Stdio.new
        @file = file if not file.empty?
        @bin = Metasm::AutoExe.decode_file(file) if not file.empty?
        @disassembler = @bin.disassembler if not @bin.nil?
        if @disassembler
                @disassembler.cpu = Metasm::Ia32.new('386_common')
        end
        super()
end

Public Instance Methods

collect(depth, pattern) click to toggle source
# File lib/rex/ropbuilder/rop.rb, line 101
def collect(depth, pattern)
        matches = []
        gadgets = []

        # find matches by scanning for the pattern
        matches = @disassembler.pattern_scan(pattern)
        if @bin.kind_of?(Metasm::PE)
                @bin.sections.each do |section|
                        next if section.characteristics.include? 'MEM_EXECUTE'
                        # delete matches if the address is outside the virtual address space
                        matches.delete_if do |ea|
                                va = section.virtaddr + @bin.optheader.image_base
                                ea >= va and ea < va + section.virtsize
                        end
                end
        elsif @bin.kind_of?(Metasm::ELF)
                @bin.segments.each do |seg|
                        next if seg.flags.include? 'X'
                        matches.delete_if do |ea|
                                ea >= seg.vaddr and ea < seg.vaddr + seg.memsz
                        end
                end
        elsif @bin.kind_of?(Metasm::MachO)
                @bin.segments.each do |seg|
                        next if seg.initprot.include? 'EXECUTE'
                        matches.delete_if do |ea|
                                ea >= seg.virtaddr and ea < seg.virtaddr + seg.filesize
                        end
                end
        end

        gadgets = process_gadgets(matches, depth)
        gadgets.each do |gadget|
                @gadgets << gadget
        end
        gadgets
end
color_pattern(gadget, disasm, addrs, p) click to toggle source
# File lib/rex/ropbuilder/rop.rb, line 164
def color_pattern(gadget, disasm, addrs, p)
        idx = disasm.index(p)
        if idx.nil?
                print_msg(gadget[:disasm])
                return
        end

        disasm = disasm.insert(idx, "%bld%grn")

        asm = ""
        cnt = 0
        colors = false
        disasm.each_line do |line|
                # if we find this then we are in the matching area
                if line.index(/\%bld\%grn/)
                        colors = true
                end
                asm << "%clr" + addrs[cnt] + "\t"

                # color the remaining parts of the gadget
                if colors and line.index("%bld%grn").nil?
                        asm << "%bld%grn" + line
                else
                        asm << line
                end

                cnt += 1
        end
        asm << "%clr\n"
        print_msg(asm)
end
pattern_search(pattern) click to toggle source
# File lib/rex/ropbuilder/rop.rb, line 139
def pattern_search(pattern)
        p = Regexp.new("(" + pattern + ")")
        matches = []

        @gadgets.each do |gadget|
                disasm = ""
                addrs = []

                gadget[:disasm].each_line do |line|
                        addr, asm = line.split("\t", 2)
                        addrs << addr
                        disasm << asm
                end

                if gadget[:raw] =~ p or gadget[:disasm] =~ p or disasm =~ p
                        matches << {:gadget => gadget, :disasm => disasm, :addrs => addrs}
                end
        end
        matches.each do |match|
                @stdio.print_status("gadget with address: %bld%cya#{match[:gadget][:address]}%clr matched")
                color_pattern(match[:gadget], match[:disasm], match[:addrs], p)
        end
        matches
end
process_gadgets(rets, num) click to toggle source
# File lib/rex/ropbuilder/rop.rb, line 196
def process_gadgets(rets, num)
        ret = {}
        gadgets = []
        tmp = []
        rets.each do |ea|
                insn = @disassembler.disassemble_instruction(ea)
                next if not insn

                xtra = insn.bin_length

                1.upto(num) do |x|
                        addr = ea - x

                        # get the disassembled instruction at this address
                        di = @disassembler.disassemble_instruction(addr)

                        # skip invalid instructions
                        next if not di
                        next if di.opcode.props[:setip]
                        next if di.opcode.props[:stopexec]

                        # get raw bytes
                        buf = @disassembler.read_raw_data(addr, x + xtra)
                        

                        # make sure disassembling forward leads to our instruction
                        next if not ends_with_addr(buf, addr, ea)

                        dasm = ""
                        while addr <= ea
                                di = @disassembler.disassemble_instruction(addr)
                                dasm << ("0x%08x:\t" % addr) + di.instruction.to_s + "\n"
                                addr = addr + di.bin_length
                        end

                        if not tmp.include?(ea)
                                tmp << ea
                        else
                                next
                        end
                        # otherwise, we create a new tailchunk and add it to the list
                        ret = {:file => @file, :address => ("0x%08x" % (ea - x)), :raw => buf, :disasm => dasm}
                        gadgets << ret
                end
        end
        gadgets
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.