mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
Add PrintBP + few fix in Debugger + simple string-address resolution in localdebugger
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user