diff options
Diffstat (limited to 'debuginfo-tests/dexter/dex/debugger/dbgeng/symbols.py')
-rw-r--r-- | debuginfo-tests/dexter/dex/debugger/dbgeng/symbols.py | 499 |
1 files changed, 499 insertions, 0 deletions
diff --git a/debuginfo-tests/dexter/dex/debugger/dbgeng/symbols.py b/debuginfo-tests/dexter/dex/debugger/dbgeng/symbols.py new file mode 100644 index 00000000000..bc998facb4e --- /dev/null +++ b/debuginfo-tests/dexter/dex/debugger/dbgeng/symbols.py @@ -0,0 +1,499 @@ +# DExTer : Debugging Experience Tester +# ~~~~~~ ~ ~~ ~ ~~ +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +from collections import namedtuple +from ctypes import * +from enum import * +from functools import reduce, partial + +from .symgroup import SymbolGroup, IDebugSymbolGroup2 +from .utils import * + +class SymbolOptionFlags(IntFlag): + SYMOPT_CASE_INSENSITIVE = 0x00000001 + SYMOPT_UNDNAME = 0x00000002 + SYMOPT_DEFERRED_LOADS = 0x00000004 + SYMOPT_NO_CPP = 0x00000008 + SYMOPT_LOAD_LINES = 0x00000010 + SYMOPT_OMAP_FIND_NEAREST = 0x00000020 + SYMOPT_LOAD_ANYTHING = 0x00000040 + SYMOPT_IGNORE_CVREC = 0x00000080 + SYMOPT_NO_UNQUALIFIED_LOADS = 0x00000100 + SYMOPT_FAIL_CRITICAL_ERRORS = 0x00000200 + SYMOPT_EXACT_SYMBOLS = 0x00000400 + SYMOPT_ALLOW_ABSOLUTE_SYMBOLS = 0x00000800 + SYMOPT_IGNORE_NT_SYMPATH = 0x00001000 + SYMOPT_INCLUDE_32BIT_MODULES = 0x00002000 + SYMOPT_PUBLICS_ONLY = 0x00004000 + SYMOPT_NO_PUBLICS = 0x00008000 + SYMOPT_AUTO_PUBLICS = 0x00010000 + SYMOPT_NO_IMAGE_SEARCH = 0x00020000 + SYMOPT_SECURE = 0x00040000 + SYMOPT_NO_PROMPTS = 0x00080000 + SYMOPT_DEBUG = 0x80000000 + +class ScopeGroupFlags(IntFlag): + DEBUG_SCOPE_GROUP_ARGUMENTS = 0x00000001 + DEBUG_SCOPE_GROUP_LOCALS = 0x00000002 + DEBUG_SCOPE_GROUP_ALL = 0x00000003 + DEBUG_SCOPE_GROUP_BY_DATAMODEL = 0x00000004 + +class DebugModuleNames(IntEnum): + DEBUG_MODNAME_IMAGE = 0x00000000 + DEBUG_MODNAME_MODULE = 0x00000001 + DEBUG_MODNAME_LOADED_IMAGE = 0x00000002 + DEBUG_MODNAME_SYMBOL_FILE = 0x00000003 + DEBUG_MODNAME_MAPPED_IMAGE = 0x00000004 + +class DebugModuleFlags(IntFlag): + DEBUG_MODULE_LOADED = 0x00000000 + DEBUG_MODULE_UNLOADED = 0x00000001 + DEBUG_MODULE_USER_MODE = 0x00000002 + DEBUG_MODULE_EXE_MODULE = 0x00000004 + DEBUG_MODULE_EXPLICIT = 0x00000008 + DEBUG_MODULE_SECONDARY = 0x00000010 + DEBUG_MODULE_SYNTHETIC = 0x00000020 + DEBUG_MODULE_SYM_BAD_CHECKSUM = 0x00010000 + +class DEBUG_MODULE_PARAMETERS(Structure): + _fields_ = [ + ("Base", c_ulonglong), + ("Size", c_ulong), + ("TimeDateStamp", c_ulong), + ("Checksum", c_ulong), + ("Flags", c_ulong), + ("SymbolType", c_ulong), + ("ImageNameSize", c_ulong), + ("ModuleNameSize", c_ulong), + ("LoadedImageNameSize", c_ulong), + ("SymbolFileNameSize", c_ulong), + ("MappedImageNameSize", c_ulong), + ("Reserved", c_ulonglong * 2) + ] +PDEBUG_MODULE_PARAMETERS = POINTER(DEBUG_MODULE_PARAMETERS) + +class DEBUG_MODULE_AND_ID(Structure): + _fields_ = [ + ("ModuleBase", c_ulonglong), + ("Id", c_ulonglong) + ] +PDEBUG_MODULE_AND_ID = POINTER(DEBUG_MODULE_AND_ID) + +class DEBUG_SYMBOL_ENTRY(Structure): + _fields_ = [ + ("ModuleBase", c_ulonglong), + ("Offset", c_ulonglong), + ("Id", c_ulonglong), + ("Arg64", c_ulonglong), + ("Size", c_ulong), + ("Flags", c_ulong), + ("TypeId", c_ulong), + ("NameSize", c_ulong), + ("Token", c_ulong), + ("Tag", c_ulong), + ("Arg32", c_ulong), + ("Reserved", c_ulong) + ] +PDEBUG_SYMBOL_ENTRY = POINTER(DEBUG_SYMBOL_ENTRY) + +# UUID for DebugSymbols5 interface. +DebugSymbols5IID = IID(0xc65fa83e, 0x1e69, 0x475e, IID_Data4_Type(0x8e, 0x0e, 0xb5, 0xd7, 0x9e, 0x9c, 0xc1, 0x7e)) + +class IDebugSymbols5(Structure): + pass + +class IDebugSymbols5Vtbl(Structure): + wrp = partial(WINFUNCTYPE, c_long, POINTER(IDebugSymbols5)) + ids_getsymboloptions = wrp(c_ulong_p) + ids_setsymboloptions = wrp(c_ulong) + ids_getmoduleparameters = wrp(c_ulong, c_ulong64_p, c_ulong, PDEBUG_MODULE_PARAMETERS) + ids_getmodulenamestring = wrp(c_ulong, c_ulong, c_ulonglong, c_char_p, c_ulong, c_ulong_p) + ids_getoffsetbyname = wrp(c_char_p, c_ulong64_p) + ids_getlinebyoffset = wrp(c_ulonglong, c_ulong_p, c_char_p, c_ulong, c_ulong_p, c_ulong64_p) + ids_getsymbolentriesbyname = wrp(c_char_p, c_ulong, PDEBUG_MODULE_AND_ID, c_ulong, c_ulong_p) + ids_getsymbolentrystring = wrp(PDEBUG_MODULE_AND_ID, c_ulong, c_char_p, c_ulong, c_ulong_p) + ids_getsymbolentryinformation = wrp(PDEBUG_MODULE_AND_ID, PDEBUG_SYMBOL_ENTRY) + ids_getcurrentscopeframeindex = wrp(c_ulong_p) + ids_getnearnamebyoffset = wrp(c_ulonglong, c_long, c_char_p, c_ulong, c_ulong_p, c_ulong64_p) + ids_setscopeframebyindex = wrp(c_ulong) + ids_getscopesymbolgroup2 = wrp(c_ulong, POINTER(IDebugSymbolGroup2), POINTER(POINTER(IDebugSymbolGroup2))) + ids_getnamebyinlinecontext = wrp(c_ulonglong, c_ulong, c_char_p, c_ulong, c_ulong_p, c_ulong64_p) + ids_getlinebyinlinecontext = wrp(c_ulonglong, c_ulong, c_ulong_p, c_char_p, c_ulong, c_ulong_p, c_ulong64_p) + _fields_ = [ + ("QueryInterface", c_void_p), + ("AddRef", c_void_p), + ("Release", c_void_p), + ("GetSymbolOptions", ids_getsymboloptions), + ("AddSymbolOptions", c_void_p), + ("RemoveSymbolOptions", c_void_p), + ("SetSymbolOptions", ids_setsymboloptions), + ("GetNameByOffset", c_void_p), + ("GetOffsetByName", ids_getoffsetbyname), + ("GetNearNameByOffset", ids_getnearnamebyoffset), + ("GetLineByOffset", ids_getlinebyoffset), + ("GetOffsetByLine", c_void_p), + ("GetNumberModules", c_void_p), + ("GetModuleByIndex", c_void_p), + ("GetModuleByModuleName", c_void_p), + ("GetModuleByOffset", c_void_p), + ("GetModuleNames", c_void_p), + ("GetModuleParameters", ids_getmoduleparameters), + ("GetSymbolModule", c_void_p), + ("GetTypeName", c_void_p), + ("GetTypeId", c_void_p), + ("GetTypeSize", c_void_p), + ("GetFieldOffset", c_void_p), + ("GetSymbolTypeId", c_void_p), + ("GetOffsetTypeId", c_void_p), + ("ReadTypedDataVirtual", c_void_p), + ("WriteTypedDataVirtual", c_void_p), + ("OutputTypedDataVirtual", c_void_p), + ("ReadTypedDataPhysical", c_void_p), + ("WriteTypedDataPhysical", c_void_p), + ("OutputTypedDataPhysical", c_void_p), + ("GetScope", c_void_p), + ("SetScope", c_void_p), + ("ResetScope", c_void_p), + ("GetScopeSymbolGroup", c_void_p), + ("CreateSymbolGroup", c_void_p), + ("StartSymbolMatch", c_void_p), + ("GetNextSymbolMatch", c_void_p), + ("EndSymbolMatch", c_void_p), + ("Reload", c_void_p), + ("GetSymbolPath", c_void_p), + ("SetSymbolPath", c_void_p), + ("AppendSymbolPath", c_void_p), + ("GetImagePath", c_void_p), + ("SetImagePath", c_void_p), + ("AppendImagePath", c_void_p), + ("GetSourcePath", c_void_p), + ("GetSourcePathElement", c_void_p), + ("SetSourcePath", c_void_p), + ("AppendSourcePath", c_void_p), + ("FindSourceFile", c_void_p), + ("GetSourceFileLineOffsets", c_void_p), + ("GetModuleVersionInformation", c_void_p), + ("GetModuleNameString", ids_getmodulenamestring), + ("GetConstantName", c_void_p), + ("GetFieldName", c_void_p), + ("GetTypeOptions", c_void_p), + ("AddTypeOptions", c_void_p), + ("RemoveTypeOptions", c_void_p), + ("SetTypeOptions", c_void_p), + ("GetNameByOffsetWide", c_void_p), + ("GetOffsetByNameWide", c_void_p), + ("GetNearNameByOffsetWide", c_void_p), + ("GetLineByOffsetWide", c_void_p), + ("GetOffsetByLineWide", c_void_p), + ("GetModuleByModuleNameWide", c_void_p), + ("GetSymbolModuleWide", c_void_p), + ("GetTypeNameWide", c_void_p), + ("GetTypeIdWide", c_void_p), + ("GetFieldOffsetWide", c_void_p), + ("GetSymbolTypeIdWide", c_void_p), + ("GetScopeSymbolGroup2", ids_getscopesymbolgroup2), + ("CreateSymbolGroup2", c_void_p), + ("StartSymbolMatchWide", c_void_p), + ("GetNextSymbolMatchWide", c_void_p), + ("ReloadWide", c_void_p), + ("GetSymbolPathWide", c_void_p), + ("SetSymbolPathWide", c_void_p), + ("AppendSymbolPathWide", c_void_p), + ("GetImagePathWide", c_void_p), + ("SetImagePathWide", c_void_p), + ("AppendImagePathWide", c_void_p), + ("GetSourcePathWide", c_void_p), + ("GetSourcePathElementWide", c_void_p), + ("SetSourcePathWide", c_void_p), + ("AppendSourcePathWide", c_void_p), + ("FindSourceFileWide", c_void_p), + ("GetSourceFileLineOffsetsWide", c_void_p), + ("GetModuleVersionInformationWide", c_void_p), + ("GetModuleNameStringWide", c_void_p), + ("GetConstantNameWide", c_void_p), + ("GetFieldNameWide", c_void_p), + ("IsManagedModule", c_void_p), + ("GetModuleByModuleName2", c_void_p), + ("GetModuleByModuleName2Wide", c_void_p), + ("GetModuleByOffset2", c_void_p), + ("AddSyntheticModule", c_void_p), + ("AddSyntheticModuleWide", c_void_p), + ("RemoveSyntheticModule", c_void_p), + ("GetCurrentScopeFrameIndex", ids_getcurrentscopeframeindex), + ("SetScopeFrameByIndex", ids_setscopeframebyindex), + ("SetScopeFromJitDebugInfo", c_void_p), + ("SetScopeFromStoredEvent", c_void_p), + ("OutputSymbolByOffset", c_void_p), + ("GetFunctionEntryByOffset", c_void_p), + ("GetFieldTypeAndOffset", c_void_p), + ("GetFieldTypeAndOffsetWide", c_void_p), + ("AddSyntheticSymbol", c_void_p), + ("AddSyntheticSymbolWide", c_void_p), + ("RemoveSyntheticSymbol", c_void_p), + ("GetSymbolEntriesByOffset", c_void_p), + ("GetSymbolEntriesByName", ids_getsymbolentriesbyname), + ("GetSymbolEntriesByNameWide", c_void_p), + ("GetSymbolEntryByToken", c_void_p), + ("GetSymbolEntryInformation", ids_getsymbolentryinformation), + ("GetSymbolEntryString", ids_getsymbolentrystring), + ("GetSymbolEntryStringWide", c_void_p), + ("GetSymbolEntryOffsetRegions", c_void_p), + ("GetSymbolEntryBySymbolEntry", c_void_p), + ("GetSourceEntriesByOffset", c_void_p), + ("GetSourceEntriesByLine", c_void_p), + ("GetSourceEntriesByLineWide", c_void_p), + ("GetSourceEntryString", c_void_p), + ("GetSourceEntryStringWide", c_void_p), + ("GetSourceEntryOffsetRegions", c_void_p), + ("GetsourceEntryBySourceEntry", c_void_p), + ("GetScopeEx", c_void_p), + ("SetScopeEx", c_void_p), + ("GetNameByInlineContext", ids_getnamebyinlinecontext), + ("GetNameByInlineContextWide", c_void_p), + ("GetLineByInlineContext", ids_getlinebyinlinecontext), + ("GetLineByInlineContextWide", c_void_p), + ("OutputSymbolByInlineContext", c_void_p), + ("GetCurrentScopeFrameIndexEx", c_void_p), + ("SetScopeFrameByIndexEx", c_void_p) + ] + +IDebugSymbols5._fields_ = [("lpVtbl", POINTER(IDebugSymbols5Vtbl))] + +SymbolId = namedtuple("SymbolId", ["ModuleBase", "Id"]) +SymbolEntry = namedtuple("SymbolEntry", ["ModuleBase", "Offset", "Id", "Arg64", "Size", "Flags", "TypeId", "NameSize", "Token", "Tag", "Arg32"]) +DebugModuleParams = namedtuple("DebugModuleParams", ["Base", "Size", "TimeDateStamp", "Checksum", "Flags", "SymbolType", "ImageNameSize", "ModuleNameSize", "LoadedImageNameSize", "SymbolFileNameSize", "MappedImageNameSize"]) + +class SymTags(IntEnum): + Null = 0 + Exe = 1 + SymTagFunction = 5 + +def make_debug_module_params(cdata): + fieldvalues = map(lambda y: getattr(cdata, y), DebugModuleParams._fields) + return DebugModuleParams(*fieldvalues) + +class Symbols(object): + def __init__(self, symbols): + self.ptr = symbols + self.symbols = symbols.contents + self.vt = self.symbols.lpVtbl.contents + # Keep some handy ulongs for passing into C methods. + self.ulong = c_ulong() + self.ulong64 = c_ulonglong() + + def GetCurrentScopeFrameIndex(self): + res = self.vt.GetCurrentScopeFrameIndex(self.symbols, byref(self.ulong)) + aborter(res, "GetCurrentScopeFrameIndex") + return self.ulong.value + + def SetScopeFrameByIndex(self, idx): + res = self.vt.SetScopeFrameByIndex(self.symbols, idx) + aborter(res, "SetScopeFrameByIndex", ignore=[E_EINVAL]) + return res != E_EINVAL + + def GetOffsetByName(self, name): + res = self.vt.GetOffsetByName(self.symbols, name.encode("ascii"), byref(self.ulong64)) + aborter(res, "GetOffsetByName {}".format(name)) + return self.ulong64.value + + def GetNearNameByOffset(self, addr): + ptr = create_string_buffer(256) + pulong = c_ulong() + disp = c_ulonglong() + # Zero arg -> "delta" indicating how many symbols to skip + res = self.vt.GetNearNameByOffset(self.symbols, addr, 0, ptr, 255, byref(pulong), byref(disp)) + if res == E_NOINTERFACE: + return "{noname}" + aborter(res, "GetNearNameByOffset") + ptr[255] = '\0'.encode("ascii") + return '{}+{}'.format(string_at(ptr).decode("ascii"), disp.value) + + def GetModuleByModuleName2(self, name): + # First zero arg -> module index to search from, second zero arg -> + # DEBUG_GETMOD_* flags, none of which we use. + res = self.vt.GetModuleByModuleName2(self.symbols, name, 0, 0, None, byref(self.ulong64)) + aborter(res, "GetModuleByModuleName2") + return self.ulong64.value + + def GetScopeSymbolGroup2(self): + retptr = POINTER(IDebugSymbolGroup2)() + res = self.vt.GetScopeSymbolGroup2(self.symbols, ScopeGroupFlags.DEBUG_SCOPE_GROUP_ALL, None, retptr) + aborter(res, "GetScopeSymbolGroup2") + return SymbolGroup(retptr) + + def GetSymbolEntryString(self, idx, module): + symid = DEBUG_MODULE_AND_ID() + symid.ModuleBase = module + symid.Id = idx + ptr = create_string_buffer(1024) + # Zero arg is the string index -- symbols can have multiple names, for now + # only support the first one. + res = self.vt.GetSymbolEntryString(self.symbols, symid, 0, ptr, 1023, byref(self.ulong)) + aborter(res, "GetSymbolEntryString") + return string_at(ptr).decode("ascii") + + def GetSymbolEntryInformation(self, module, theid): + symid = DEBUG_MODULE_AND_ID() + symentry = DEBUG_SYMBOL_ENTRY() + symid.ModuleBase = module + symid.Id = theid + res = self.vt.GetSymbolEntryInformation(self.symbols, symid, symentry) + aborter(res, "GetSymbolEntryInformation") + # Fetch fields into SymbolEntry object + fields = map(lambda x: getattr(symentry, x), SymbolEntry._fields) + return SymbolEntry(*fields) + + def GetSymbolEntriesByName(self, symstr): + # Initial query to find number of symbol entries + res = self.vt.GetSymbolEntriesByName(self.symbols, symstr.encode("ascii"), 0, None, 0, byref(self.ulong)) + aborter(res, "GetSymbolEntriesByName") + + # Build a buffer and query for 'length' entries + length = self.ulong.value + symrecs = (DEBUG_MODULE_AND_ID * length)() + # Zero arg -> flags, of which there are none defined. + res = self.vt.GetSymbolEntriesByName(self.symbols, symstr.encode("ascii"), 0, symrecs, length, byref(self.ulong)) + aborter(res, "GetSymbolEntriesByName") + + # Extract 'length' number of SymbolIds + length = self.ulong.value + def extract(x): + sym = symrecs[x] + return SymbolId(sym.ModuleBase, sym.Id) + return [extract(x) for x in range(length)] + + def GetSymbolPath(self): + # Query for length of buffer to allocate + res = self.vt.GetSymbolPath(self.symbols, None, 0, byref(self.ulong)) + aborter(res, "GetSymbolPath", ignore=[S_FALSE]) + + # Fetch 'length' length symbol path string + length = self.ulong.value + arr = create_string_buffer(length) + res = self.vt.GetSymbolPath(self.symbols, arr, length, byref(self.ulong)) + aborter(res, "GetSymbolPath") + + return string_at(arr).decode("ascii") + + def GetSourcePath(self): + # Query for length of buffer to allocate + res = self.vt.GetSourcePath(self.symbols, None, 0, byref(self.ulong)) + aborter(res, "GetSourcePath", ignore=[S_FALSE]) + + # Fetch a string of len 'length' + length = self.ulong.value + arr = create_string_buffer(length) + res = self.vt.GetSourcePath(self.symbols, arr, length, byref(self.ulong)) + aborter(res, "GetSourcePath") + + return string_at(arr).decode("ascii") + + def SetSourcePath(self, string): + res = self.vt.SetSourcePath(self.symbols, string.encode("ascii")) + aborter(res, "SetSourcePath") + return + + def GetModuleParameters(self, base): + self.ulong64.value = base + params = DEBUG_MODULE_PARAMETERS() + # Fetch one module params struct, starting at idx zero + res = self.vt.GetModuleParameters(self.symbols, 1, byref(self.ulong64), 0, byref(params)) + aborter(res, "GetModuleParameters") + return make_debug_module_params(params) + + def GetSymbolOptions(self): + res = self.vt.GetSymbolOptions(self.symbols, byref(self.ulong)) + aborter(res, "GetSymbolOptions") + return SymbolOptionFlags(self.ulong.value) + + def SetSymbolOptions(self, opts): + assert isinstance(opts, SymbolOptionFlags) + res = self.vt.SetSymbolOptions(self.symbols, opts.value) + aborter(res, "SetSymbolOptions") + return + + def GetLineByOffset(self, offs): + # Initial query for filename buffer size + res = self.vt.GetLineByOffset(self.symbols, offs, None, None, 0, byref(self.ulong), None) + if res == E_FAIL: + return None # Sometimes we just can't get line numbers, of course + aborter(res, "GetLineByOffset", ignore=[S_FALSE]) + + # Allocate filename buffer and query for line number too + filenamelen = self.ulong.value + text = create_string_buffer(filenamelen) + line = c_ulong() + res = self.vt.GetLineByOffset(self.symbols, offs, byref(line), text, filenamelen, byref(self.ulong), None) + aborter(res, "GetLineByOffset") + + return string_at(text).decode("ascii"), line.value + + def GetModuleNameString(self, whichname, base): + # Initial query for name string length + res = self.vt.GetModuleNameString(self.symbols, whichname, DEBUG_ANY_ID, base, None, 0, byref(self.ulong)) + aborter(res, "GetModuleNameString", ignore=[S_FALSE]) + + module_name_len = self.ulong.value + module_name = (c_char * module_name_len)() + res = self.vt.GetModuleNameString(self.symbols, whichname, DEBUG_ANY_ID, base, module_name, module_name_len, None) + aborter(res, "GetModuleNameString") + + return string_at(module_name).decode("ascii") + + def GetNameByInlineContext(self, pc, ctx): + # None args -> ignore output name size and displacement + buf = create_string_buffer(256) + res = self.vt.GetNameByInlineContext(self.symbols, pc, ctx, buf, 255, None, None) + aborter(res, "GetNameByInlineContext") + return string_at(buf).decode("ascii") + + def GetLineByInlineContext(self, pc, ctx): + # None args -> ignore output filename size and displacement + buf = create_string_buffer(256) + res = self.vt.GetLineByInlineContext(self.symbols, pc, ctx, byref(self.ulong), buf, 255, None, None) + aborter(res, "GetLineByInlineContext") + return string_at(buf).decode("ascii"), self.ulong.value + + def get_all_symbols(self): + main_module_name = self.get_exefile_module_name() + idnumbers = self.GetSymbolEntriesByName("{}!*".format(main_module_name)) + lst = [] + for symid in idnumbers: + s = self.GetSymbolEntryString(symid.Id, symid.ModuleBase) + symentry = self.GetSymbolEntryInformation(symid.ModuleBase, symid.Id) + lst.append((s, symentry)) + return lst + + def get_all_functions(self): + syms = self.get_all_symbols() + return [x for x in syms if x[1].Tag == SymTags.SymTagFunction] + + def get_all_modules(self): + params = DEBUG_MODULE_PARAMETERS() + idx = 0 + res = 0 + all_modules = [] + while res != E_EINVAL: + res = self.vt.GetModuleParameters(self.symbols, 1, None, idx, byref(params)) + aborter(res, "GetModuleParameters", ignore=[E_EINVAL]) + all_modules.append(make_debug_module_params(params)) + idx += 1 + return all_modules + + def get_exefile_module(self): + all_modules = self.get_all_modules() + reduce_func = lambda x, y: y if y.Flags & DebugModuleFlags.DEBUG_MODULE_EXE_MODULE else x + main_module = reduce(reduce_func, all_modules, None) + if main_module is None: + raise Exception("Couldn't find the exefile module") + return main_module + + def get_module_name(self, base): + return self.GetModuleNameString(DebugModuleNames.DEBUG_MODNAME_MODULE, base) + + def get_exefile_module_name(self): + return self.get_module_name(self.get_exefile_module().Base) |