1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 4# Copyright (c) 2009-2014, Mario Vilas 5# All rights reserved. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions are met: 9# 10# * Redistributions of source code must retain the above copyright notice, 11# this list of conditions and the following disclaimer. 12# * Redistributions in binary form must reproduce the above copyright 13# notice,this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# * Neither the name of the copyright holder nor the names of its 16# contributors may be used to endorse or promote products derived from 17# this software without specific prior written permission. 18# 19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29# POSSIBILITY OF SUCH DAMAGE. 30 31""" 32Wrapper for dbghelp.dll in ctypes. 33""" 34 35__revision__ = "$Id$" 36 37from winappdbg.win32.defines import * 38from winappdbg.win32.version import * 39from winappdbg.win32.kernel32 import * 40 41# DbgHelp versions and features list: 42# http://msdn.microsoft.com/en-us/library/windows/desktop/ms679294(v=vs.85).aspx 43 44#------------------------------------------------------------------------------ 45# Tries to load the newest version of dbghelp.dll if available. 46 47def _load_latest_dbghelp_dll(): 48 49 from os import getenv 50 from os.path import join, exists 51 52 program_files_location = getenv("ProgramFiles") 53 if not program_files_location: 54 program_files_location = "C:\\Program Files" 55 56 program_files_x86_location = getenv("ProgramFiles(x86)") 57 58 if arch == ARCH_AMD64: 59 if wow64: 60 pathname = join( 61 program_files_x86_location or program_files_location, 62 "Debugging Tools for Windows (x86)", 63 "dbghelp.dll") 64 else: 65 pathname = join( 66 program_files_location, 67 "Debugging Tools for Windows (x64)", 68 "dbghelp.dll") 69 elif arch == ARCH_I386: 70 pathname = join( 71 program_files_location, 72 "Debugging Tools for Windows (x86)", 73 "dbghelp.dll") 74 else: 75 pathname = None 76 77 if pathname and exists(pathname): 78 try: 79 _dbghelp = ctypes.windll.LoadLibrary(pathname) 80 ctypes.windll.dbghelp = _dbghelp 81 except Exception: 82 pass 83 84_load_latest_dbghelp_dll() 85 86# Recover the old binding of the "os" symbol. 87# XXX FIXME not sure if I really need to do this! 88##from version import os 89 90#------------------------------------------------------------------------------ 91 92#============================================================================== 93# This is used later on to calculate the list of exported symbols. 94_all = None 95_all = set(vars().keys()) 96#============================================================================== 97 98# SymGetHomeDirectory "type" values 99hdBase = 0 100hdSym = 1 101hdSrc = 2 102 103UNDNAME_32_BIT_DECODE = 0x0800 104UNDNAME_COMPLETE = 0x0000 105UNDNAME_NAME_ONLY = 0x1000 106UNDNAME_NO_ACCESS_SPECIFIERS = 0x0080 107UNDNAME_NO_ALLOCATION_LANGUAGE = 0x0010 108UNDNAME_NO_ALLOCATION_MODEL = 0x0008 109UNDNAME_NO_ARGUMENTS = 0x2000 110UNDNAME_NO_CV_THISTYPE = 0x0040 111UNDNAME_NO_FUNCTION_RETURNS = 0x0004 112UNDNAME_NO_LEADING_UNDERSCORES = 0x0001 113UNDNAME_NO_MEMBER_TYPE = 0x0200 114UNDNAME_NO_MS_KEYWORDS = 0x0002 115UNDNAME_NO_MS_THISTYPE = 0x0020 116UNDNAME_NO_RETURN_UDT_MODEL = 0x0400 117UNDNAME_NO_SPECIAL_SYMS = 0x4000 118UNDNAME_NO_THISTYPE = 0x0060 119UNDNAME_NO_THROW_SIGNATURES = 0x0100 120 121#--- IMAGEHLP_MODULE structure and related ------------------------------------ 122 123SYMOPT_ALLOW_ABSOLUTE_SYMBOLS = 0x00000800 124SYMOPT_ALLOW_ZERO_ADDRESS = 0x01000000 125SYMOPT_AUTO_PUBLICS = 0x00010000 126SYMOPT_CASE_INSENSITIVE = 0x00000001 127SYMOPT_DEBUG = 0x80000000 128SYMOPT_DEFERRED_LOADS = 0x00000004 129SYMOPT_DISABLE_SYMSRV_AUTODETECT = 0x02000000 130SYMOPT_EXACT_SYMBOLS = 0x00000400 131SYMOPT_FAIL_CRITICAL_ERRORS = 0x00000200 132SYMOPT_FAVOR_COMPRESSED = 0x00800000 133SYMOPT_FLAT_DIRECTORY = 0x00400000 134SYMOPT_IGNORE_CVREC = 0x00000080 135SYMOPT_IGNORE_IMAGEDIR = 0x00200000 136SYMOPT_IGNORE_NT_SYMPATH = 0x00001000 137SYMOPT_INCLUDE_32BIT_MODULES = 0x00002000 138SYMOPT_LOAD_ANYTHING = 0x00000040 139SYMOPT_LOAD_LINES = 0x00000010 140SYMOPT_NO_CPP = 0x00000008 141SYMOPT_NO_IMAGE_SEARCH = 0x00020000 142SYMOPT_NO_PROMPTS = 0x00080000 143SYMOPT_NO_PUBLICS = 0x00008000 144SYMOPT_NO_UNQUALIFIED_LOADS = 0x00000100 145SYMOPT_OVERWRITE = 0x00100000 146SYMOPT_PUBLICS_ONLY = 0x00004000 147SYMOPT_SECURE = 0x00040000 148SYMOPT_UNDNAME = 0x00000002 149 150##SSRVOPT_DWORD 151##SSRVOPT_DWORDPTR 152##SSRVOPT_GUIDPTR 153## 154##SSRVOPT_CALLBACK 155##SSRVOPT_DOWNSTREAM_STORE 156##SSRVOPT_FLAT_DEFAULT_STORE 157##SSRVOPT_FAVOR_COMPRESSED 158##SSRVOPT_NOCOPY 159##SSRVOPT_OVERWRITE 160##SSRVOPT_PARAMTYPE 161##SSRVOPT_PARENTWIN 162##SSRVOPT_PROXY 163##SSRVOPT_RESET 164##SSRVOPT_SECURE 165##SSRVOPT_SETCONTEXT 166##SSRVOPT_TRACE 167##SSRVOPT_UNATTENDED 168 169# typedef enum 170# { 171# SymNone = 0, 172# SymCoff, 173# SymCv, 174# SymPdb, 175# SymExport, 176# SymDeferred, 177# SymSym, 178# SymDia, 179# SymVirtual, 180# NumSymTypes 181# } SYM_TYPE; 182SymNone = 0 183SymCoff = 1 184SymCv = 2 185SymPdb = 3 186SymExport = 4 187SymDeferred = 5 188SymSym = 6 189SymDia = 7 190SymVirtual = 8 191NumSymTypes = 9 192 193# typedef struct _IMAGEHLP_MODULE64 { 194# DWORD SizeOfStruct; 195# DWORD64 BaseOfImage; 196# DWORD ImageSize; 197# DWORD TimeDateStamp; 198# DWORD CheckSum; 199# DWORD NumSyms; 200# SYM_TYPE SymType; 201# TCHAR ModuleName[32]; 202# TCHAR ImageName[256]; 203# TCHAR LoadedImageName[256]; 204# TCHAR LoadedPdbName[256]; 205# DWORD CVSig; 206# TCHAR CVData[MAX_PATH*3]; 207# DWORD PdbSig; 208# GUID PdbSig70; 209# DWORD PdbAge; 210# BOOL PdbUnmatched; 211# BOOL DbgUnmatched; 212# BOOL LineNumbers; 213# BOOL GlobalSymbols; 214# BOOL TypeInfo; 215# BOOL SourceIndexed; 216# BOOL Publics; 217# } IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64; 218 219class IMAGEHLP_MODULE (Structure): 220 _fields_ = [ 221 ("SizeOfStruct", DWORD), 222 ("BaseOfImage", DWORD), 223 ("ImageSize", DWORD), 224 ("TimeDateStamp", DWORD), 225 ("CheckSum", DWORD), 226 ("NumSyms", DWORD), 227 ("SymType", DWORD), # SYM_TYPE 228 ("ModuleName", CHAR * 32), 229 ("ImageName", CHAR * 256), 230 ("LoadedImageName", CHAR * 256), 231 ] 232PIMAGEHLP_MODULE = POINTER(IMAGEHLP_MODULE) 233 234class IMAGEHLP_MODULE64 (Structure): 235 _fields_ = [ 236 ("SizeOfStruct", DWORD), 237 ("BaseOfImage", DWORD64), 238 ("ImageSize", DWORD), 239 ("TimeDateStamp", DWORD), 240 ("CheckSum", DWORD), 241 ("NumSyms", DWORD), 242 ("SymType", DWORD), # SYM_TYPE 243 ("ModuleName", CHAR * 32), 244 ("ImageName", CHAR * 256), 245 ("LoadedImageName", CHAR * 256), 246 ("LoadedPdbName", CHAR * 256), 247 ("CVSig", DWORD), 248 ("CVData", CHAR * (MAX_PATH * 3)), 249 ("PdbSig", DWORD), 250 ("PdbSig70", GUID), 251 ("PdbAge", DWORD), 252 ("PdbUnmatched", BOOL), 253 ("DbgUnmatched", BOOL), 254 ("LineNumbers", BOOL), 255 ("GlobalSymbols", BOOL), 256 ("TypeInfo", BOOL), 257 ("SourceIndexed", BOOL), 258 ("Publics", BOOL), 259 ] 260PIMAGEHLP_MODULE64 = POINTER(IMAGEHLP_MODULE64) 261 262class IMAGEHLP_MODULEW (Structure): 263 _fields_ = [ 264 ("SizeOfStruct", DWORD), 265 ("BaseOfImage", DWORD), 266 ("ImageSize", DWORD), 267 ("TimeDateStamp", DWORD), 268 ("CheckSum", DWORD), 269 ("NumSyms", DWORD), 270 ("SymType", DWORD), # SYM_TYPE 271 ("ModuleName", WCHAR * 32), 272 ("ImageName", WCHAR * 256), 273 ("LoadedImageName", WCHAR * 256), 274 ] 275PIMAGEHLP_MODULEW = POINTER(IMAGEHLP_MODULEW) 276 277class IMAGEHLP_MODULEW64 (Structure): 278 _fields_ = [ 279 ("SizeOfStruct", DWORD), 280 ("BaseOfImage", DWORD64), 281 ("ImageSize", DWORD), 282 ("TimeDateStamp", DWORD), 283 ("CheckSum", DWORD), 284 ("NumSyms", DWORD), 285 ("SymType", DWORD), # SYM_TYPE 286 ("ModuleName", WCHAR * 32), 287 ("ImageName", WCHAR * 256), 288 ("LoadedImageName", WCHAR * 256), 289 ("LoadedPdbName", WCHAR * 256), 290 ("CVSig", DWORD), 291 ("CVData", WCHAR * (MAX_PATH * 3)), 292 ("PdbSig", DWORD), 293 ("PdbSig70", GUID), 294 ("PdbAge", DWORD), 295 ("PdbUnmatched", BOOL), 296 ("DbgUnmatched", BOOL), 297 ("LineNumbers", BOOL), 298 ("GlobalSymbols", BOOL), 299 ("TypeInfo", BOOL), 300 ("SourceIndexed", BOOL), 301 ("Publics", BOOL), 302 ] 303PIMAGEHLP_MODULEW64 = POINTER(IMAGEHLP_MODULEW64) 304 305#--- dbghelp.dll -------------------------------------------------------------- 306 307# XXX the ANSI versions of these functions don't end in "A" as expected! 308 309# BOOL WINAPI MakeSureDirectoryPathExists( 310# _In_ PCSTR DirPath 311# ); 312def MakeSureDirectoryPathExistsA(DirPath): 313 _MakeSureDirectoryPathExists = windll.dbghelp.MakeSureDirectoryPathExists 314 _MakeSureDirectoryPathExists.argtypes = [LPSTR] 315 _MakeSureDirectoryPathExists.restype = bool 316 _MakeSureDirectoryPathExists.errcheck = RaiseIfZero 317 return _MakeSureDirectoryPathExists(DirPath) 318 319MakeSureDirectoryPathExistsW = MakeWideVersion(MakeSureDirectoryPathExistsA) 320MakeSureDirectoryPathExists = GuessStringType(MakeSureDirectoryPathExistsA, MakeSureDirectoryPathExistsW) 321 322# BOOL WINAPI SymInitialize( 323# __in HANDLE hProcess, 324# __in_opt PCTSTR UserSearchPath, 325# __in BOOL fInvadeProcess 326# ); 327def SymInitializeA(hProcess, UserSearchPath = None, fInvadeProcess = False): 328 _SymInitialize = windll.dbghelp.SymInitialize 329 _SymInitialize.argtypes = [HANDLE, LPSTR, BOOL] 330 _SymInitialize.restype = bool 331 _SymInitialize.errcheck = RaiseIfZero 332 if not UserSearchPath: 333 UserSearchPath = None 334 _SymInitialize(hProcess, UserSearchPath, fInvadeProcess) 335 336SymInitializeW = MakeWideVersion(SymInitializeA) 337SymInitialize = GuessStringType(SymInitializeA, SymInitializeW) 338 339# BOOL WINAPI SymCleanup( 340# __in HANDLE hProcess 341# ); 342def SymCleanup(hProcess): 343 _SymCleanup = windll.dbghelp.SymCleanup 344 _SymCleanup.argtypes = [HANDLE] 345 _SymCleanup.restype = bool 346 _SymCleanup.errcheck = RaiseIfZero 347 _SymCleanup(hProcess) 348 349# BOOL WINAPI SymRefreshModuleList( 350# __in HANDLE hProcess 351# ); 352def SymRefreshModuleList(hProcess): 353 _SymRefreshModuleList = windll.dbghelp.SymRefreshModuleList 354 _SymRefreshModuleList.argtypes = [HANDLE] 355 _SymRefreshModuleList.restype = bool 356 _SymRefreshModuleList.errcheck = RaiseIfZero 357 _SymRefreshModuleList(hProcess) 358 359# BOOL WINAPI SymSetParentWindow( 360# __in HWND hwnd 361# ); 362def SymSetParentWindow(hwnd): 363 _SymSetParentWindow = windll.dbghelp.SymSetParentWindow 364 _SymSetParentWindow.argtypes = [HWND] 365 _SymSetParentWindow.restype = bool 366 _SymSetParentWindow.errcheck = RaiseIfZero 367 _SymSetParentWindow(hwnd) 368 369# DWORD WINAPI SymSetOptions( 370# __in DWORD SymOptions 371# ); 372def SymSetOptions(SymOptions): 373 _SymSetOptions = windll.dbghelp.SymSetOptions 374 _SymSetOptions.argtypes = [DWORD] 375 _SymSetOptions.restype = DWORD 376 _SymSetOptions.errcheck = RaiseIfZero 377 _SymSetOptions(SymOptions) 378 379# DWORD WINAPI SymGetOptions(void); 380def SymGetOptions(): 381 _SymGetOptions = windll.dbghelp.SymGetOptions 382 _SymGetOptions.argtypes = [] 383 _SymGetOptions.restype = DWORD 384 return _SymGetOptions() 385 386# DWORD WINAPI SymLoadModule( 387# __in HANDLE hProcess, 388# __in_opt HANDLE hFile, 389# __in_opt PCSTR ImageName, 390# __in_opt PCSTR ModuleName, 391# __in DWORD BaseOfDll, 392# __in DWORD SizeOfDll 393# ); 394def SymLoadModuleA(hProcess, hFile = None, ImageName = None, ModuleName = None, BaseOfDll = None, SizeOfDll = None): 395 _SymLoadModule = windll.dbghelp.SymLoadModule 396 _SymLoadModule.argtypes = [HANDLE, HANDLE, LPSTR, LPSTR, DWORD, DWORD] 397 _SymLoadModule.restype = DWORD 398 399 if not ImageName: 400 ImageName = None 401 if not ModuleName: 402 ModuleName = None 403 if not BaseOfDll: 404 BaseOfDll = 0 405 if not SizeOfDll: 406 SizeOfDll = 0 407 SetLastError(ERROR_SUCCESS) 408 lpBaseAddress = _SymLoadModule(hProcess, hFile, ImageName, ModuleName, BaseOfDll, SizeOfDll) 409 if lpBaseAddress == NULL: 410 dwErrorCode = GetLastError() 411 if dwErrorCode != ERROR_SUCCESS: 412 raise ctypes.WinError(dwErrorCode) 413 return lpBaseAddress 414 415SymLoadModuleW = MakeWideVersion(SymLoadModuleA) 416SymLoadModule = GuessStringType(SymLoadModuleA, SymLoadModuleW) 417 418# DWORD64 WINAPI SymLoadModule64( 419# __in HANDLE hProcess, 420# __in_opt HANDLE hFile, 421# __in_opt PCSTR ImageName, 422# __in_opt PCSTR ModuleName, 423# __in DWORD64 BaseOfDll, 424# __in DWORD SizeOfDll 425# ); 426def SymLoadModule64A(hProcess, hFile = None, ImageName = None, ModuleName = None, BaseOfDll = None, SizeOfDll = None): 427 _SymLoadModule64 = windll.dbghelp.SymLoadModule64 428 _SymLoadModule64.argtypes = [HANDLE, HANDLE, LPSTR, LPSTR, DWORD64, DWORD] 429 _SymLoadModule64.restype = DWORD64 430 431 if not ImageName: 432 ImageName = None 433 if not ModuleName: 434 ModuleName = None 435 if not BaseOfDll: 436 BaseOfDll = 0 437 if not SizeOfDll: 438 SizeOfDll = 0 439 SetLastError(ERROR_SUCCESS) 440 lpBaseAddress = _SymLoadModule64(hProcess, hFile, ImageName, ModuleName, BaseOfDll, SizeOfDll) 441 if lpBaseAddress == NULL: 442 dwErrorCode = GetLastError() 443 if dwErrorCode != ERROR_SUCCESS: 444 raise ctypes.WinError(dwErrorCode) 445 return lpBaseAddress 446 447SymLoadModule64W = MakeWideVersion(SymLoadModule64A) 448SymLoadModule64 = GuessStringType(SymLoadModule64A, SymLoadModule64W) 449 450# BOOL WINAPI SymUnloadModule( 451# __in HANDLE hProcess, 452# __in DWORD BaseOfDll 453# ); 454def SymUnloadModule(hProcess, BaseOfDll): 455 _SymUnloadModule = windll.dbghelp.SymUnloadModule 456 _SymUnloadModule.argtypes = [HANDLE, DWORD] 457 _SymUnloadModule.restype = bool 458 _SymUnloadModule.errcheck = RaiseIfZero 459 _SymUnloadModule(hProcess, BaseOfDll) 460 461# BOOL WINAPI SymUnloadModule64( 462# __in HANDLE hProcess, 463# __in DWORD64 BaseOfDll 464# ); 465def SymUnloadModule64(hProcess, BaseOfDll): 466 _SymUnloadModule64 = windll.dbghelp.SymUnloadModule64 467 _SymUnloadModule64.argtypes = [HANDLE, DWORD64] 468 _SymUnloadModule64.restype = bool 469 _SymUnloadModule64.errcheck = RaiseIfZero 470 _SymUnloadModule64(hProcess, BaseOfDll) 471 472# BOOL WINAPI SymGetModuleInfo( 473# __in HANDLE hProcess, 474# __in DWORD dwAddr, 475# __out PIMAGEHLP_MODULE ModuleInfo 476# ); 477def SymGetModuleInfoA(hProcess, dwAddr): 478 _SymGetModuleInfo = windll.dbghelp.SymGetModuleInfo 479 _SymGetModuleInfo.argtypes = [HANDLE, DWORD, PIMAGEHLP_MODULE] 480 _SymGetModuleInfo.restype = bool 481 _SymGetModuleInfo.errcheck = RaiseIfZero 482 483 ModuleInfo = IMAGEHLP_MODULE() 484 ModuleInfo.SizeOfStruct = sizeof(ModuleInfo) 485 _SymGetModuleInfo(hProcess, dwAddr, byref(ModuleInfo)) 486 return ModuleInfo 487 488def SymGetModuleInfoW(hProcess, dwAddr): 489 _SymGetModuleInfoW = windll.dbghelp.SymGetModuleInfoW 490 _SymGetModuleInfoW.argtypes = [HANDLE, DWORD, PIMAGEHLP_MODULEW] 491 _SymGetModuleInfoW.restype = bool 492 _SymGetModuleInfoW.errcheck = RaiseIfZero 493 494 ModuleInfo = IMAGEHLP_MODULEW() 495 ModuleInfo.SizeOfStruct = sizeof(ModuleInfo) 496 _SymGetModuleInfoW(hProcess, dwAddr, byref(ModuleInfo)) 497 return ModuleInfo 498 499SymGetModuleInfo = GuessStringType(SymGetModuleInfoA, SymGetModuleInfoW) 500 501# BOOL WINAPI SymGetModuleInfo64( 502# __in HANDLE hProcess, 503# __in DWORD64 dwAddr, 504# __out PIMAGEHLP_MODULE64 ModuleInfo 505# ); 506def SymGetModuleInfo64A(hProcess, dwAddr): 507 _SymGetModuleInfo64 = windll.dbghelp.SymGetModuleInfo64 508 _SymGetModuleInfo64.argtypes = [HANDLE, DWORD64, PIMAGEHLP_MODULE64] 509 _SymGetModuleInfo64.restype = bool 510 _SymGetModuleInfo64.errcheck = RaiseIfZero 511 512 ModuleInfo = IMAGEHLP_MODULE64() 513 ModuleInfo.SizeOfStruct = sizeof(ModuleInfo) 514 _SymGetModuleInfo64(hProcess, dwAddr, byref(ModuleInfo)) 515 return ModuleInfo 516 517def SymGetModuleInfo64W(hProcess, dwAddr): 518 _SymGetModuleInfo64W = windll.dbghelp.SymGetModuleInfo64W 519 _SymGetModuleInfo64W.argtypes = [HANDLE, DWORD64, PIMAGEHLP_MODULE64W] 520 _SymGetModuleInfo64W.restype = bool 521 _SymGetModuleInfo64W.errcheck = RaiseIfZero 522 523 ModuleInfo = IMAGEHLP_MODULE64W() 524 ModuleInfo.SizeOfStruct = sizeof(ModuleInfo) 525 _SymGetModuleInfo64W(hProcess, dwAddr, byref(ModuleInfo)) 526 return ModuleInfo 527 528SymGetModuleInfo64 = GuessStringType(SymGetModuleInfo64A, SymGetModuleInfo64W) 529 530# BOOL CALLBACK SymEnumerateModulesProc( 531# __in PCTSTR ModuleName, 532# __in DWORD BaseOfDll, 533# __in_opt PVOID UserContext 534# ); 535PSYM_ENUMMODULES_CALLBACK = WINFUNCTYPE(BOOL, LPSTR, DWORD, PVOID) 536PSYM_ENUMMODULES_CALLBACKW = WINFUNCTYPE(BOOL, LPWSTR, DWORD, PVOID) 537 538# BOOL CALLBACK SymEnumerateModulesProc64( 539# __in PCTSTR ModuleName, 540# __in DWORD64 BaseOfDll, 541# __in_opt PVOID UserContext 542# ); 543PSYM_ENUMMODULES_CALLBACK64 = WINFUNCTYPE(BOOL, LPSTR, DWORD64, PVOID) 544PSYM_ENUMMODULES_CALLBACKW64 = WINFUNCTYPE(BOOL, LPWSTR, DWORD64, PVOID) 545 546# BOOL WINAPI SymEnumerateModules( 547# __in HANDLE hProcess, 548# __in PSYM_ENUMMODULES_CALLBACK EnumModulesCallback, 549# __in_opt PVOID UserContext 550# ); 551def SymEnumerateModulesA(hProcess, EnumModulesCallback, UserContext = None): 552 _SymEnumerateModules = windll.dbghelp.SymEnumerateModules 553 _SymEnumerateModules.argtypes = [HANDLE, PSYM_ENUMMODULES_CALLBACK, PVOID] 554 _SymEnumerateModules.restype = bool 555 _SymEnumerateModules.errcheck = RaiseIfZero 556 557 EnumModulesCallback = PSYM_ENUMMODULES_CALLBACK(EnumModulesCallback) 558 if UserContext: 559 UserContext = ctypes.pointer(UserContext) 560 else: 561 UserContext = LPVOID(NULL) 562 _SymEnumerateModules(hProcess, EnumModulesCallback, UserContext) 563 564def SymEnumerateModulesW(hProcess, EnumModulesCallback, UserContext = None): 565 _SymEnumerateModulesW = windll.dbghelp.SymEnumerateModulesW 566 _SymEnumerateModulesW.argtypes = [HANDLE, PSYM_ENUMMODULES_CALLBACKW, PVOID] 567 _SymEnumerateModulesW.restype = bool 568 _SymEnumerateModulesW.errcheck = RaiseIfZero 569 570 EnumModulesCallback = PSYM_ENUMMODULES_CALLBACKW(EnumModulesCallback) 571 if UserContext: 572 UserContext = ctypes.pointer(UserContext) 573 else: 574 UserContext = LPVOID(NULL) 575 _SymEnumerateModulesW(hProcess, EnumModulesCallback, UserContext) 576 577SymEnumerateModules = GuessStringType(SymEnumerateModulesA, SymEnumerateModulesW) 578 579# BOOL WINAPI SymEnumerateModules64( 580# __in HANDLE hProcess, 581# __in PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback, 582# __in_opt PVOID UserContext 583# ); 584def SymEnumerateModules64A(hProcess, EnumModulesCallback, UserContext = None): 585 _SymEnumerateModules64 = windll.dbghelp.SymEnumerateModules64 586 _SymEnumerateModules64.argtypes = [HANDLE, PSYM_ENUMMODULES_CALLBACK64, PVOID] 587 _SymEnumerateModules64.restype = bool 588 _SymEnumerateModules64.errcheck = RaiseIfZero 589 590 EnumModulesCallback = PSYM_ENUMMODULES_CALLBACK64(EnumModulesCallback) 591 if UserContext: 592 UserContext = ctypes.pointer(UserContext) 593 else: 594 UserContext = LPVOID(NULL) 595 _SymEnumerateModules64(hProcess, EnumModulesCallback, UserContext) 596 597def SymEnumerateModules64W(hProcess, EnumModulesCallback, UserContext = None): 598 _SymEnumerateModules64W = windll.dbghelp.SymEnumerateModules64W 599 _SymEnumerateModules64W.argtypes = [HANDLE, PSYM_ENUMMODULES_CALLBACK64W, PVOID] 600 _SymEnumerateModules64W.restype = bool 601 _SymEnumerateModules64W.errcheck = RaiseIfZero 602 603 EnumModulesCallback = PSYM_ENUMMODULES_CALLBACK64W(EnumModulesCallback) 604 if UserContext: 605 UserContext = ctypes.pointer(UserContext) 606 else: 607 UserContext = LPVOID(NULL) 608 _SymEnumerateModules64W(hProcess, EnumModulesCallback, UserContext) 609 610SymEnumerateModules64 = GuessStringType(SymEnumerateModules64A, SymEnumerateModules64W) 611 612# BOOL CALLBACK SymEnumerateSymbolsProc( 613# __in PCTSTR SymbolName, 614# __in DWORD SymbolAddress, 615# __in ULONG SymbolSize, 616# __in_opt PVOID UserContext 617# ); 618PSYM_ENUMSYMBOLS_CALLBACK = WINFUNCTYPE(BOOL, LPSTR, DWORD, ULONG, PVOID) 619PSYM_ENUMSYMBOLS_CALLBACKW = WINFUNCTYPE(BOOL, LPWSTR, DWORD, ULONG, PVOID) 620 621# BOOL CALLBACK SymEnumerateSymbolsProc64( 622# __in PCTSTR SymbolName, 623# __in DWORD64 SymbolAddress, 624# __in ULONG SymbolSize, 625# __in_opt PVOID UserContext 626# ); 627PSYM_ENUMSYMBOLS_CALLBACK64 = WINFUNCTYPE(BOOL, LPSTR, DWORD64, ULONG, PVOID) 628PSYM_ENUMSYMBOLS_CALLBACKW64 = WINFUNCTYPE(BOOL, LPWSTR, DWORD64, ULONG, PVOID) 629 630# BOOL WINAPI SymEnumerateSymbols( 631# __in HANDLE hProcess, 632# __in ULONG BaseOfDll, 633# __in PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback, 634# __in_opt PVOID UserContext 635# ); 636def SymEnumerateSymbolsA(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext = None): 637 _SymEnumerateSymbols = windll.dbghelp.SymEnumerateSymbols 638 _SymEnumerateSymbols.argtypes = [HANDLE, ULONG, PSYM_ENUMSYMBOLS_CALLBACK, PVOID] 639 _SymEnumerateSymbols.restype = bool 640 _SymEnumerateSymbols.errcheck = RaiseIfZero 641 642 EnumSymbolsCallback = PSYM_ENUMSYMBOLS_CALLBACK(EnumSymbolsCallback) 643 if UserContext: 644 UserContext = ctypes.pointer(UserContext) 645 else: 646 UserContext = LPVOID(NULL) 647 _SymEnumerateSymbols(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext) 648 649def SymEnumerateSymbolsW(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext = None): 650 _SymEnumerateSymbolsW = windll.dbghelp.SymEnumerateSymbolsW 651 _SymEnumerateSymbolsW.argtypes = [HANDLE, ULONG, PSYM_ENUMSYMBOLS_CALLBACKW, PVOID] 652 _SymEnumerateSymbolsW.restype = bool 653 _SymEnumerateSymbolsW.errcheck = RaiseIfZero 654 655 EnumSymbolsCallback = PSYM_ENUMSYMBOLS_CALLBACKW(EnumSymbolsCallback) 656 if UserContext: 657 UserContext = ctypes.pointer(UserContext) 658 else: 659 UserContext = LPVOID(NULL) 660 _SymEnumerateSymbolsW(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext) 661 662SymEnumerateSymbols = GuessStringType(SymEnumerateSymbolsA, SymEnumerateSymbolsW) 663 664# BOOL WINAPI SymEnumerateSymbols64( 665# __in HANDLE hProcess, 666# __in ULONG64 BaseOfDll, 667# __in PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback, 668# __in_opt PVOID UserContext 669# ); 670def SymEnumerateSymbols64A(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext = None): 671 _SymEnumerateSymbols64 = windll.dbghelp.SymEnumerateSymbols64 672 _SymEnumerateSymbols64.argtypes = [HANDLE, ULONG64, PSYM_ENUMSYMBOLS_CALLBACK64, PVOID] 673 _SymEnumerateSymbols64.restype = bool 674 _SymEnumerateSymbols64.errcheck = RaiseIfZero 675 676 EnumSymbolsCallback = PSYM_ENUMSYMBOLS_CALLBACK64(EnumSymbolsCallback) 677 if UserContext: 678 UserContext = ctypes.pointer(UserContext) 679 else: 680 UserContext = LPVOID(NULL) 681 _SymEnumerateSymbols64(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext) 682 683def SymEnumerateSymbols64W(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext = None): 684 _SymEnumerateSymbols64W = windll.dbghelp.SymEnumerateSymbols64W 685 _SymEnumerateSymbols64W.argtypes = [HANDLE, ULONG64, PSYM_ENUMSYMBOLS_CALLBACK64W, PVOID] 686 _SymEnumerateSymbols64W.restype = bool 687 _SymEnumerateSymbols64W.errcheck = RaiseIfZero 688 689 EnumSymbolsCallback = PSYM_ENUMSYMBOLS_CALLBACK64W(EnumSymbolsCallback) 690 if UserContext: 691 UserContext = ctypes.pointer(UserContext) 692 else: 693 UserContext = LPVOID(NULL) 694 _SymEnumerateSymbols64W(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext) 695 696SymEnumerateSymbols64 = GuessStringType(SymEnumerateSymbols64A, SymEnumerateSymbols64W) 697 698# DWORD WINAPI UnDecorateSymbolName( 699# __in PCTSTR DecoratedName, 700# __out PTSTR UnDecoratedName, 701# __in DWORD UndecoratedLength, 702# __in DWORD Flags 703# ); 704def UnDecorateSymbolNameA(DecoratedName, Flags = UNDNAME_COMPLETE): 705 _UnDecorateSymbolNameA = windll.dbghelp.UnDecorateSymbolName 706 _UnDecorateSymbolNameA.argtypes = [LPSTR, LPSTR, DWORD, DWORD] 707 _UnDecorateSymbolNameA.restype = DWORD 708 _UnDecorateSymbolNameA.errcheck = RaiseIfZero 709 710 UndecoratedLength = _UnDecorateSymbolNameA(DecoratedName, None, 0, Flags) 711 UnDecoratedName = ctypes.create_string_buffer('', UndecoratedLength + 1) 712 _UnDecorateSymbolNameA(DecoratedName, UnDecoratedName, UndecoratedLength, Flags) 713 return UnDecoratedName.value 714 715def UnDecorateSymbolNameW(DecoratedName, Flags = UNDNAME_COMPLETE): 716 _UnDecorateSymbolNameW = windll.dbghelp.UnDecorateSymbolNameW 717 _UnDecorateSymbolNameW.argtypes = [LPWSTR, LPWSTR, DWORD, DWORD] 718 _UnDecorateSymbolNameW.restype = DWORD 719 _UnDecorateSymbolNameW.errcheck = RaiseIfZero 720 721 UndecoratedLength = _UnDecorateSymbolNameW(DecoratedName, None, 0, Flags) 722 UnDecoratedName = ctypes.create_unicode_buffer(u'', UndecoratedLength + 1) 723 _UnDecorateSymbolNameW(DecoratedName, UnDecoratedName, UndecoratedLength, Flags) 724 return UnDecoratedName.value 725 726UnDecorateSymbolName = GuessStringType(UnDecorateSymbolNameA, UnDecorateSymbolNameW) 727 728# BOOL WINAPI SymGetSearchPath( 729# __in HANDLE hProcess, 730# __out PTSTR SearchPath, 731# __in DWORD SearchPathLength 732# ); 733def SymGetSearchPathA(hProcess): 734 _SymGetSearchPath = windll.dbghelp.SymGetSearchPath 735 _SymGetSearchPath.argtypes = [HANDLE, LPSTR, DWORD] 736 _SymGetSearchPath.restype = bool 737 _SymGetSearchPath.errcheck = RaiseIfZero 738 739 SearchPathLength = MAX_PATH 740 SearchPath = ctypes.create_string_buffer("", SearchPathLength) 741 _SymGetSearchPath(hProcess, SearchPath, SearchPathLength) 742 return SearchPath.value 743 744def SymGetSearchPathW(hProcess): 745 _SymGetSearchPathW = windll.dbghelp.SymGetSearchPathW 746 _SymGetSearchPathW.argtypes = [HANDLE, LPWSTR, DWORD] 747 _SymGetSearchPathW.restype = bool 748 _SymGetSearchPathW.errcheck = RaiseIfZero 749 750 SearchPathLength = MAX_PATH 751 SearchPath = ctypes.create_unicode_buffer(u"", SearchPathLength) 752 _SymGetSearchPathW(hProcess, SearchPath, SearchPathLength) 753 return SearchPath.value 754 755SymGetSearchPath = GuessStringType(SymGetSearchPathA, SymGetSearchPathW) 756 757# BOOL WINAPI SymSetSearchPath( 758# __in HANDLE hProcess, 759# __in_opt PCTSTR SearchPath 760# ); 761def SymSetSearchPathA(hProcess, SearchPath = None): 762 _SymSetSearchPath = windll.dbghelp.SymSetSearchPath 763 _SymSetSearchPath.argtypes = [HANDLE, LPSTR] 764 _SymSetSearchPath.restype = bool 765 _SymSetSearchPath.errcheck = RaiseIfZero 766 if not SearchPath: 767 SearchPath = None 768 _SymSetSearchPath(hProcess, SearchPath) 769 770def SymSetSearchPathW(hProcess, SearchPath = None): 771 _SymSetSearchPathW = windll.dbghelp.SymSetSearchPathW 772 _SymSetSearchPathW.argtypes = [HANDLE, LPWSTR] 773 _SymSetSearchPathW.restype = bool 774 _SymSetSearchPathW.errcheck = RaiseIfZero 775 if not SearchPath: 776 SearchPath = None 777 _SymSetSearchPathW(hProcess, SearchPath) 778 779SymSetSearchPath = GuessStringType(SymSetSearchPathA, SymSetSearchPathW) 780 781# PTCHAR WINAPI SymGetHomeDirectory( 782# __in DWORD type, 783# __out PTSTR dir, 784# __in size_t size 785# ); 786def SymGetHomeDirectoryA(type): 787 _SymGetHomeDirectoryA = windll.dbghelp.SymGetHomeDirectoryA 788 _SymGetHomeDirectoryA.argtypes = [DWORD, LPSTR, SIZE_T] 789 _SymGetHomeDirectoryA.restype = LPSTR 790 _SymGetHomeDirectoryA.errcheck = RaiseIfZero 791 792 size = MAX_PATH 793 dir = ctypes.create_string_buffer("", size) 794 _SymGetHomeDirectoryA(type, dir, size) 795 return dir.value 796 797def SymGetHomeDirectoryW(type): 798 _SymGetHomeDirectoryW = windll.dbghelp.SymGetHomeDirectoryW 799 _SymGetHomeDirectoryW.argtypes = [DWORD, LPWSTR, SIZE_T] 800 _SymGetHomeDirectoryW.restype = LPWSTR 801 _SymGetHomeDirectoryW.errcheck = RaiseIfZero 802 803 size = MAX_PATH 804 dir = ctypes.create_unicode_buffer(u"", size) 805 _SymGetHomeDirectoryW(type, dir, size) 806 return dir.value 807 808SymGetHomeDirectory = GuessStringType(SymGetHomeDirectoryA, SymGetHomeDirectoryW) 809 810# PTCHAR WINAPI SymSetHomeDirectory( 811# __in HANDLE hProcess, 812# __in_opt PCTSTR dir 813# ); 814def SymSetHomeDirectoryA(hProcess, dir = None): 815 _SymSetHomeDirectoryA = windll.dbghelp.SymSetHomeDirectoryA 816 _SymSetHomeDirectoryA.argtypes = [HANDLE, LPSTR] 817 _SymSetHomeDirectoryA.restype = LPSTR 818 _SymSetHomeDirectoryA.errcheck = RaiseIfZero 819 if not dir: 820 dir = None 821 _SymSetHomeDirectoryA(hProcess, dir) 822 return dir 823 824def SymSetHomeDirectoryW(hProcess, dir = None): 825 _SymSetHomeDirectoryW = windll.dbghelp.SymSetHomeDirectoryW 826 _SymSetHomeDirectoryW.argtypes = [HANDLE, LPWSTR] 827 _SymSetHomeDirectoryW.restype = LPWSTR 828 _SymSetHomeDirectoryW.errcheck = RaiseIfZero 829 if not dir: 830 dir = None 831 _SymSetHomeDirectoryW(hProcess, dir) 832 return dir 833 834SymSetHomeDirectory = GuessStringType(SymSetHomeDirectoryA, SymSetHomeDirectoryW) 835 836#--- DbgHelp 5+ support, patch by Neitsa -------------------------------------- 837 838# XXX TODO 839# + use the GuessStringType decorator for ANSI/Wide versions 840# + replace hardcoded struct sizes with sizeof() calls 841# + StackWalk64 should raise on error, but something has to be done about it 842# not setting the last error code (maybe we should call SetLastError 843# ourselves with a default error code?) 844# /Mario 845 846#maximum length of a symbol name 847MAX_SYM_NAME = 2000 848 849class SYM_INFO(Structure): 850 _fields_ = [ 851 ("SizeOfStruct", ULONG), 852 ("TypeIndex", ULONG), 853 ("Reserved", ULONG64 * 2), 854 ("Index", ULONG), 855 ("Size", ULONG), 856 ("ModBase", ULONG64), 857 ("Flags", ULONG), 858 ("Value", ULONG64), 859 ("Address", ULONG64), 860 ("Register", ULONG), 861 ("Scope", ULONG), 862 ("Tag", ULONG), 863 ("NameLen", ULONG), 864 ("MaxNameLen", ULONG), 865 ("Name", CHAR * (MAX_SYM_NAME + 1)), 866 ] 867PSYM_INFO = POINTER(SYM_INFO) 868 869class SYM_INFOW(Structure): 870 _fields_ = [ 871 ("SizeOfStruct", ULONG), 872 ("TypeIndex", ULONG), 873 ("Reserved", ULONG64 * 2), 874 ("Index", ULONG), 875 ("Size", ULONG), 876 ("ModBase", ULONG64), 877 ("Flags", ULONG), 878 ("Value", ULONG64), 879 ("Address", ULONG64), 880 ("Register", ULONG), 881 ("Scope", ULONG), 882 ("Tag", ULONG), 883 ("NameLen", ULONG), 884 ("MaxNameLen", ULONG), 885 ("Name", WCHAR * (MAX_SYM_NAME + 1)), 886 ] 887PSYM_INFOW = POINTER(SYM_INFOW) 888 889#=============================================================================== 890# BOOL WINAPI SymFromName( 891# __in HANDLE hProcess, 892# __in PCTSTR Name, 893# __inout PSYMBOL_INFO Symbol 894# ); 895#=============================================================================== 896def SymFromName(hProcess, Name): 897 _SymFromNameA = windll.dbghelp.SymFromName 898 _SymFromNameA.argtypes = [HANDLE, LPSTR, PSYM_INFO] 899 _SymFromNameA.restype = bool 900 _SymFromNameA.errcheck = RaiseIfZero 901 902 SymInfo = SYM_INFO() 903 SymInfo.SizeOfStruct = 88 # *don't modify*: sizeof(SYMBOL_INFO) in C. 904 SymInfo.MaxNameLen = MAX_SYM_NAME 905 906 _SymFromNameA(hProcess, Name, byref(SymInfo)) 907 908 return SymInfo 909 910def SymFromNameW(hProcess, Name): 911 _SymFromNameW = windll.dbghelp.SymFromNameW 912 _SymFromNameW.argtypes = [HANDLE, LPWSTR, PSYM_INFOW] 913 _SymFromNameW.restype = bool 914 _SymFromNameW.errcheck = RaiseIfZero 915 916 SymInfo = SYM_INFOW() 917 SymInfo.SizeOfStruct = 88 # *don't modify*: sizeof(SYMBOL_INFOW) in C. 918 SymInfo.MaxNameLen = MAX_SYM_NAME 919 920 _SymFromNameW(hProcess, Name, byref(SymInfo)) 921 922 return SymInfo 923 924#=============================================================================== 925# BOOL WINAPI SymFromAddr( 926# __in HANDLE hProcess, 927# __in DWORD64 Address, 928# __out_opt PDWORD64 Displacement, 929# __inout PSYMBOL_INFO Symbol 930# ); 931#=============================================================================== 932def SymFromAddr(hProcess, Address): 933 _SymFromAddr = windll.dbghelp.SymFromAddr 934 _SymFromAddr.argtypes = [HANDLE, DWORD64, PDWORD64, PSYM_INFO] 935 _SymFromAddr.restype = bool 936 _SymFromAddr.errcheck = RaiseIfZero 937 938 SymInfo = SYM_INFO() 939 SymInfo.SizeOfStruct = 88 # *don't modify*: sizeof(SYMBOL_INFO) in C. 940 SymInfo.MaxNameLen = MAX_SYM_NAME 941 942 Displacement = DWORD64(0) 943 _SymFromAddr(hProcess, Address, byref(Displacement), byref(SymInfo)) 944 945 return (Displacement.value, SymInfo) 946 947def SymFromAddrW(hProcess, Address): 948 _SymFromAddr = windll.dbghelp.SymFromAddrW 949 _SymFromAddr.argtypes = [HANDLE, DWORD64, PDWORD64, PSYM_INFOW] 950 _SymFromAddr.restype = bool 951 _SymFromAddr.errcheck = RaiseIfZero 952 953 SymInfo = SYM_INFOW() 954 SymInfo.SizeOfStruct = 88 # *don't modify*: sizeof(SYMBOL_INFOW) in C. 955 SymInfo.MaxNameLen = MAX_SYM_NAME 956 957 Displacement = DWORD64(0) 958 _SymFromAddr(hProcess, Address, byref(Displacement), byref(SymInfo)) 959 960 return (Displacement.value, SymInfo) 961 962#=============================================================================== 963# typedef struct _IMAGEHLP_SYMBOL64 { 964# DWORD SizeOfStruct; 965# DWORD64 Address; 966# DWORD Size; 967# DWORD Flags; 968# DWORD MaxNameLength; 969# CHAR Name[1]; 970# } IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64; 971#=============================================================================== 972class IMAGEHLP_SYMBOL64 (Structure): 973 _fields_ = [ 974 ("SizeOfStruct", DWORD), 975 ("Address", DWORD64), 976 ("Size", DWORD), 977 ("Flags", DWORD), 978 ("MaxNameLength", DWORD), 979 ("Name", CHAR * (MAX_SYM_NAME + 1)), 980 ] 981PIMAGEHLP_SYMBOL64 = POINTER(IMAGEHLP_SYMBOL64) 982 983#=============================================================================== 984# typedef struct _IMAGEHLP_SYMBOLW64 { 985# DWORD SizeOfStruct; 986# DWORD64 Address; 987# DWORD Size; 988# DWORD Flags; 989# DWORD MaxNameLength; 990# WCHAR Name[1]; 991# } IMAGEHLP_SYMBOLW64, *PIMAGEHLP_SYMBOLW64; 992#=============================================================================== 993class IMAGEHLP_SYMBOLW64 (Structure): 994 _fields_ = [ 995 ("SizeOfStruct", DWORD), 996 ("Address", DWORD64), 997 ("Size", DWORD), 998 ("Flags", DWORD), 999 ("MaxNameLength", DWORD), 1000 ("Name", WCHAR * (MAX_SYM_NAME + 1)), 1001 ] 1002PIMAGEHLP_SYMBOLW64 = POINTER(IMAGEHLP_SYMBOLW64) 1003 1004#=============================================================================== 1005# BOOL WINAPI SymGetSymFromAddr64( 1006# __in HANDLE hProcess, 1007# __in DWORD64 Address, 1008# __out_opt PDWORD64 Displacement, 1009# __inout PIMAGEHLP_SYMBOL64 Symbol 1010# ); 1011#=============================================================================== 1012def SymGetSymFromAddr64(hProcess, Address): 1013 _SymGetSymFromAddr64 = windll.dbghelp.SymGetSymFromAddr64 1014 _SymGetSymFromAddr64.argtypes = [HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64] 1015 _SymGetSymFromAddr64.restype = bool 1016 _SymGetSymFromAddr64.errcheck = RaiseIfZero 1017 1018 imagehlp_symbol64 = IMAGEHLP_SYMBOL64() 1019 imagehlp_symbol64.SizeOfStruct = 32 # *don't modify*: sizeof(IMAGEHLP_SYMBOL64) in C. 1020 imagehlp_symbol64.MaxNameLen = MAX_SYM_NAME 1021 1022 Displacement = DWORD64(0) 1023 _SymGetSymFromAddr64(hProcess, Address, byref(Displacement), byref(imagehlp_symbol64)) 1024 1025 return (Displacement.value, imagehlp_symbol64) 1026 1027#TODO: check for the 'W' version of SymGetSymFromAddr64() 1028 1029 1030#=============================================================================== 1031# typedef struct API_VERSION { 1032# USHORT MajorVersion; 1033# USHORT MinorVersion; 1034# USHORT Revision; 1035# USHORT Reserved; 1036# } API_VERSION, *LPAPI_VERSION; 1037#=============================================================================== 1038class API_VERSION (Structure): 1039 _fields_ = [ 1040 ("MajorVersion", USHORT), 1041 ("MinorVersion", USHORT), 1042 ("Revision", USHORT), 1043 ("Reserved", USHORT), 1044 ] 1045PAPI_VERSION = POINTER(API_VERSION) 1046LPAPI_VERSION = PAPI_VERSION 1047 1048#=============================================================================== 1049# LPAPI_VERSION WINAPI ImagehlpApiVersion(void); 1050#=============================================================================== 1051def ImagehlpApiVersion(): 1052 _ImagehlpApiVersion = windll.dbghelp.ImagehlpApiVersion 1053 _ImagehlpApiVersion.restype = LPAPI_VERSION 1054 1055 api_version = _ImagehlpApiVersion() 1056 return api_version.contents 1057 1058 1059#=============================================================================== 1060# LPAPI_VERSION WINAPI ImagehlpApiVersionEx( 1061# __in LPAPI_VERSION AppVersion 1062# ); 1063#=============================================================================== 1064def ImagehlpApiVersionEx(MajorVersion, MinorVersion, Revision): 1065 _ImagehlpApiVersionEx = windll.dbghelp.ImagehlpApiVersionEx 1066 _ImagehlpApiVersionEx.argtypes = [LPAPI_VERSION] 1067 _ImagehlpApiVersionEx.restype = LPAPI_VERSION 1068 1069 api_version = API_VERSION(MajorVersion, MinorVersion, Revision, 0) 1070 1071 ret_api_version = _ImagehlpApiVersionEx(byref(api_version)) 1072 1073 return ret_api_version.contents 1074 1075#=============================================================================== 1076# typedef enum { 1077# AddrMode1616, 1078# AddrMode1632, 1079# AddrModeReal, 1080# AddrModeFlat 1081# } ADDRESS_MODE; 1082#=============================================================================== 1083AddrMode1616 = 0 1084AddrMode1632 = 1 1085AddrModeReal = 2 1086AddrModeFlat = 3 1087 1088ADDRESS_MODE = DWORD #needed for the size of an ADDRESS_MODE (see ADDRESS64) 1089 1090#=============================================================================== 1091# typedef struct _tagADDRESS64 { 1092# DWORD64 Offset; 1093# WORD Segment; 1094# ADDRESS_MODE Mode; 1095# } ADDRESS64, *LPADDRESS64; 1096#=============================================================================== 1097class ADDRESS64 (Structure): 1098 _fields_ = [ 1099 ("Offset", DWORD64), 1100 ("Segment", WORD), 1101 ("Mode", ADDRESS_MODE), #it's a member of the ADDRESS_MODE enum. 1102 ] 1103LPADDRESS64 = POINTER(ADDRESS64) 1104 1105#=============================================================================== 1106# typedef struct _KDHELP64 { 1107# DWORD64 Thread; 1108# DWORD ThCallbackStack; 1109# DWORD ThCallbackBStore; 1110# DWORD NextCallback; 1111# DWORD FramePointer; 1112# DWORD64 KiCallUserMode; 1113# DWORD64 KeUserCallbackDispatcher; 1114# DWORD64 SystemRangeStart; 1115# DWORD64 KiUserExceptionDispatcher; 1116# DWORD64 StackBase; 1117# DWORD64 StackLimit; 1118# DWORD64 Reserved[5]; 1119# } KDHELP64, *PKDHELP64; 1120#=============================================================================== 1121class KDHELP64 (Structure): 1122 _fields_ = [ 1123 ("Thread", DWORD64), 1124 ("ThCallbackStack", DWORD), 1125 ("ThCallbackBStore", DWORD), 1126 ("NextCallback", DWORD), 1127 ("FramePointer", DWORD), 1128 ("KiCallUserMode", DWORD64), 1129 ("KeUserCallbackDispatcher", DWORD64), 1130 ("SystemRangeStart", DWORD64), 1131 ("KiUserExceptionDispatcher", DWORD64), 1132 ("StackBase", DWORD64), 1133 ("StackLimit", DWORD64), 1134 ("Reserved", DWORD64 * 5), 1135 ] 1136PKDHELP64 = POINTER(KDHELP64) 1137 1138#=============================================================================== 1139# typedef struct _tagSTACKFRAME64 { 1140# ADDRESS64 AddrPC; 1141# ADDRESS64 AddrReturn; 1142# ADDRESS64 AddrFrame; 1143# ADDRESS64 AddrStack; 1144# ADDRESS64 AddrBStore; 1145# PVOID FuncTableEntry; 1146# DWORD64 Params[4]; 1147# BOOL Far; 1148# BOOL Virtual; 1149# DWORD64 Reserved[3]; 1150# KDHELP64 KdHelp; 1151# } STACKFRAME64, *LPSTACKFRAME64; 1152#=============================================================================== 1153class STACKFRAME64(Structure): 1154 _fields_ = [ 1155 ("AddrPC", ADDRESS64), 1156 ("AddrReturn", ADDRESS64), 1157 ("AddrFrame", ADDRESS64), 1158 ("AddrStack", ADDRESS64), 1159 ("AddrBStore", ADDRESS64), 1160 ("FuncTableEntry", PVOID), 1161 ("Params", DWORD64 * 4), 1162 ("Far", BOOL), 1163 ("Virtual", BOOL), 1164 ("Reserved", DWORD64 * 3), 1165 ("KdHelp", KDHELP64), 1166 ] 1167LPSTACKFRAME64 = POINTER(STACKFRAME64) 1168 1169#=============================================================================== 1170# BOOL CALLBACK ReadProcessMemoryProc64( 1171# __in HANDLE hProcess, 1172# __in DWORD64 lpBaseAddress, 1173# __out PVOID lpBuffer, 1174# __in DWORD nSize, 1175# __out LPDWORD lpNumberOfBytesRead 1176# ); 1177#=============================================================================== 1178PREAD_PROCESS_MEMORY_ROUTINE64 = WINFUNCTYPE(BOOL, HANDLE, DWORD64, PVOID, DWORD, LPDWORD) 1179 1180#=============================================================================== 1181# PVOID CALLBACK FunctionTableAccessProc64( 1182# __in HANDLE hProcess, 1183# __in DWORD64 AddrBase 1184# ); 1185#=============================================================================== 1186PFUNCTION_TABLE_ACCESS_ROUTINE64 = WINFUNCTYPE(PVOID, HANDLE, DWORD64) 1187 1188#=============================================================================== 1189# DWORD64 CALLBACK GetModuleBaseProc64( 1190# __in HANDLE hProcess, 1191# __in DWORD64 Address 1192# ); 1193#=============================================================================== 1194PGET_MODULE_BASE_ROUTINE64 = WINFUNCTYPE(DWORD64, HANDLE, DWORD64) 1195 1196#=============================================================================== 1197# DWORD64 CALLBACK GetModuleBaseProc64( 1198# __in HANDLE hProcess, 1199# __in DWORD64 Address 1200# ); 1201#=============================================================================== 1202PTRANSLATE_ADDRESS_ROUTINE64 = WINFUNCTYPE(DWORD64, HANDLE, DWORD64) 1203 1204# Valid machine types for StackWalk64 function 1205IMAGE_FILE_MACHINE_I386 = 0x014c #Intel x86 1206IMAGE_FILE_MACHINE_IA64 = 0x0200 #Intel Itanium Processor Family (IPF) 1207IMAGE_FILE_MACHINE_AMD64 = 0x8664 #x64 (AMD64 or EM64T) 1208 1209#=============================================================================== 1210# BOOL WINAPI StackWalk64( 1211# __in DWORD MachineType, 1212# __in HANDLE hProcess, 1213# __in HANDLE hThread, 1214# __inout LPSTACKFRAME64 StackFrame, 1215# __inout PVOID ContextRecord, 1216# __in_opt PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, 1217# __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, 1218# __in_opt PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, 1219# __in_opt PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress 1220# ); 1221#=============================================================================== 1222def StackWalk64(MachineType, hProcess, hThread, StackFrame, 1223 ContextRecord = None, ReadMemoryRoutine = None, 1224 FunctionTableAccessRoutine = None, GetModuleBaseRoutine = None, 1225 TranslateAddress = None): 1226 1227 _StackWalk64 = windll.dbghelp.StackWalk64 1228 _StackWalk64.argtypes = [DWORD, HANDLE, HANDLE, LPSTACKFRAME64, PVOID, 1229 PREAD_PROCESS_MEMORY_ROUTINE64, 1230 PFUNCTION_TABLE_ACCESS_ROUTINE64, 1231 PGET_MODULE_BASE_ROUTINE64, 1232 PTRANSLATE_ADDRESS_ROUTINE64] 1233 _StackWalk64.restype = bool 1234 1235 pReadMemoryRoutine = None 1236 if ReadMemoryRoutine: 1237 pReadMemoryRoutine = PREAD_PROCESS_MEMORY_ROUTINE64(ReadMemoryRoutine) 1238 else: 1239 pReadMemoryRoutine = ctypes.cast(None, PREAD_PROCESS_MEMORY_ROUTINE64) 1240 1241 pFunctionTableAccessRoutine = None 1242 if FunctionTableAccessRoutine: 1243 pFunctionTableAccessRoutine = PFUNCTION_TABLE_ACCESS_ROUTINE64(FunctionTableAccessRoutine) 1244 else: 1245 pFunctionTableAccessRoutine = ctypes.cast(None, PFUNCTION_TABLE_ACCESS_ROUTINE64) 1246 1247 pGetModuleBaseRoutine = None 1248 if GetModuleBaseRoutine: 1249 pGetModuleBaseRoutine = PGET_MODULE_BASE_ROUTINE64(GetModuleBaseRoutine) 1250 else: 1251 pGetModuleBaseRoutine = ctypes.cast(None, PGET_MODULE_BASE_ROUTINE64) 1252 1253 pTranslateAddress = None 1254 if TranslateAddress: 1255 pTranslateAddress = PTRANSLATE_ADDRESS_ROUTINE64(TranslateAddress) 1256 else: 1257 pTranslateAddress = ctypes.cast(None, PTRANSLATE_ADDRESS_ROUTINE64) 1258 1259 pContextRecord = None 1260 if ContextRecord is None: 1261 ContextRecord = GetThreadContext(hThread, raw=True) 1262 pContextRecord = PCONTEXT(ContextRecord) 1263 1264 #this function *DOESN'T* set last error [GetLastError()] properly most of the time. 1265 ret = _StackWalk64(MachineType, hProcess, hThread, byref(StackFrame), 1266 pContextRecord, pReadMemoryRoutine, 1267 pFunctionTableAccessRoutine, pGetModuleBaseRoutine, 1268 pTranslateAddress) 1269 1270 return ret 1271 1272#============================================================================== 1273# This calculates the list of exported symbols. 1274_all = set(vars().keys()).difference(_all) 1275__all__ = [_x for _x in _all if not _x.startswith('_')] 1276__all__.sort() 1277#============================================================================== 1278