1# DExTer : Debugging Experience Tester 2# ~~~~~~ ~ ~~ ~ ~~ 3# 4# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5# See https://llvm.org/LICENSE.txt for license information. 6# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 8from collections import namedtuple 9from ctypes import * 10from enum import * 11from functools import reduce, partial 12 13from .symgroup import SymbolGroup, IDebugSymbolGroup2 14from .utils import * 15 16class SymbolOptionFlags(IntFlag): 17 SYMOPT_CASE_INSENSITIVE = 0x00000001 18 SYMOPT_UNDNAME = 0x00000002 19 SYMOPT_DEFERRED_LOADS = 0x00000004 20 SYMOPT_NO_CPP = 0x00000008 21 SYMOPT_LOAD_LINES = 0x00000010 22 SYMOPT_OMAP_FIND_NEAREST = 0x00000020 23 SYMOPT_LOAD_ANYTHING = 0x00000040 24 SYMOPT_IGNORE_CVREC = 0x00000080 25 SYMOPT_NO_UNQUALIFIED_LOADS = 0x00000100 26 SYMOPT_FAIL_CRITICAL_ERRORS = 0x00000200 27 SYMOPT_EXACT_SYMBOLS = 0x00000400 28 SYMOPT_ALLOW_ABSOLUTE_SYMBOLS = 0x00000800 29 SYMOPT_IGNORE_NT_SYMPATH = 0x00001000 30 SYMOPT_INCLUDE_32BIT_MODULES = 0x00002000 31 SYMOPT_PUBLICS_ONLY = 0x00004000 32 SYMOPT_NO_PUBLICS = 0x00008000 33 SYMOPT_AUTO_PUBLICS = 0x00010000 34 SYMOPT_NO_IMAGE_SEARCH = 0x00020000 35 SYMOPT_SECURE = 0x00040000 36 SYMOPT_NO_PROMPTS = 0x00080000 37 SYMOPT_DEBUG = 0x80000000 38 39class ScopeGroupFlags(IntFlag): 40 DEBUG_SCOPE_GROUP_ARGUMENTS = 0x00000001 41 DEBUG_SCOPE_GROUP_LOCALS = 0x00000002 42 DEBUG_SCOPE_GROUP_ALL = 0x00000003 43 DEBUG_SCOPE_GROUP_BY_DATAMODEL = 0x00000004 44 45class DebugModuleNames(IntEnum): 46 DEBUG_MODNAME_IMAGE = 0x00000000 47 DEBUG_MODNAME_MODULE = 0x00000001 48 DEBUG_MODNAME_LOADED_IMAGE = 0x00000002 49 DEBUG_MODNAME_SYMBOL_FILE = 0x00000003 50 DEBUG_MODNAME_MAPPED_IMAGE = 0x00000004 51 52class DebugModuleFlags(IntFlag): 53 DEBUG_MODULE_LOADED = 0x00000000 54 DEBUG_MODULE_UNLOADED = 0x00000001 55 DEBUG_MODULE_USER_MODE = 0x00000002 56 DEBUG_MODULE_EXE_MODULE = 0x00000004 57 DEBUG_MODULE_EXPLICIT = 0x00000008 58 DEBUG_MODULE_SECONDARY = 0x00000010 59 DEBUG_MODULE_SYNTHETIC = 0x00000020 60 DEBUG_MODULE_SYM_BAD_CHECKSUM = 0x00010000 61 62class DEBUG_MODULE_PARAMETERS(Structure): 63 _fields_ = [ 64 ("Base", c_ulonglong), 65 ("Size", c_ulong), 66 ("TimeDateStamp", c_ulong), 67 ("Checksum", c_ulong), 68 ("Flags", c_ulong), 69 ("SymbolType", c_ulong), 70 ("ImageNameSize", c_ulong), 71 ("ModuleNameSize", c_ulong), 72 ("LoadedImageNameSize", c_ulong), 73 ("SymbolFileNameSize", c_ulong), 74 ("MappedImageNameSize", c_ulong), 75 ("Reserved", c_ulonglong * 2) 76 ] 77PDEBUG_MODULE_PARAMETERS = POINTER(DEBUG_MODULE_PARAMETERS) 78 79class DEBUG_MODULE_AND_ID(Structure): 80 _fields_ = [ 81 ("ModuleBase", c_ulonglong), 82 ("Id", c_ulonglong) 83 ] 84PDEBUG_MODULE_AND_ID = POINTER(DEBUG_MODULE_AND_ID) 85 86class DEBUG_SYMBOL_ENTRY(Structure): 87 _fields_ = [ 88 ("ModuleBase", c_ulonglong), 89 ("Offset", c_ulonglong), 90 ("Id", c_ulonglong), 91 ("Arg64", c_ulonglong), 92 ("Size", c_ulong), 93 ("Flags", c_ulong), 94 ("TypeId", c_ulong), 95 ("NameSize", c_ulong), 96 ("Token", c_ulong), 97 ("Tag", c_ulong), 98 ("Arg32", c_ulong), 99 ("Reserved", c_ulong) 100 ] 101PDEBUG_SYMBOL_ENTRY = POINTER(DEBUG_SYMBOL_ENTRY) 102 103# UUID for DebugSymbols5 interface. 104DebugSymbols5IID = IID(0xc65fa83e, 0x1e69, 0x475e, IID_Data4_Type(0x8e, 0x0e, 0xb5, 0xd7, 0x9e, 0x9c, 0xc1, 0x7e)) 105 106class IDebugSymbols5(Structure): 107 pass 108 109class IDebugSymbols5Vtbl(Structure): 110 wrp = partial(WINFUNCTYPE, c_long, POINTER(IDebugSymbols5)) 111 ids_getsymboloptions = wrp(c_ulong_p) 112 ids_setsymboloptions = wrp(c_ulong) 113 ids_getmoduleparameters = wrp(c_ulong, c_ulong64_p, c_ulong, PDEBUG_MODULE_PARAMETERS) 114 ids_getmodulenamestring = wrp(c_ulong, c_ulong, c_ulonglong, c_char_p, c_ulong, c_ulong_p) 115 ids_getoffsetbyname = wrp(c_char_p, c_ulong64_p) 116 ids_getlinebyoffset = wrp(c_ulonglong, c_ulong_p, c_char_p, c_ulong, c_ulong_p, c_ulong64_p) 117 ids_getsymbolentriesbyname = wrp(c_char_p, c_ulong, PDEBUG_MODULE_AND_ID, c_ulong, c_ulong_p) 118 ids_getsymbolentrystring = wrp(PDEBUG_MODULE_AND_ID, c_ulong, c_char_p, c_ulong, c_ulong_p) 119 ids_getsymbolentryinformation = wrp(PDEBUG_MODULE_AND_ID, PDEBUG_SYMBOL_ENTRY) 120 ids_getcurrentscopeframeindex = wrp(c_ulong_p) 121 ids_getnearnamebyoffset = wrp(c_ulonglong, c_long, c_char_p, c_ulong, c_ulong_p, c_ulong64_p) 122 ids_setscopeframebyindex = wrp(c_ulong) 123 ids_getscopesymbolgroup2 = wrp(c_ulong, POINTER(IDebugSymbolGroup2), POINTER(POINTER(IDebugSymbolGroup2))) 124 ids_getnamebyinlinecontext = wrp(c_ulonglong, c_ulong, c_char_p, c_ulong, c_ulong_p, c_ulong64_p) 125 ids_getlinebyinlinecontext = wrp(c_ulonglong, c_ulong, c_ulong_p, c_char_p, c_ulong, c_ulong_p, c_ulong64_p) 126 _fields_ = [ 127 ("QueryInterface", c_void_p), 128 ("AddRef", c_void_p), 129 ("Release", c_void_p), 130 ("GetSymbolOptions", ids_getsymboloptions), 131 ("AddSymbolOptions", c_void_p), 132 ("RemoveSymbolOptions", c_void_p), 133 ("SetSymbolOptions", ids_setsymboloptions), 134 ("GetNameByOffset", c_void_p), 135 ("GetOffsetByName", ids_getoffsetbyname), 136 ("GetNearNameByOffset", ids_getnearnamebyoffset), 137 ("GetLineByOffset", ids_getlinebyoffset), 138 ("GetOffsetByLine", c_void_p), 139 ("GetNumberModules", c_void_p), 140 ("GetModuleByIndex", c_void_p), 141 ("GetModuleByModuleName", c_void_p), 142 ("GetModuleByOffset", c_void_p), 143 ("GetModuleNames", c_void_p), 144 ("GetModuleParameters", ids_getmoduleparameters), 145 ("GetSymbolModule", c_void_p), 146 ("GetTypeName", c_void_p), 147 ("GetTypeId", c_void_p), 148 ("GetTypeSize", c_void_p), 149 ("GetFieldOffset", c_void_p), 150 ("GetSymbolTypeId", c_void_p), 151 ("GetOffsetTypeId", c_void_p), 152 ("ReadTypedDataVirtual", c_void_p), 153 ("WriteTypedDataVirtual", c_void_p), 154 ("OutputTypedDataVirtual", c_void_p), 155 ("ReadTypedDataPhysical", c_void_p), 156 ("WriteTypedDataPhysical", c_void_p), 157 ("OutputTypedDataPhysical", c_void_p), 158 ("GetScope", c_void_p), 159 ("SetScope", c_void_p), 160 ("ResetScope", c_void_p), 161 ("GetScopeSymbolGroup", c_void_p), 162 ("CreateSymbolGroup", c_void_p), 163 ("StartSymbolMatch", c_void_p), 164 ("GetNextSymbolMatch", c_void_p), 165 ("EndSymbolMatch", c_void_p), 166 ("Reload", c_void_p), 167 ("GetSymbolPath", c_void_p), 168 ("SetSymbolPath", c_void_p), 169 ("AppendSymbolPath", c_void_p), 170 ("GetImagePath", c_void_p), 171 ("SetImagePath", c_void_p), 172 ("AppendImagePath", c_void_p), 173 ("GetSourcePath", c_void_p), 174 ("GetSourcePathElement", c_void_p), 175 ("SetSourcePath", c_void_p), 176 ("AppendSourcePath", c_void_p), 177 ("FindSourceFile", c_void_p), 178 ("GetSourceFileLineOffsets", c_void_p), 179 ("GetModuleVersionInformation", c_void_p), 180 ("GetModuleNameString", ids_getmodulenamestring), 181 ("GetConstantName", c_void_p), 182 ("GetFieldName", c_void_p), 183 ("GetTypeOptions", c_void_p), 184 ("AddTypeOptions", c_void_p), 185 ("RemoveTypeOptions", c_void_p), 186 ("SetTypeOptions", c_void_p), 187 ("GetNameByOffsetWide", c_void_p), 188 ("GetOffsetByNameWide", c_void_p), 189 ("GetNearNameByOffsetWide", c_void_p), 190 ("GetLineByOffsetWide", c_void_p), 191 ("GetOffsetByLineWide", c_void_p), 192 ("GetModuleByModuleNameWide", c_void_p), 193 ("GetSymbolModuleWide", c_void_p), 194 ("GetTypeNameWide", c_void_p), 195 ("GetTypeIdWide", c_void_p), 196 ("GetFieldOffsetWide", c_void_p), 197 ("GetSymbolTypeIdWide", c_void_p), 198 ("GetScopeSymbolGroup2", ids_getscopesymbolgroup2), 199 ("CreateSymbolGroup2", c_void_p), 200 ("StartSymbolMatchWide", c_void_p), 201 ("GetNextSymbolMatchWide", c_void_p), 202 ("ReloadWide", c_void_p), 203 ("GetSymbolPathWide", c_void_p), 204 ("SetSymbolPathWide", c_void_p), 205 ("AppendSymbolPathWide", c_void_p), 206 ("GetImagePathWide", c_void_p), 207 ("SetImagePathWide", c_void_p), 208 ("AppendImagePathWide", c_void_p), 209 ("GetSourcePathWide", c_void_p), 210 ("GetSourcePathElementWide", c_void_p), 211 ("SetSourcePathWide", c_void_p), 212 ("AppendSourcePathWide", c_void_p), 213 ("FindSourceFileWide", c_void_p), 214 ("GetSourceFileLineOffsetsWide", c_void_p), 215 ("GetModuleVersionInformationWide", c_void_p), 216 ("GetModuleNameStringWide", c_void_p), 217 ("GetConstantNameWide", c_void_p), 218 ("GetFieldNameWide", c_void_p), 219 ("IsManagedModule", c_void_p), 220 ("GetModuleByModuleName2", c_void_p), 221 ("GetModuleByModuleName2Wide", c_void_p), 222 ("GetModuleByOffset2", c_void_p), 223 ("AddSyntheticModule", c_void_p), 224 ("AddSyntheticModuleWide", c_void_p), 225 ("RemoveSyntheticModule", c_void_p), 226 ("GetCurrentScopeFrameIndex", ids_getcurrentscopeframeindex), 227 ("SetScopeFrameByIndex", ids_setscopeframebyindex), 228 ("SetScopeFromJitDebugInfo", c_void_p), 229 ("SetScopeFromStoredEvent", c_void_p), 230 ("OutputSymbolByOffset", c_void_p), 231 ("GetFunctionEntryByOffset", c_void_p), 232 ("GetFieldTypeAndOffset", c_void_p), 233 ("GetFieldTypeAndOffsetWide", c_void_p), 234 ("AddSyntheticSymbol", c_void_p), 235 ("AddSyntheticSymbolWide", c_void_p), 236 ("RemoveSyntheticSymbol", c_void_p), 237 ("GetSymbolEntriesByOffset", c_void_p), 238 ("GetSymbolEntriesByName", ids_getsymbolentriesbyname), 239 ("GetSymbolEntriesByNameWide", c_void_p), 240 ("GetSymbolEntryByToken", c_void_p), 241 ("GetSymbolEntryInformation", ids_getsymbolentryinformation), 242 ("GetSymbolEntryString", ids_getsymbolentrystring), 243 ("GetSymbolEntryStringWide", c_void_p), 244 ("GetSymbolEntryOffsetRegions", c_void_p), 245 ("GetSymbolEntryBySymbolEntry", c_void_p), 246 ("GetSourceEntriesByOffset", c_void_p), 247 ("GetSourceEntriesByLine", c_void_p), 248 ("GetSourceEntriesByLineWide", c_void_p), 249 ("GetSourceEntryString", c_void_p), 250 ("GetSourceEntryStringWide", c_void_p), 251 ("GetSourceEntryOffsetRegions", c_void_p), 252 ("GetsourceEntryBySourceEntry", c_void_p), 253 ("GetScopeEx", c_void_p), 254 ("SetScopeEx", c_void_p), 255 ("GetNameByInlineContext", ids_getnamebyinlinecontext), 256 ("GetNameByInlineContextWide", c_void_p), 257 ("GetLineByInlineContext", ids_getlinebyinlinecontext), 258 ("GetLineByInlineContextWide", c_void_p), 259 ("OutputSymbolByInlineContext", c_void_p), 260 ("GetCurrentScopeFrameIndexEx", c_void_p), 261 ("SetScopeFrameByIndexEx", c_void_p) 262 ] 263 264IDebugSymbols5._fields_ = [("lpVtbl", POINTER(IDebugSymbols5Vtbl))] 265 266SymbolId = namedtuple("SymbolId", ["ModuleBase", "Id"]) 267SymbolEntry = namedtuple("SymbolEntry", ["ModuleBase", "Offset", "Id", "Arg64", "Size", "Flags", "TypeId", "NameSize", "Token", "Tag", "Arg32"]) 268DebugModuleParams = namedtuple("DebugModuleParams", ["Base", "Size", "TimeDateStamp", "Checksum", "Flags", "SymbolType", "ImageNameSize", "ModuleNameSize", "LoadedImageNameSize", "SymbolFileNameSize", "MappedImageNameSize"]) 269 270class SymTags(IntEnum): 271 Null = 0 272 Exe = 1 273 SymTagFunction = 5 274 275def make_debug_module_params(cdata): 276 fieldvalues = map(lambda y: getattr(cdata, y), DebugModuleParams._fields) 277 return DebugModuleParams(*fieldvalues) 278 279class Symbols(object): 280 def __init__(self, symbols): 281 self.ptr = symbols 282 self.symbols = symbols.contents 283 self.vt = self.symbols.lpVtbl.contents 284 # Keep some handy ulongs for passing into C methods. 285 self.ulong = c_ulong() 286 self.ulong64 = c_ulonglong() 287 288 def GetCurrentScopeFrameIndex(self): 289 res = self.vt.GetCurrentScopeFrameIndex(self.symbols, byref(self.ulong)) 290 aborter(res, "GetCurrentScopeFrameIndex") 291 return self.ulong.value 292 293 def SetScopeFrameByIndex(self, idx): 294 res = self.vt.SetScopeFrameByIndex(self.symbols, idx) 295 aborter(res, "SetScopeFrameByIndex", ignore=[E_EINVAL]) 296 return res != E_EINVAL 297 298 def GetOffsetByName(self, name): 299 res = self.vt.GetOffsetByName(self.symbols, name.encode("ascii"), byref(self.ulong64)) 300 aborter(res, "GetOffsetByName {}".format(name)) 301 return self.ulong64.value 302 303 def GetNearNameByOffset(self, addr): 304 ptr = create_string_buffer(256) 305 pulong = c_ulong() 306 disp = c_ulonglong() 307 # Zero arg -> "delta" indicating how many symbols to skip 308 res = self.vt.GetNearNameByOffset(self.symbols, addr, 0, ptr, 255, byref(pulong), byref(disp)) 309 if res == E_NOINTERFACE: 310 return "{noname}" 311 aborter(res, "GetNearNameByOffset") 312 ptr[255] = '\0'.encode("ascii") 313 return '{}+{}'.format(string_at(ptr).decode("ascii"), disp.value) 314 315 def GetModuleByModuleName2(self, name): 316 # First zero arg -> module index to search from, second zero arg -> 317 # DEBUG_GETMOD_* flags, none of which we use. 318 res = self.vt.GetModuleByModuleName2(self.symbols, name, 0, 0, None, byref(self.ulong64)) 319 aborter(res, "GetModuleByModuleName2") 320 return self.ulong64.value 321 322 def GetScopeSymbolGroup2(self): 323 retptr = POINTER(IDebugSymbolGroup2)() 324 res = self.vt.GetScopeSymbolGroup2(self.symbols, ScopeGroupFlags.DEBUG_SCOPE_GROUP_ALL, None, retptr) 325 aborter(res, "GetScopeSymbolGroup2") 326 return SymbolGroup(retptr) 327 328 def GetSymbolEntryString(self, idx, module): 329 symid = DEBUG_MODULE_AND_ID() 330 symid.ModuleBase = module 331 symid.Id = idx 332 ptr = create_string_buffer(1024) 333 # Zero arg is the string index -- symbols can have multiple names, for now 334 # only support the first one. 335 res = self.vt.GetSymbolEntryString(self.symbols, symid, 0, ptr, 1023, byref(self.ulong)) 336 aborter(res, "GetSymbolEntryString") 337 return string_at(ptr).decode("ascii") 338 339 def GetSymbolEntryInformation(self, module, theid): 340 symid = DEBUG_MODULE_AND_ID() 341 symentry = DEBUG_SYMBOL_ENTRY() 342 symid.ModuleBase = module 343 symid.Id = theid 344 res = self.vt.GetSymbolEntryInformation(self.symbols, symid, symentry) 345 aborter(res, "GetSymbolEntryInformation") 346 # Fetch fields into SymbolEntry object 347 fields = map(lambda x: getattr(symentry, x), SymbolEntry._fields) 348 return SymbolEntry(*fields) 349 350 def GetSymbolEntriesByName(self, symstr): 351 # Initial query to find number of symbol entries 352 res = self.vt.GetSymbolEntriesByName(self.symbols, symstr.encode("ascii"), 0, None, 0, byref(self.ulong)) 353 aborter(res, "GetSymbolEntriesByName") 354 355 # Build a buffer and query for 'length' entries 356 length = self.ulong.value 357 symrecs = (DEBUG_MODULE_AND_ID * length)() 358 # Zero arg -> flags, of which there are none defined. 359 res = self.vt.GetSymbolEntriesByName(self.symbols, symstr.encode("ascii"), 0, symrecs, length, byref(self.ulong)) 360 aborter(res, "GetSymbolEntriesByName") 361 362 # Extract 'length' number of SymbolIds 363 length = self.ulong.value 364 def extract(x): 365 sym = symrecs[x] 366 return SymbolId(sym.ModuleBase, sym.Id) 367 return [extract(x) for x in range(length)] 368 369 def GetSymbolPath(self): 370 # Query for length of buffer to allocate 371 res = self.vt.GetSymbolPath(self.symbols, None, 0, byref(self.ulong)) 372 aborter(res, "GetSymbolPath", ignore=[S_FALSE]) 373 374 # Fetch 'length' length symbol path string 375 length = self.ulong.value 376 arr = create_string_buffer(length) 377 res = self.vt.GetSymbolPath(self.symbols, arr, length, byref(self.ulong)) 378 aborter(res, "GetSymbolPath") 379 380 return string_at(arr).decode("ascii") 381 382 def GetSourcePath(self): 383 # Query for length of buffer to allocate 384 res = self.vt.GetSourcePath(self.symbols, None, 0, byref(self.ulong)) 385 aborter(res, "GetSourcePath", ignore=[S_FALSE]) 386 387 # Fetch a string of len 'length' 388 length = self.ulong.value 389 arr = create_string_buffer(length) 390 res = self.vt.GetSourcePath(self.symbols, arr, length, byref(self.ulong)) 391 aborter(res, "GetSourcePath") 392 393 return string_at(arr).decode("ascii") 394 395 def SetSourcePath(self, string): 396 res = self.vt.SetSourcePath(self.symbols, string.encode("ascii")) 397 aborter(res, "SetSourcePath") 398 return 399 400 def GetModuleParameters(self, base): 401 self.ulong64.value = base 402 params = DEBUG_MODULE_PARAMETERS() 403 # Fetch one module params struct, starting at idx zero 404 res = self.vt.GetModuleParameters(self.symbols, 1, byref(self.ulong64), 0, byref(params)) 405 aborter(res, "GetModuleParameters") 406 return make_debug_module_params(params) 407 408 def GetSymbolOptions(self): 409 res = self.vt.GetSymbolOptions(self.symbols, byref(self.ulong)) 410 aborter(res, "GetSymbolOptions") 411 return SymbolOptionFlags(self.ulong.value) 412 413 def SetSymbolOptions(self, opts): 414 assert isinstance(opts, SymbolOptionFlags) 415 res = self.vt.SetSymbolOptions(self.symbols, opts.value) 416 aborter(res, "SetSymbolOptions") 417 return 418 419 def GetLineByOffset(self, offs): 420 # Initial query for filename buffer size 421 res = self.vt.GetLineByOffset(self.symbols, offs, None, None, 0, byref(self.ulong), None) 422 if res == E_FAIL: 423 return None # Sometimes we just can't get line numbers, of course 424 aborter(res, "GetLineByOffset", ignore=[S_FALSE]) 425 426 # Allocate filename buffer and query for line number too 427 filenamelen = self.ulong.value 428 text = create_string_buffer(filenamelen) 429 line = c_ulong() 430 res = self.vt.GetLineByOffset(self.symbols, offs, byref(line), text, filenamelen, byref(self.ulong), None) 431 aborter(res, "GetLineByOffset") 432 433 return string_at(text).decode("ascii"), line.value 434 435 def GetModuleNameString(self, whichname, base): 436 # Initial query for name string length 437 res = self.vt.GetModuleNameString(self.symbols, whichname, DEBUG_ANY_ID, base, None, 0, byref(self.ulong)) 438 aborter(res, "GetModuleNameString", ignore=[S_FALSE]) 439 440 module_name_len = self.ulong.value 441 module_name = (c_char * module_name_len)() 442 res = self.vt.GetModuleNameString(self.symbols, whichname, DEBUG_ANY_ID, base, module_name, module_name_len, None) 443 aborter(res, "GetModuleNameString") 444 445 return string_at(module_name).decode("ascii") 446 447 def GetNameByInlineContext(self, pc, ctx): 448 # None args -> ignore output name size and displacement 449 buf = create_string_buffer(256) 450 res = self.vt.GetNameByInlineContext(self.symbols, pc, ctx, buf, 255, None, None) 451 aborter(res, "GetNameByInlineContext") 452 return string_at(buf).decode("ascii") 453 454 def GetLineByInlineContext(self, pc, ctx): 455 # None args -> ignore output filename size and displacement 456 buf = create_string_buffer(256) 457 res = self.vt.GetLineByInlineContext(self.symbols, pc, ctx, byref(self.ulong), buf, 255, None, None) 458 aborter(res, "GetLineByInlineContext") 459 return string_at(buf).decode("ascii"), self.ulong.value 460 461 def get_all_symbols(self): 462 main_module_name = self.get_exefile_module_name() 463 idnumbers = self.GetSymbolEntriesByName("{}!*".format(main_module_name)) 464 lst = [] 465 for symid in idnumbers: 466 s = self.GetSymbolEntryString(symid.Id, symid.ModuleBase) 467 symentry = self.GetSymbolEntryInformation(symid.ModuleBase, symid.Id) 468 lst.append((s, symentry)) 469 return lst 470 471 def get_all_functions(self): 472 syms = self.get_all_symbols() 473 return [x for x in syms if x[1].Tag == SymTags.SymTagFunction] 474 475 def get_all_modules(self): 476 params = DEBUG_MODULE_PARAMETERS() 477 idx = 0 478 res = 0 479 all_modules = [] 480 while res != E_EINVAL: 481 res = self.vt.GetModuleParameters(self.symbols, 1, None, idx, byref(params)) 482 aborter(res, "GetModuleParameters", ignore=[E_EINVAL]) 483 all_modules.append(make_debug_module_params(params)) 484 idx += 1 485 return all_modules 486 487 def get_exefile_module(self): 488 all_modules = self.get_all_modules() 489 reduce_func = lambda x, y: y if y.Flags & DebugModuleFlags.DEBUG_MODULE_EXE_MODULE else x 490 main_module = reduce(reduce_func, all_modules, None) 491 if main_module is None: 492 raise Exception("Couldn't find the exefile module") 493 return main_module 494 495 def get_module_name(self, base): 496 return self.GetModuleNameString(DebugModuleNames.DEBUG_MODNAME_MODULE, base) 497 498 def get_exefile_module_name(self): 499 return self.get_module_name(self.get_exefile_module().Base) 500