Skip to content

Commit e4c0f86

Browse files
committed
Adapted symbol code & samples for py3 compat
1 parent 2e48f90 commit e4c0f86

5 files changed

Lines changed: 154 additions & 4 deletions

File tree

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import sys
2+
import os.path
3+
import pprint
4+
import argparse
5+
sys.path.append(os.path.abspath(__file__ + "\..\.."))
6+
7+
import windows
8+
import windows.debug
9+
import windows.generated_def as gdef
10+
11+
class FollowNtCreateFile(windows.debug.FunctionBP):
12+
TARGET = windows.winproxy.NtCreateFile
13+
14+
def trigger(self, dbg, exc):
15+
params = self.extract_arguments(dbg.current_process, dbg.current_thread)
16+
filename = params["ObjectAttributes"].contents.ObjectName.contents.str
17+
handle_addr = params["FileHandle"].value
18+
self.data = (filename, handle_addr)
19+
self.break_on_ret(dbg, exc)
20+
21+
def ret_trigger(self, dbg, exc):
22+
filename, handle_addr = self.data
23+
ret_value = dbg.current_thread.context.func_result # EAX / RAX depending of bitness
24+
if ret_value:
25+
return # Creation failed
26+
handle_value = dbg.current_process.read_ptr(handle_addr)
27+
return dbg.on_file_create(filename, handle_value)
28+
29+
class FollowReadFile(windows.debug.FunctionBP):
30+
TARGET = windows.winproxy.ReadFile
31+
32+
def trigger(self, dbg, exc):
33+
params = self.extract_arguments(dbg.current_process, dbg.current_thread)
34+
self.data = params
35+
if params["hFile"] in dbg.followed_handles:
36+
self.break_on_ret(dbg, exc)
37+
38+
def ret_trigger(self, dbg, exc):
39+
params = self.data
40+
ret_value = dbg.current_thread.context.func_result
41+
if not ret_value: # Read failed
42+
return
43+
buffer_size = dbg.current_process.read_dword(params["lpNumberOfBytesRead"])
44+
read_data = dbg.current_process.read_memory(params["lpBuffer"], buffer_size)
45+
return dbg.on_file_read(params["hFile"], read_data)
46+
47+
class FollowWriteFile(windows.debug.FunctionBP):
48+
TARGET = windows.winproxy.WriteFile
49+
50+
def trigger(self, dbg, exc):
51+
params = self.extract_arguments(dbg.current_process, dbg.current_thread)
52+
write_data = dbg.current_process.read_memory(params["lpBuffer"], params["nNumberOfBytesToWrite"])
53+
return dbg.on_file_write(params["hFile"], write_data)
54+
55+
class FollowCloseFile(windows.debug.FunctionBP):
56+
TARGET = windows.winproxy.CloseHandle
57+
58+
def trigger(self, dbg, exc):
59+
params = self.extract_arguments(dbg.current_process, dbg.current_thread)
60+
return dbg.on_file_close(params["hObject"])
61+
62+
63+
class FileFollowDebugger(windows.debug.Debugger):
64+
def __init__(self, target, filenames):
65+
super(FileFollowDebugger, self).__init__(target)
66+
self.filenames = filenames
67+
self.followed_handles = {}
68+
self.add_bp(FollowNtCreateFile())
69+
self.add_bp(FollowReadFile())
70+
self.add_bp(FollowWriteFile())
71+
self.add_bp(FollowCloseFile())
72+
73+
def on_exception(self, exc):
74+
if exc.ExceptionRecord.ExceptionCode == gdef.EXCEPTION_BREAKPOINT:
75+
return gdef.DBG_CONTINUE
76+
return gdef.DBG_EXCEPTION_NOT_HANDLED
77+
78+
def on_file_create(self, filename, handle):
79+
if any(filename.lower().endswith(fname) for fname in self.filenames):
80+
self.followed_handles[handle] = filename
81+
print("Opened <{0}> as handle <{1:#x}>".format(filename, handle))
82+
83+
84+
def on_file_read(self, handle, data):
85+
filename = self.followed_handles[handle]
86+
print("Read from <{0}> ({1:#x})".format(filename, handle))
87+
print(repr(data))
88+
89+
def on_file_write(self, handle, data):
90+
filename = self.followed_handles[handle]
91+
print("Write to <{0}> ({1:#x})".format(filename, handle))
92+
print(repr(data))
93+
94+
def on_file_close(self, handle):
95+
try:
96+
filename = self.followed_handles[handle]
97+
except KeyError as e:
98+
return
99+
print("Closing handle <{0:#x}> to <{1}>".format(handle, filename))
100+
del self.followed_handles[handle]
101+
102+
103+
104+
if __name__ == "__main__":
105+
parser = argparse.ArgumentParser(prog=__file__)
106+
parser.add_argument('exe')
107+
parser.add_argument('--cmdline', default="")
108+
parser.add_argument('files', nargs="+")
109+
args = parser.parse_args()
110+
print(args)
111+
112+
target = windows.utils.create_process(args.exe, args.cmdline.split(), dwCreationFlags=gdef.DEBUG_PROCESS, show_windows=True)
113+
114+
dbg = FileFollowDebugger(target, args.files)
115+
dbg.loop()
116+
print("BYE")
117+
118+

