607 lines · python
1# DExTer : Debugging Experience Tester2# ~~~~~~ ~ ~~ ~ ~~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-exception7 8from collections import namedtuple9from ctypes import *10from enum import *11from functools import reduce, partial12 13from .symgroup import SymbolGroup, IDebugSymbolGroup214from .utils import *15 16 17class SymbolOptionFlags(IntFlag):18 SYMOPT_CASE_INSENSITIVE = 0x0000000119 SYMOPT_UNDNAME = 0x0000000220 SYMOPT_DEFERRED_LOADS = 0x0000000421 SYMOPT_NO_CPP = 0x0000000822 SYMOPT_LOAD_LINES = 0x0000001023 SYMOPT_OMAP_FIND_NEAREST = 0x0000002024 SYMOPT_LOAD_ANYTHING = 0x0000004025 SYMOPT_IGNORE_CVREC = 0x0000008026 SYMOPT_NO_UNQUALIFIED_LOADS = 0x0000010027 SYMOPT_FAIL_CRITICAL_ERRORS = 0x0000020028 SYMOPT_EXACT_SYMBOLS = 0x0000040029 SYMOPT_ALLOW_ABSOLUTE_SYMBOLS = 0x0000080030 SYMOPT_IGNORE_NT_SYMPATH = 0x0000100031 SYMOPT_INCLUDE_32BIT_MODULES = 0x0000200032 SYMOPT_PUBLICS_ONLY = 0x0000400033 SYMOPT_NO_PUBLICS = 0x0000800034 SYMOPT_AUTO_PUBLICS = 0x0001000035 SYMOPT_NO_IMAGE_SEARCH = 0x0002000036 SYMOPT_SECURE = 0x0004000037 SYMOPT_NO_PROMPTS = 0x0008000038 SYMOPT_DEBUG = 0x8000000039 40 41class ScopeGroupFlags(IntFlag):42 DEBUG_SCOPE_GROUP_ARGUMENTS = 0x0000000143 DEBUG_SCOPE_GROUP_LOCALS = 0x0000000244 DEBUG_SCOPE_GROUP_ALL = 0x0000000345 DEBUG_SCOPE_GROUP_BY_DATAMODEL = 0x0000000446 47 48class DebugModuleNames(IntEnum):49 DEBUG_MODNAME_IMAGE = 0x0000000050 DEBUG_MODNAME_MODULE = 0x0000000151 DEBUG_MODNAME_LOADED_IMAGE = 0x0000000252 DEBUG_MODNAME_SYMBOL_FILE = 0x0000000353 DEBUG_MODNAME_MAPPED_IMAGE = 0x0000000454 55 56class DebugModuleFlags(IntFlag):57 DEBUG_MODULE_LOADED = 0x0000000058 DEBUG_MODULE_UNLOADED = 0x0000000159 DEBUG_MODULE_USER_MODE = 0x0000000260 DEBUG_MODULE_EXE_MODULE = 0x0000000461 DEBUG_MODULE_EXPLICIT = 0x0000000862 DEBUG_MODULE_SECONDARY = 0x0000001063 DEBUG_MODULE_SYNTHETIC = 0x0000002064 DEBUG_MODULE_SYM_BAD_CHECKSUM = 0x0001000065 66 67class DEBUG_MODULE_PARAMETERS(Structure):68 _fields_ = [69 ("Base", c_ulonglong),70 ("Size", c_ulong),71 ("TimeDateStamp", c_ulong),72 ("Checksum", c_ulong),73 ("Flags", c_ulong),74 ("SymbolType", c_ulong),75 ("ImageNameSize", c_ulong),76 ("ModuleNameSize", c_ulong),77 ("LoadedImageNameSize", c_ulong),78 ("SymbolFileNameSize", c_ulong),79 ("MappedImageNameSize", c_ulong),80 ("Reserved", c_ulonglong * 2),81 ]82 83 84PDEBUG_MODULE_PARAMETERS = POINTER(DEBUG_MODULE_PARAMETERS)85 86 87class DEBUG_MODULE_AND_ID(Structure):88 _fields_ = [("ModuleBase", c_ulonglong), ("Id", c_ulonglong)]89 90 91PDEBUG_MODULE_AND_ID = POINTER(DEBUG_MODULE_AND_ID)92 93 94class DEBUG_SYMBOL_ENTRY(Structure):95 _fields_ = [96 ("ModuleBase", c_ulonglong),97 ("Offset", c_ulonglong),98 ("Id", c_ulonglong),99 ("Arg64", c_ulonglong),100 ("Size", c_ulong),101 ("Flags", c_ulong),102 ("TypeId", c_ulong),103 ("NameSize", c_ulong),104 ("Token", c_ulong),105 ("Tag", c_ulong),106 ("Arg32", c_ulong),107 ("Reserved", c_ulong),108 ]109 110 111PDEBUG_SYMBOL_ENTRY = POINTER(DEBUG_SYMBOL_ENTRY)112 113# UUID for DebugSymbols5 interface.114DebugSymbols5IID = IID(115 0xC65FA83E,116 0x1E69,117 0x475E,118 IID_Data4_Type(0x8E, 0x0E, 0xB5, 0xD7, 0x9E, 0x9C, 0xC1, 0x7E),119)120 121 122class IDebugSymbols5(Structure):123 pass124 125 126class IDebugSymbols5Vtbl(Structure):127 wrp = partial(WINFUNCTYPE, c_long, POINTER(IDebugSymbols5))128 ids_getsymboloptions = wrp(c_ulong_p)129 ids_setsymboloptions = wrp(c_ulong)130 ids_getmoduleparameters = wrp(131 c_ulong, c_ulong64_p, c_ulong, PDEBUG_MODULE_PARAMETERS132 )133 ids_getmodulenamestring = wrp(134 c_ulong, c_ulong, c_ulonglong, c_char_p, c_ulong, c_ulong_p135 )136 ids_getoffsetbyname = wrp(c_char_p, c_ulong64_p)137 ids_getlinebyoffset = wrp(138 c_ulonglong, c_ulong_p, c_char_p, c_ulong, c_ulong_p, c_ulong64_p139 )140 ids_getsymbolentriesbyname = wrp(141 c_char_p, c_ulong, PDEBUG_MODULE_AND_ID, c_ulong, c_ulong_p142 )143 ids_getsymbolentrystring = wrp(144 PDEBUG_MODULE_AND_ID, c_ulong, c_char_p, c_ulong, c_ulong_p145 )146 ids_getsymbolentryinformation = wrp(PDEBUG_MODULE_AND_ID, PDEBUG_SYMBOL_ENTRY)147 ids_getcurrentscopeframeindex = wrp(c_ulong_p)148 ids_getnearnamebyoffset = wrp(149 c_ulonglong, c_long, c_char_p, c_ulong, c_ulong_p, c_ulong64_p150 )151 ids_setscopeframebyindex = wrp(c_ulong)152 ids_getscopesymbolgroup2 = wrp(153 c_ulong, POINTER(IDebugSymbolGroup2), POINTER(POINTER(IDebugSymbolGroup2))154 )155 ids_getnamebyinlinecontext = wrp(156 c_ulonglong, c_ulong, c_char_p, c_ulong, c_ulong_p, c_ulong64_p157 )158 ids_getlinebyinlinecontext = wrp(159 c_ulonglong, c_ulong, c_ulong_p, c_char_p, c_ulong, c_ulong_p, c_ulong64_p160 )161 _fields_ = [162 ("QueryInterface", c_void_p),163 ("AddRef", c_void_p),164 ("Release", c_void_p),165 ("GetSymbolOptions", ids_getsymboloptions),166 ("AddSymbolOptions", c_void_p),167 ("RemoveSymbolOptions", c_void_p),168 ("SetSymbolOptions", ids_setsymboloptions),169 ("GetNameByOffset", c_void_p),170 ("GetOffsetByName", ids_getoffsetbyname),171 ("GetNearNameByOffset", ids_getnearnamebyoffset),172 ("GetLineByOffset", ids_getlinebyoffset),173 ("GetOffsetByLine", c_void_p),174 ("GetNumberModules", c_void_p),175 ("GetModuleByIndex", c_void_p),176 ("GetModuleByModuleName", c_void_p),177 ("GetModuleByOffset", c_void_p),178 ("GetModuleNames", c_void_p),179 ("GetModuleParameters", ids_getmoduleparameters),180 ("GetSymbolModule", c_void_p),181 ("GetTypeName", c_void_p),182 ("GetTypeId", c_void_p),183 ("GetTypeSize", c_void_p),184 ("GetFieldOffset", c_void_p),185 ("GetSymbolTypeId", c_void_p),186 ("GetOffsetTypeId", c_void_p),187 ("ReadTypedDataVirtual", c_void_p),188 ("WriteTypedDataVirtual", c_void_p),189 ("OutputTypedDataVirtual", c_void_p),190 ("ReadTypedDataPhysical", c_void_p),191 ("WriteTypedDataPhysical", c_void_p),192 ("OutputTypedDataPhysical", c_void_p),193 ("GetScope", c_void_p),194 ("SetScope", c_void_p),195 ("ResetScope", c_void_p),196 ("GetScopeSymbolGroup", c_void_p),197 ("CreateSymbolGroup", c_void_p),198 ("StartSymbolMatch", c_void_p),199 ("GetNextSymbolMatch", c_void_p),200 ("EndSymbolMatch", c_void_p),201 ("Reload", c_void_p),202 ("GetSymbolPath", c_void_p),203 ("SetSymbolPath", c_void_p),204 ("AppendSymbolPath", c_void_p),205 ("GetImagePath", c_void_p),206 ("SetImagePath", c_void_p),207 ("AppendImagePath", c_void_p),208 ("GetSourcePath", c_void_p),209 ("GetSourcePathElement", c_void_p),210 ("SetSourcePath", c_void_p),211 ("AppendSourcePath", c_void_p),212 ("FindSourceFile", c_void_p),213 ("GetSourceFileLineOffsets", c_void_p),214 ("GetModuleVersionInformation", c_void_p),215 ("GetModuleNameString", ids_getmodulenamestring),216 ("GetConstantName", c_void_p),217 ("GetFieldName", c_void_p),218 ("GetTypeOptions", c_void_p),219 ("AddTypeOptions", c_void_p),220 ("RemoveTypeOptions", c_void_p),221 ("SetTypeOptions", c_void_p),222 ("GetNameByOffsetWide", c_void_p),223 ("GetOffsetByNameWide", c_void_p),224 ("GetNearNameByOffsetWide", c_void_p),225 ("GetLineByOffsetWide", c_void_p),226 ("GetOffsetByLineWide", c_void_p),227 ("GetModuleByModuleNameWide", c_void_p),228 ("GetSymbolModuleWide", c_void_p),229 ("GetTypeNameWide", c_void_p),230 ("GetTypeIdWide", c_void_p),231 ("GetFieldOffsetWide", c_void_p),232 ("GetSymbolTypeIdWide", c_void_p),233 ("GetScopeSymbolGroup2", ids_getscopesymbolgroup2),234 ("CreateSymbolGroup2", c_void_p),235 ("StartSymbolMatchWide", c_void_p),236 ("GetNextSymbolMatchWide", c_void_p),237 ("ReloadWide", c_void_p),238 ("GetSymbolPathWide", c_void_p),239 ("SetSymbolPathWide", c_void_p),240 ("AppendSymbolPathWide", c_void_p),241 ("GetImagePathWide", c_void_p),242 ("SetImagePathWide", c_void_p),243 ("AppendImagePathWide", c_void_p),244 ("GetSourcePathWide", c_void_p),245 ("GetSourcePathElementWide", c_void_p),246 ("SetSourcePathWide", c_void_p),247 ("AppendSourcePathWide", c_void_p),248 ("FindSourceFileWide", c_void_p),249 ("GetSourceFileLineOffsetsWide", c_void_p),250 ("GetModuleVersionInformationWide", c_void_p),251 ("GetModuleNameStringWide", c_void_p),252 ("GetConstantNameWide", c_void_p),253 ("GetFieldNameWide", c_void_p),254 ("IsManagedModule", c_void_p),255 ("GetModuleByModuleName2", c_void_p),256 ("GetModuleByModuleName2Wide", c_void_p),257 ("GetModuleByOffset2", c_void_p),258 ("AddSyntheticModule", c_void_p),259 ("AddSyntheticModuleWide", c_void_p),260 ("RemoveSyntheticModule", c_void_p),261 ("GetCurrentScopeFrameIndex", ids_getcurrentscopeframeindex),262 ("SetScopeFrameByIndex", ids_setscopeframebyindex),263 ("SetScopeFromJitDebugInfo", c_void_p),264 ("SetScopeFromStoredEvent", c_void_p),265 ("OutputSymbolByOffset", c_void_p),266 ("GetFunctionEntryByOffset", c_void_p),267 ("GetFieldTypeAndOffset", c_void_p),268 ("GetFieldTypeAndOffsetWide", c_void_p),269 ("AddSyntheticSymbol", c_void_p),270 ("AddSyntheticSymbolWide", c_void_p),271 ("RemoveSyntheticSymbol", c_void_p),272 ("GetSymbolEntriesByOffset", c_void_p),273 ("GetSymbolEntriesByName", ids_getsymbolentriesbyname),274 ("GetSymbolEntriesByNameWide", c_void_p),275 ("GetSymbolEntryByToken", c_void_p),276 ("GetSymbolEntryInformation", ids_getsymbolentryinformation),277 ("GetSymbolEntryString", ids_getsymbolentrystring),278 ("GetSymbolEntryStringWide", c_void_p),279 ("GetSymbolEntryOffsetRegions", c_void_p),280 ("GetSymbolEntryBySymbolEntry", c_void_p),281 ("GetSourceEntriesByOffset", c_void_p),282 ("GetSourceEntriesByLine", c_void_p),283 ("GetSourceEntriesByLineWide", c_void_p),284 ("GetSourceEntryString", c_void_p),285 ("GetSourceEntryStringWide", c_void_p),286 ("GetSourceEntryOffsetRegions", c_void_p),287 ("GetsourceEntryBySourceEntry", c_void_p),288 ("GetScopeEx", c_void_p),289 ("SetScopeEx", c_void_p),290 ("GetNameByInlineContext", ids_getnamebyinlinecontext),291 ("GetNameByInlineContextWide", c_void_p),292 ("GetLineByInlineContext", ids_getlinebyinlinecontext),293 ("GetLineByInlineContextWide", c_void_p),294 ("OutputSymbolByInlineContext", c_void_p),295 ("GetCurrentScopeFrameIndexEx", c_void_p),296 ("SetScopeFrameByIndexEx", c_void_p),297 ]298 299 300IDebugSymbols5._fields_ = [("lpVtbl", POINTER(IDebugSymbols5Vtbl))]301 302SymbolId = namedtuple("SymbolId", ["ModuleBase", "Id"])303SymbolEntry = namedtuple(304 "SymbolEntry",305 [306 "ModuleBase",307 "Offset",308 "Id",309 "Arg64",310 "Size",311 "Flags",312 "TypeId",313 "NameSize",314 "Token",315 "Tag",316 "Arg32",317 ],318)319DebugModuleParams = namedtuple(320 "DebugModuleParams",321 [322 "Base",323 "Size",324 "TimeDateStamp",325 "Checksum",326 "Flags",327 "SymbolType",328 "ImageNameSize",329 "ModuleNameSize",330 "LoadedImageNameSize",331 "SymbolFileNameSize",332 "MappedImageNameSize",333 ],334)335 336 337class SymTags(IntEnum):338 Null = 0339 Exe = 1340 SymTagFunction = 5341 342 343def make_debug_module_params(cdata):344 fieldvalues = map(lambda y: getattr(cdata, y), DebugModuleParams._fields)345 return DebugModuleParams(*fieldvalues)346 347 348class Symbols(object):349 def __init__(self, symbols):350 self.ptr = symbols351 self.symbols = symbols.contents352 self.vt = self.symbols.lpVtbl.contents353 # Keep some handy ulongs for passing into C methods.354 self.ulong = c_ulong()355 self.ulong64 = c_ulonglong()356 357 def GetCurrentScopeFrameIndex(self):358 res = self.vt.GetCurrentScopeFrameIndex(self.symbols, byref(self.ulong))359 aborter(res, "GetCurrentScopeFrameIndex")360 return self.ulong.value361 362 def SetScopeFrameByIndex(self, idx):363 res = self.vt.SetScopeFrameByIndex(self.symbols, idx)364 aborter(res, "SetScopeFrameByIndex", ignore=[E_EINVAL])365 return res != E_EINVAL366 367 def GetOffsetByName(self, name):368 res = self.vt.GetOffsetByName(369 self.symbols, name.encode("ascii"), byref(self.ulong64)370 )371 aborter(res, "GetOffsetByName {}".format(name))372 return self.ulong64.value373 374 def GetNearNameByOffset(self, addr):375 ptr = create_string_buffer(256)376 pulong = c_ulong()377 disp = c_ulonglong()378 # Zero arg -> "delta" indicating how many symbols to skip379 res = self.vt.GetNearNameByOffset(380 self.symbols, addr, 0, ptr, 255, byref(pulong), byref(disp)381 )382 if res == E_NOINTERFACE:383 return "{noname}"384 aborter(res, "GetNearNameByOffset")385 ptr[255] = "\0".encode("ascii")386 return "{}+{}".format(string_at(ptr).decode("ascii"), disp.value)387 388 def GetModuleByModuleName2(self, name):389 # First zero arg -> module index to search from, second zero arg ->390 # DEBUG_GETMOD_* flags, none of which we use.391 res = self.vt.GetModuleByModuleName2(392 self.symbols, name, 0, 0, None, byref(self.ulong64)393 )394 aborter(res, "GetModuleByModuleName2")395 return self.ulong64.value396 397 def GetScopeSymbolGroup2(self):398 retptr = POINTER(IDebugSymbolGroup2)()399 res = self.vt.GetScopeSymbolGroup2(400 self.symbols, ScopeGroupFlags.DEBUG_SCOPE_GROUP_ALL, None, retptr401 )402 aborter(res, "GetScopeSymbolGroup2")403 return SymbolGroup(retptr)404 405 def GetSymbolEntryString(self, idx, module):406 symid = DEBUG_MODULE_AND_ID()407 symid.ModuleBase = module408 symid.Id = idx409 ptr = create_string_buffer(1024)410 # Zero arg is the string index -- symbols can have multiple names, for now411 # only support the first one.412 res = self.vt.GetSymbolEntryString(413 self.symbols, symid, 0, ptr, 1023, byref(self.ulong)414 )415 aborter(res, "GetSymbolEntryString")416 return string_at(ptr).decode("ascii")417 418 def GetSymbolEntryInformation(self, module, theid):419 symid = DEBUG_MODULE_AND_ID()420 symentry = DEBUG_SYMBOL_ENTRY()421 symid.ModuleBase = module422 symid.Id = theid423 res = self.vt.GetSymbolEntryInformation(self.symbols, symid, symentry)424 aborter(res, "GetSymbolEntryInformation")425 # Fetch fields into SymbolEntry object426 fields = map(lambda x: getattr(symentry, x), SymbolEntry._fields)427 return SymbolEntry(*fields)428 429 def GetSymbolEntriesByName(self, symstr):430 # Initial query to find number of symbol entries431 res = self.vt.GetSymbolEntriesByName(432 self.symbols, symstr.encode("ascii"), 0, None, 0, byref(self.ulong)433 )434 aborter(res, "GetSymbolEntriesByName")435 436 # Build a buffer and query for 'length' entries437 length = self.ulong.value438 symrecs = (DEBUG_MODULE_AND_ID * length)()439 # Zero arg -> flags, of which there are none defined.440 res = self.vt.GetSymbolEntriesByName(441 self.symbols, symstr.encode("ascii"), 0, symrecs, length, byref(self.ulong)442 )443 aborter(res, "GetSymbolEntriesByName")444 445 # Extract 'length' number of SymbolIds446 length = self.ulong.value447 448 def extract(x):449 sym = symrecs[x]450 return SymbolId(sym.ModuleBase, sym.Id)451 452 return [extract(x) for x in range(length)]453 454 def GetSymbolPath(self):455 # Query for length of buffer to allocate456 res = self.vt.GetSymbolPath(self.symbols, None, 0, byref(self.ulong))457 aborter(res, "GetSymbolPath", ignore=[S_FALSE])458 459 # Fetch 'length' length symbol path string460 length = self.ulong.value461 arr = create_string_buffer(length)462 res = self.vt.GetSymbolPath(self.symbols, arr, length, byref(self.ulong))463 aborter(res, "GetSymbolPath")464 465 return string_at(arr).decode("ascii")466 467 def GetSourcePath(self):468 # Query for length of buffer to allocate469 res = self.vt.GetSourcePath(self.symbols, None, 0, byref(self.ulong))470 aborter(res, "GetSourcePath", ignore=[S_FALSE])471 472 # Fetch a string of len 'length'473 length = self.ulong.value474 arr = create_string_buffer(length)475 res = self.vt.GetSourcePath(self.symbols, arr, length, byref(self.ulong))476 aborter(res, "GetSourcePath")477 478 return string_at(arr).decode("ascii")479 480 def SetSourcePath(self, string):481 res = self.vt.SetSourcePath(self.symbols, string.encode("ascii"))482 aborter(res, "SetSourcePath")483 return484 485 def GetModuleParameters(self, base):486 self.ulong64.value = base487 params = DEBUG_MODULE_PARAMETERS()488 # Fetch one module params struct, starting at idx zero489 res = self.vt.GetModuleParameters(490 self.symbols, 1, byref(self.ulong64), 0, byref(params)491 )492 aborter(res, "GetModuleParameters")493 return make_debug_module_params(params)494 495 def GetSymbolOptions(self):496 res = self.vt.GetSymbolOptions(self.symbols, byref(self.ulong))497 aborter(res, "GetSymbolOptions")498 return SymbolOptionFlags(self.ulong.value)499 500 def SetSymbolOptions(self, opts):501 assert isinstance(opts, SymbolOptionFlags)502 res = self.vt.SetSymbolOptions(self.symbols, opts.value)503 aborter(res, "SetSymbolOptions")504 return505 506 def GetLineByOffset(self, offs):507 # Initial query for filename buffer size508 res = self.vt.GetLineByOffset(509 self.symbols, offs, None, None, 0, byref(self.ulong), None510 )511 if res == E_FAIL:512 return None # Sometimes we just can't get line numbers, of course513 aborter(res, "GetLineByOffset", ignore=[S_FALSE])514 515 # Allocate filename buffer and query for line number too516 filenamelen = self.ulong.value517 text = create_string_buffer(filenamelen)518 line = c_ulong()519 res = self.vt.GetLineByOffset(520 self.symbols, offs, byref(line), text, filenamelen, byref(self.ulong), None521 )522 aborter(res, "GetLineByOffset")523 524 return string_at(text).decode("ascii"), line.value525 526 def GetModuleNameString(self, whichname, base):527 # Initial query for name string length528 res = self.vt.GetModuleNameString(529 self.symbols, whichname, DEBUG_ANY_ID, base, None, 0, byref(self.ulong)530 )531 aborter(res, "GetModuleNameString", ignore=[S_FALSE])532 533 module_name_len = self.ulong.value534 module_name = (c_char * module_name_len)()535 res = self.vt.GetModuleNameString(536 self.symbols,537 whichname,538 DEBUG_ANY_ID,539 base,540 module_name,541 module_name_len,542 None,543 )544 aborter(res, "GetModuleNameString")545 546 return string_at(module_name).decode("ascii")547 548 def GetNameByInlineContext(self, pc, ctx):549 # None args -> ignore output name size and displacement550 buf = create_string_buffer(256)551 res = self.vt.GetNameByInlineContext(552 self.symbols, pc, ctx, buf, 255, None, None553 )554 aborter(res, "GetNameByInlineContext")555 return string_at(buf).decode("ascii")556 557 def GetLineByInlineContext(self, pc, ctx):558 # None args -> ignore output filename size and displacement559 buf = create_string_buffer(256)560 res = self.vt.GetLineByInlineContext(561 self.symbols, pc, ctx, byref(self.ulong), buf, 255, None, None562 )563 aborter(res, "GetLineByInlineContext")564 return string_at(buf).decode("ascii"), self.ulong.value565 566 def get_all_symbols(self):567 main_module_name = self.get_exefile_module_name()568 idnumbers = self.GetSymbolEntriesByName("{}!*".format(main_module_name))569 lst = []570 for symid in idnumbers:571 s = self.GetSymbolEntryString(symid.Id, symid.ModuleBase)572 symentry = self.GetSymbolEntryInformation(symid.ModuleBase, symid.Id)573 lst.append((s, symentry))574 return lst575 576 def get_all_functions(self):577 syms = self.get_all_symbols()578 return [x for x in syms if x[1].Tag == SymTags.SymTagFunction]579 580 def get_all_modules(self):581 params = DEBUG_MODULE_PARAMETERS()582 idx = 0583 res = 0584 all_modules = []585 while res != E_EINVAL:586 res = self.vt.GetModuleParameters(self.symbols, 1, None, idx, byref(params))587 aborter(res, "GetModuleParameters", ignore=[E_EINVAL])588 all_modules.append(make_debug_module_params(params))589 idx += 1590 return all_modules591 592 def get_exefile_module(self):593 all_modules = self.get_all_modules()594 reduce_func = (595 lambda x, y: y if y.Flags & DebugModuleFlags.DEBUG_MODULE_EXE_MODULE else x596 )597 main_module = reduce(reduce_func, all_modules, None)598 if main_module is None:599 raise Exception("Couldn't find the exefile module")600 return main_module601 602 def get_module_name(self, base):603 return self.GetModuleNameString(DebugModuleNames.DEBUG_MODNAME_MODULE, base)604 605 def get_exefile_module_name(self):606 return self.get_module_name(self.get_exefile_module().Base)607