Add PrintBP + few fix in Debugger + simple string-address resolution in localdebugger

This commit is contained in:
Clement Rouault
2017-05-19 15:39:32 +02:00
parent bc3c033e84
commit d24e62e319
4 changed files with 65 additions and 19 deletions
+8
View File
@@ -20,6 +20,14 @@ TODO:
- if I have a ntdll32 and ntdll64: both would have the same name in the list..
- Il y a un truc fucked-up avec le add_bp(target=XXX)
- j'attends a avoir un thread/process mais je fait des check sur TID/PID..
- Ecrire un test et fix..
- windows.alpc | windows.rpc
- Clean + doc + samples
- remotectypes
- pretty sur I can get rid of PointerToStruct64/PointerToStruct32
+10 -2
View File
@@ -70,7 +70,7 @@ class X64ArgumentRetriever(object):
def get_arg(self, nb, proc, thread):
if nb < len(self.REG_ARGS):
return getattr(thread.context, self.REG_ARGS[nb])
return proc.read_dword(thread.context.sp + 8 + (8 * nb))
return proc.read_qword(thread.context.sp + 8 + (8 * nb))
## Behaviour breakpoint !
class FunctionParamDumpBP(Breakpoint):
@@ -157,4 +157,12 @@ class FunctionBP(FunctionCallBP, FunctionParamDumpBP):
- Extract the arguments of the functions
- Break at the return of the function
"""
"""
class PrintBP(Breakpoint):
def __init__(self, addr, format):
super(PrintBP, self).__init__(addr)
self.format = format
def trigger(self, dbg, exc):
print(self.format.format(dbg=dbg, exc=exc, ctx=dbg.current_thread.context))
+16 -13
View File
@@ -133,7 +133,7 @@ class Debugger(object):
self.current_process = None
self.current_thread = None
if target.pid == self.target.pid:
if self.target and target.pid == self.target.pid:
self.target = None
windows.winproxy.DebugActiveProcessStop(target.pid)
@@ -254,7 +254,7 @@ class Debugger(object):
def _setup_breakpoint_BP(self, bp, target):
if not isinstance(target, WinProcess):
raise ValueError("SETUP STANDARD_BP on {0}".format(target))
raise ValueError("Cannot setup STANDARD_BP on {0}".format(target))
addr = self._resolve(bp.addr, target)
if addr is None:
@@ -621,12 +621,12 @@ class Debugger(object):
if self.current_process.bitness == 32 and pe.bitness == 64:
name_sufix = "64"
if not load_dll.lpImageName:
return pe.export_name + name_sufix
try:
addr = self.current_process.read_ptr(load_dll.lpImageName)
except:
addr = None
addr = None
if load_dll.lpImageName:
try:
addr = self.current_process.read_ptr(load_dll.lpImageName)
except:
pass
if not addr:
pe = windows.pe_parse.GetPEFile(load_dll.lpBaseOfDll, self.current_process)
@@ -659,6 +659,7 @@ class Debugger(object):
self.current_process = WinProcess._from_handle(proc_handle.value)
self.current_thread = WinThread._from_handle(thread_handle.value)
dbgprint("New process: {0}".format(self.current_process), "DBG")
self.threads[self.current_thread.tid] = self.current_thread
self._explicit_single_step[self.current_thread.tid] = False
@@ -710,8 +711,10 @@ class Debugger(object):
thread_handle = HANDLE()
cp_handle = windows.current_process.handle
winproxy.DuplicateHandle(cp_handle, create_thread.hThread, cp_handle, ctypes.byref(thread_handle), dwOptions=DUPLICATE_SAME_ACCESS)
self.current_thread = WinThread._from_handle(thread_handle.value)
self.threads[self.current_thread.tid] = self.current_thread
new_thread = WinThread._from_handle(thread_handle.value)
self.threads[new_thread.tid] = new_thread
# The new thread is on the thread pool: we can now update the debugger state
self._update_debugger_state(debug_event)
self._explicit_single_step[self.current_thread.tid] = False
self._breakpoint_to_reput[self.current_thread.tid] = []
self._hardware_breakpoint[self.current_thread.tid] = {}
@@ -818,10 +821,10 @@ class Debugger(object):
elif target is not None:
# Check that targets are accepted
if target not in self.processes.values() + self.threads.values():
if target == self.target: # Original target (that have not been lauched yet)
# if target == self.target: # Original target (that have not been lauched yet)
return self.add_pending_breakpoint(bp, target)
else:
raise ValueError("Unknown target {0}".format(target))
# else:
# raise ValueError("Unknown target {0}".format(target))
return self._setup_breakpoint(bp, target)
def del_bp(self, bp, targets=None):
+31 -4
View File
@@ -32,6 +32,7 @@ class LocalDebugger(object):
self.veh_depth = 0
self.current_exception = None
self.exceptions_stack = [None]
self.current_process = windows.current_process
@contextmanager
def NewCurrentException(self, exc):
@@ -64,6 +65,31 @@ class LocalDebugger(object):
self._reput_breakpoint[windows.current_thread.tid] = self.breakpoints[addr], single_step
return self.single_step()
def _local_resolve(self, addr):
if not isinstance(addr, basestring):
return addr
dll, api = addr.split("!")
dll = dll.lower()
modules = {m.name[:-len(".dll")] if m.name.endswith(".dll") else m.name : m for m in windows.current_process.peb.modules}
mod = None
if dll in modules:
mod = [modules[dll]]
if not mod:
return None
# TODO: optim exports are the same for whole system (32 vs 64 bits)
# I don't have to reparse the exports each time..
# Try to interpret api as an int
try:
api_int = int(api, 0)
return mod[0].baseaddr + api_int
except ValueError:
pass
exports = mod[0].pe.exports
if api not in exports:
dbgprint("Error resolving <{0}> in local process".format(addr, target), "DBG")
raise ValueError("Unknown API <{0}> in DLL {1}".format(api, dll))
return exports[api]
def callback(self, exc):
with self.NewCurrentException(exc):
return self.handle_exception(exc)
@@ -134,10 +160,11 @@ class LocalDebugger(object):
raise NotImplementedError("Unknow BP type {0}".format(bp.type))
if targets is not None:
raise ValueError("LocalDebugger: STANDARD_BP doest not support targets {0}".format(targets))
self.breakpoints[bp.addr] = bp
self._memory_save[bp.addr] = windows.current_process.read_memory(bp.addr, 1)
with windows.utils.VirtualProtected(bp.addr, 1, PAGE_EXECUTE_READWRITE):
windows.current_process.write_memory(bp.addr, "\xcc")
addr = self._local_resolve(bp.addr)
self.breakpoints[addr] = bp
self._memory_save[addr] = windows.current_process.read_memory(addr, 1)
with windows.utils.VirtualProtected(addr, 1, PAGE_EXECUTE_READWRITE):
windows.current_process.write_memory(addr, "\xcc")
return
def add_bp_hxbp(self, bp, targets=None):