samples/debug/symbol_debugger.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def trigger(self, dbg, exc):
3030
dbg.current_process.exit()
3131
print("")
3232

33-
dbg = windows.debug.SymbolDebugger.debug(r"c:\windows\system32\notepad.exe")
33+
dbg = windows.debug.SymbolDebugger.debug(b"c:\\windows\\system32\\notepad.exe")
3434
dbg.add_bp(MyInfoBP("kernelbase!CreateFileInternal+2"))
3535
dbg.add_bp(MyInfoBP("ntdll!LdrpInitializeProcess"))
3636
dbg.loop()

samples/service/service_demo.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import windows
2+
import windows.generated_def as gdef
3+
4+
print("Listing the first 3 services:")
5+
for service in windows.system.services[:3]:
6+
print(" * {0}".format(service))
7+
print("")
8+
9+
TARGET_SERVICE = "TapiSrv"
10+
print("Retriving service <{0}>".format(TARGET_SERVICE))
11+
service = windows.system.services[TARGET_SERVICE]
12+
print("{0}".format(service))
13+
print(" - name: {0!r}".format(service.name))
14+
print(" - description: {0!r}".format(service.description))
15+
print(" - state: {0!r}".format(service.status.state))
16+
print(" - type: {0!r}".format(service.status.type))
17+
print(" - process: {0!r}".format(service.process))
18+
print(" - security-description: {0}".format(service.security_descriptor))
19+
20+
if service.status.state == gdef.SERVICE_RUNNING:
21+
print("Service already running, not trying to start it")
22+
else:
23+
print("Trying to start the service")
24+
service.start()
25+
while service.status.state != gdef.SERVICE_RUNNING:
26+
pass
27+
print("Service started !")
28+
print("{0}".format(service))
29+
print(" - state: {0!r}".format(service.status.state))
30+
print(" - process: {0!r}".format(service.process))

windows/debug/symbols.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ def pdb(self):
296296
return LoadedPdbName
297297

298298
def __repr__(self):
299-
pdb_basename = self.LoadedPdbName.split("\\")[-1]
299+
pdb_basename = self.LoadedPdbName.split(b"\\")[-1]
300300
return '<{0} name="{1}" type={2} pdb="{3}" addr={4:#x}>'.format(type(self).__name__, self.name, self.type.value.name, pdb_basename, self.addr)
301301

302302

@@ -483,7 +483,8 @@ def search(self, mask, mod=0, tag=0, options=gdef.SYMSEARCH_ALLITEMS, callback=N
483483
callback = ctypes.WINFUNCTYPE(gdef.BOOL, ctypes.POINTER(SymbolInfo), gdef.ULONG , ctypes.py_object)(callback)
484484

485485
addr = getattr(mod, "addr", mod) # Retrieve mod.addr, else us the value directly
486-
486+
# Expect A-string
487+
mask = windows.pycompat.raw_encode(mask)
487488
windows.winproxy.SymSearch(self.handle, gdef.DWORD64(addr), 0, tag, mask, 0, callback, res, options)
488489
for sym in res:
489490
sym.resolver = self

windows/winproxy/apis/dbghelp.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import ctypes
22
import windows.generated_def as gdef
3+
from windows.pycompat import int_types
34

45
from ..apiproxy import ApiProxy, NeededParameter
56
from ..error import fail_on_zero
@@ -14,7 +15,7 @@ class DbgHelpProxy(ApiProxy):
1415
# !! this code loose a ref to obj.
1516
# Should still work as our calling-caller method keep a ref
1617
def transform_pyobject_to_pvoid(obj):
17-
if obj is None or isinstance(obj, (int, long)):
18+
if obj is None or isinstance(obj, int_types):
1819
return obj
1920
return ctypes.POINTER(gdef.PVOID)(ctypes.py_object(obj))[0]
2021

0 commit comments

Comments
 (0)