Me estoy iniciando en esto del PyDbg que es un debugger programatico en python y me ha maravillado.
Tiene algunos bugs pero el codigo fuente es muy claro, yo ya he corregido uno (el de los bps hw) y ampliado alguna funcion.
El mayor escollo con que he topado es el de siempre, los metodos anti-debug, he conseguido limpiar algunas huellas pero llegado al metodo de las HeapFlags me he quedado estancado.
La primera solucion fue crear mi funcion de carga del proceso, myload, que crea el proceso suspendido, sustituye el entry point por un JMP EIP, lo resume, y luego attachea el debugger sustituyendo el entry point con los bytes originales. Funciona a veces, pero si lo uso no van los bps hardware, y me interesa usarlos para cargar el UnpackArmadillo6 que os adjunte el otro dia.
No se si pastearos aqui el codigo o que, bueno alla va, sera un rollo, lo he comentado algo:
Código:
def myload (self, path_to_file, command_line=None, create_new_console=None, show_window = None):
pi = PROCESS_INFORMATION()
si = STARTUPINFO()
si.cb = sizeof(si)
# these flags control the main window display of the debuggee.
if not show_window:
si.dwFlags = 0x1
si.wShowWindow = 0x0
# CreateProcess() seems to work better with command line arguments when the path_to_file is passed as NULL.
if command_line:
command_line = path_to_file + " " + command_line
path_to_file = 0
creation_flags = 4 # CREATE_SUSPENDED
if create_new_console:
creation_flags |= CREATE_NEW_CONSOLE
success = kernel32.CreateProcessA(c_char_p(path_to_file),
c_char_p(command_line),
0,
0,
0,
creation_flags,
0,
0,
byref(si),
byref(pi))
if not success:
raise pdx("CreateProcess()", True)
# store the handles we need.
self.pid = pi.dwProcessId
self.h_process = pi.hProcess
# resolve the PEB address.
selector_entry = LDT_ENTRY()
thread_context = self.get_thread_context(pi.hThread)
if not kernel32.GetThreadSelectorEntry(pi.hThread, thread_context.SegFs, byref(selector_entry)):
self.win32_error("GetThreadSelectorEntry()")
teb = selector_entry.BaseLow
teb += (selector_entry.HighWord.Bits.BaseMid << 16) + (selector_entry.HighWord.Bits.BaseHi << 24)
# add this TEB to the internal dictionary.
self.tebs[pi.dwThreadId] = teb
self.h_thread = pi.hThread
self.dwThreadId = pi.dwThreadId
self.peb = self.read_process_memory(teb + 0x30, 4)
self.peb = struct.unpack("<L", self.peb)[0]
pef = pefile.PE(path_to_file)
address = pef.OPTIONAL_HEADER.AddressOfEntryPoint + pef.OPTIONAL_HEADER.ImageBase
# save the original byte at the requested breakpoint address.
original_bytes = self.read_process_memory(address, 2)
self.write_process_memory(address, "\xEB\xFE") #JMP EIP
kernel32.ResumeThread(pi.hThread)
self.attach(self.pid)
self.write_process_memory(address, original_bytes, 2)
kernel32.FlushInstructionCache(self.h_process, 0, 0)
he usado tambien pefile la libreria para obetner el entry point del fichero aa cargar, nada, lo dicho esta nueva herrramienta merece la pena
Hay otra forma de borrar las heapflags? que no sea la de la clave del registro(aunque me acabare rindiendo a ella), y por cierto alguien sabe que pasaria si cambiase las HeapFlags en memoria con un ReadProcessMemory??
Sludos,