#------------------------------------------------------------------------------
# BOOL TextOut(
# __in HDC hdc,
# __in int nXStart,
# __in int nYStart,
# __in LPCTSTR lpString,
# __in int cbString
# );
def TextOutA(event, ra, hdc, nXStart, nYStart, lpString, cbString):
log_ansi(event, "TextOutA", lpString, cbString)
def TextOutW(event, ra, hdc, nXStart, nYStart, lpString, cbString):
log_wide(event, "TextOutW", lpString, cbString)
# BOOL ExtTextOut(
# __in HDC hdc,
# __in int X,
# __in int Y,
# __in UINT fuOptions,
# __in const RECT * lprc,
# __in LPCTSTR lpString,
# __in UINT cbCount,
# __in const INT * lpDx
# );
def ExtTextOutA(event, ra, hdc, X, Y, fuOptions, lprc, lpString, cbCount, lpDx):
log_ansi(event, "ExtTextOutA", lpString, cbCount)
def ExtTextOutW(event, ra, hdc, X, Y, fuOptions, lprc, lpString, cbCount, lpDx):
log_wide(event, "ExtTextOutW", lpString, cbCount)
# typedef struct _POLYTEXT {
# int x;
# int y;
# UINT n;
# LPCTSTR lpstr;
# UINT uiFlags;
# RECT rcl;
# int * pdx;
# } POLYTEXT,* PPOLYTEXT;
class POLYTEXT(Structure):
_fields_ = [
('x', c_int),
('y', c_int),
('n', c_uint),
('lpstr', c_void_p),
('uiFlags', c_uint),
('rcl', c_uint*4),
('pdx', POINTER(c_int)),
]
# BOOL PolyTextOut(
# __in HDC hdc,
# __in const POLYTEXT * pptxt,
# __in int cStrings
# );
def PolyTextOutA(event, ra, hdc, pptxt, cStrings):
process = event.get_process()
sizeof_polytext = sizeof(POLYTEXT)
while cStrings:
txt = process.read_structure(pptxt, POLYTEXT)
log_ansi(event, "PolyTextOutA", txt.lpstr, txt.n)
pptxt = pptxt + sizeof_polytext
cStrings = cStrings - 1
def PolyTextOutW(event, ra, hdc, pptxt, cStrings):
process = event.get_process()
sizeof_polytext = sizeof(POLYTEXT)
while cStrings:
txt = process.read_structure(pptxt, POLYTEXT)
log_wide(event, "PolyTextOutW", txt.lpstr, txt.n)
pptxt = pptxt + sizeof_polytext
cStrings = cStrings - 1
#------------------------------------------------------------------------------
def log_ansi(event, fn, lpString, nCount):
if lpString and nCount:
if c_int(nCount).value == -1:
lpString = event.get_process().read_string(lpString, fUnicode = False)
else:
lpString = event.get_process().read_string(lpString, nCount)
print (DebugLog.log_text("%s( %r );" % (fn, lpString)))
def log_wide(event, fn, lpString, nCount):
if lpString and nCount:
if c_int(nCount).value == -1:
lpString = event.get_process().read_string(lpString, fUnicode = True)
else:
# lpString = event.get_process().peek(lpString, nCount * 2)
# lpString = unicode(lpString, 'U16', 'strict')
lpString=event.get_process().read_string(lpString, nCount,fUnicode = True)
print (DebugLog.log_text("%s( %r );" % (fn, lpString)))
class MyEventHandler( EventHandler ):
def load_dll(self, event):
pid = event.get_pid()
module = event.get_module()
if module.match_name("gdi32.dll"):
event.debug.hook_function(pid, module.resolve("TextOutA"), TextOutA, paramCount = 5)
event.debug.hook_function(pid, module.resolve("TextOutW"), TextOutW, paramCount = 5)
event.debug.hook_function(pid, module.resolve("ExtTextOutA"), ExtTextOutA, paramCount = 8)
event.debug.hook_function(pid, module.resolve("ExtTextOutW"), ExtTextOutW, paramCount = 8)
event.debug.hook_function(pid, module.resolve("PolyTextOutA"), PolyTextOutA, paramCount = 2)
event.debug.hook_function(pid, module.resolve("PolyTextOutW"), PolyTextOutW, paramCount = 2)
def simple_debugger(argv):
print (DebugLog.log_text("Trace started on %s" % argv[0]))
debug = Debug(MyEventHandler())
try:
debug.execv(argv)
debug.loop()
finally:
debug.stop()
print (DebugLog.log_text("Trace stopped on %s" % argv[0]))
if __name__=="__main__":
program_to_debug="c:\\windows\\system32\\notepad.exe"
sys.argv.append(program_to_debug)
simple_debugger(sys.argv[1:])