class Tracer

SYMOPT = 4|0x80000 # defered_load no_prompt Metasm::WinAPI.new_api dll, 'SymInitialize', 'III I' Metasm::WinAPI.new_api dll, 'SymGetOptions', 'I' Metasm::WinAPI.new_api dll, 'SymSetOptions', 'I I' Metasm::WinAPI.new_api dll, 'SymSetSearchPath', 'IP I' Metasm::WinAPI.new_api dll, 'SymLoadModule64', 'IIPIIII I' # ???ull? Metasm::WinAPI.new_api dll, 'SymFromAddr', 'IIIPP I' # handle ull_addr poffset psym

Public Class Methods

new(*a) click to toggle source
Calls superclass method
# File samples/dbghelp.rb, line 86
def initialize(*a)
        super(*a)
        loop
        puts 'finished'
end

Public Instance Methods

do_singlestep(pid, tid) click to toggle source

dumps the opcode at eip, sets the trace flag

# File samples/wintrace.rb, line 61
def do_singlestep(pid, tid)
        ctx = get_context(pid, tid)
        eip = ctx[:eip]

        if l = @label[eip]
                puts l + ':'
        end
        if $VERBOSE
        bin = @mem[pid][eip, 16]
        di = @prog.cpu.decode_instruction(Metasm::EncodedData.new(bin), eip)
        puts "#{'%08X' % eip} #{di.instruction}"
        end

        ctx[:eflags] |= 0x100
end
handler_exception(pid, tid, info) click to toggle source
Calls superclass method
# File samples/wintrace.rb, line 35
def handler_exception(pid, tid, info)
        do_singlestep(pid, tid) if @hthread[pid] and @hthread[pid][tid]
        case info.code
        when Metasm::WinAPI::STATUS_SINGLE_STEP
                Metasm::WinAPI::DBG_CONTINUE
        else super(pid, tid, info)
        end
end
handler_loaddll(pid, tid, info) click to toggle source
# File samples/dbghelp.rb, line 105
def handler_loaddll(pid, tid, info)
        pe = Metasm::LoadedPE.load(@mem[pid][info.imagebase, 0x1000000])
        pe.decode_header
        pe.decode_exports
        return if not pe.export
        libname = pe.export.libname
        puts "loaddll: #{libname} @#{'%x' % info.imagebase}"
        h = @hprocess[pid]
        dl = Metasm::DynLdr
        dl.symloadmodule64(h, 0, libname, 0, info.imagebase, pe.optheader.image_size)
        symstruct = [0x58].pack('L') + 0.chr*4*19 + [512].pack('L')   # sizeofstruct, ..., nameszmax
        text = pe.sections.find { |s| s.name == '.text' }
        # XXX should SymEnumSymbols, but win32api callbacks sucks
        text.rawsize.times { |o|
                sym = symstruct + 0.chr*512  # name concat'ed after the struct
                off = 0.chr*8
                if dl.symfromaddr(h, info.imagebase+text.virtaddr+o, off, sym) and off.unpack('L').first == 0
                        symnamelen = sym[19*4, 4].unpack('L').first
                        puts ' %x %s' % [text.virtaddr+o, sym[0x54, symnamelen]]
                end
                puts '  %x/%x' % [o, text.rawsize] if $VERBOSE and o & 0xffff == 0
        }
        puts
end
handler_newprocess(pid, tid, info) click to toggle source
# File samples/dbghelp.rb, line 92
def handler_newprocess(pid, tid, info)
        puts "newprocess: init symsrv"

        h = @hprocess[pid]
        dl = Metasm::DynLdr
        dl.syminitialize(h, 0, 0)
        dl.symsetoptions(dl.symgetoptions|dl::SYMOPT_DEFERRED_LOADS|dl::SYMOPT_NO_PROMPTS)
        sympath = ENV['_NT_SYMBOL_PATH'] || 'srv**symbols*http://msdl.microsoft.com/download/symbols'
        dl.symsetsearchpath(h, sympath.dup)   # dup cause ENV is frozen and make WinAPI raises

        Metasm::WinAPI::DBG_CONTINUE
end
handler_newthread(pid, tid, info) click to toggle source
# File samples/wintrace.rb, line 30
def handler_newthread(pid, tid, info)
        do_singlestep(pid, tid)
        Metasm::WinAPI::DBG_CONTINUE
end
hide_debugger(pid, tid, info) click to toggle source

resets the DebuggerPresent field of the PEB

# File samples/wintrace.rb, line 78
def hide_debugger(pid, tid, info)
        peb = @mem[pid][info.threadlocalbase + 0x30, 4].unpack('L').first
        @mem[pid][peb + 2, 2] = [0].pack('S')
end