# This file is part of Metasm, the Ruby assembly manipulation suite # Copyright (C) 2006-2009 Yoann GUILLOT # # Licence is LGPL, see LICENCE in the top-level directory # This creates/uses a ring0 driver for tracing a program # x86/windows/singlecore only # the scripts allows interacting with the driver # you still have to set the target thread in singlestep mode (eg using Debugger) # How does it work: # the driver hooks the IDT int1/int0f (NOT SMP PROOF) # on int1, it logs eip in a memory buffer # on int0f, it returns the memory buffer (memcopy to mem pointed by eax) # the buffer 1st dword is the number of used dwords in the buffer (0 = empty) # on overflow, eips are lost require 'metasm' include Metasm $drv = 'r0trace.sys' # size of the eip buffer (in dwords) TRACE_BUF_SZ = 4*1024*1024-4 if not File.exist? $drv PE.assemble(Ia32.new, <DriverUnload call setup_idt xor eax, eax mov [buf], eax // buf used size ret unload: // XXX smp call get_idt push [oldi1+4] push [oldi1] pop [eax+8*1] pop [eax+8*1+4] push [oldi15+4] push [oldi15] pop [eax+8*15] pop [eax+8*15+4] xor eax, eax ret setup_idt: // XXX smp call get_idt push [eax+8*1] push [eax+8*1+4] pop [oldi1+4] pop [oldi1] push [eax+8*15] push [eax+8*15+4] pop [oldi15+4] pop [oldi15] mov ecx, i1hook mov [eax+8*1], ecx mov [eax+8*1+4], ecx mov ecx, cs mov [eax+8*1+2], cx mov word ptr [eax+8*1+4], (15 + (3<<5) + (1<<7)) << 8 // call gate mov ecx, i15hook mov [eax+8*15], ecx mov [eax+8*15+4], ecx mov ecx, cs mov [eax+8*15+2], cx mov word ptr [eax+8*15+4], (15 + (3<<5) + (1<<7)) << 8 // call gate ret get_idt: sub esp, 8 sidt [esp] mov eax, [esp+2] add esp, 8 ret i1hook: push eax mov eax, buf cmp [eax], bufsz jae 1f inc [eax] add eax, [eax] push [esp+4] pop [eax] 1: pop eax iret i15hook: push esi push edi push ecx mov esi, buf mov edi, eax mov ecx, [esi] inc ecx rep movsd mov dword ptr [buf], 0 pop ecx pop edi pop esi iret EOS end DynLdr.new_api_c <