Refactor symbolinfo.cpp/.h
This commit is contained in:
parent
722665fe53
commit
61c731693c
|
@ -186,7 +186,7 @@ void dbgfunctionsinit()
|
|||
_dbgfunctions.DisasmFast = disasmfast;
|
||||
_dbgfunctions.MemUpdateMap = _memupdatemap;
|
||||
_dbgfunctions.GetCallStack = _getcallstack;
|
||||
_dbgfunctions.SymbolDownloadAllSymbols = symdownloadallsymbols;
|
||||
_dbgfunctions.SymbolDownloadAllSymbols = SymDownloadAllSymbols;
|
||||
_dbgfunctions.GetJit = _getjit;
|
||||
_dbgfunctions.GetJitAuto = _getjitauto;
|
||||
_dbgfunctions.GetDefJit = dbggetdefjit;
|
||||
|
|
|
@ -690,7 +690,7 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
|
|||
case DBG_SYMBOL_ENUM:
|
||||
{
|
||||
SYMBOLCBINFO* cbInfo = (SYMBOLCBINFO*)param1;
|
||||
symenum(cbInfo->base, cbInfo->cbSymbolEnum, cbInfo->user);
|
||||
SymEnum(cbInfo->base, cbInfo->cbSymbolEnum, cbInfo->user);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -225,7 +225,7 @@ void cbUserBreakpoint()
|
|||
bptype = "UD2";
|
||||
else if((titantype & UE_BREAKPOINT_TYPE_LONG_INT3) == UE_BREAKPOINT_TYPE_LONG_INT3)
|
||||
bptype = "LONG INT3";
|
||||
const char* symbolicname = symgetsymbolicname(bp.addr);
|
||||
const char* symbolicname = SymGetSymbolicName(bp.addr);
|
||||
if(symbolicname)
|
||||
{
|
||||
if(*bp.name)
|
||||
|
@ -302,7 +302,7 @@ void cbHardwareBreakpoint(void* ExceptionAddress)
|
|||
bptype = "write";
|
||||
break;
|
||||
}
|
||||
const char* symbolicname = symgetsymbolicname(bp.addr);
|
||||
const char* symbolicname = SymGetSymbolicName(bp.addr);
|
||||
if(symbolicname)
|
||||
{
|
||||
if(*bp.name)
|
||||
|
@ -363,7 +363,7 @@ void cbMemoryBreakpoint(void* ExceptionAddress)
|
|||
bptype = " (read/write/execute)";
|
||||
break;
|
||||
}
|
||||
const char* symbolicname = symgetsymbolicname(bp.addr);
|
||||
const char* symbolicname = SymGetSymbolicName(bp.addr);
|
||||
if(symbolicname)
|
||||
{
|
||||
if(*bp.name)
|
||||
|
@ -633,7 +633,7 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
|
|||
memset(&modInfo, 0, sizeof(modInfo));
|
||||
modInfo.SizeOfStruct = sizeof(modInfo);
|
||||
if(SymGetModuleInfo64(fdProcessInfo->hProcess, (DWORD64)base, &modInfo))
|
||||
modload((uint)base, modInfo.ImageSize, modInfo.ImageName);
|
||||
ModLoad((uint)base, modInfo.ImageSize, modInfo.ImageName);
|
||||
dbggetprivateusage(fdProcessInfo->hProcess, true);
|
||||
memupdatemap(fdProcessInfo->hProcess); //update memory map
|
||||
char modname[256] = "";
|
||||
|
@ -813,7 +813,7 @@ static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
|
|||
memset(&modInfo, 0, sizeof(modInfo));
|
||||
modInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);
|
||||
if(SymGetModuleInfo64(fdProcessInfo->hProcess, (DWORD64)base, &modInfo))
|
||||
modload((uint)base, modInfo.ImageSize, modInfo.ImageName);
|
||||
ModLoad((uint)base, modInfo.ImageSize, modInfo.ImageName);
|
||||
dbggetprivateusage(fdProcessInfo->hProcess, true);
|
||||
memupdatemap(fdProcessInfo->hProcess); //update memory map
|
||||
char modname[256] = "";
|
||||
|
|
|
@ -1382,7 +1382,7 @@ CMDRESULT cbDebugDownloadSymbol(int argc, char* argv[])
|
|||
}
|
||||
if(argc < 2) //no arguments
|
||||
{
|
||||
symdownloadallsymbols(szSymbolStore); //download symbols for all modules
|
||||
SymDownloadAllSymbols(szSymbolStore); //download symbols for all modules
|
||||
GuiSymbolRefreshCurrent();
|
||||
dputs("Done! See symbol log for more information");
|
||||
return STATUS_CONTINUE;
|
||||
|
|
|
@ -80,9 +80,9 @@ bool ModLoad(uint base, uint size, const char* fullpath)
|
|||
// Add module to list
|
||||
EXCLUSIVE_ACQUIRE(LockModules);
|
||||
modinfo.insert(std::make_pair(Range(base, base + size - 1), info));
|
||||
EXCLUSIVE_RELEASE(LockModules);
|
||||
EXCLUSIVE_RELEASE();
|
||||
|
||||
symupdatemodulelist();
|
||||
SymUpdateModuleList();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@ bool ModUnload(uint base)
|
|||
StaticFileUnloadW(nullptr, false, found->second.Handle, found->second.FileMapSize, found->second.MapHandle, found->second.FileMapVA);
|
||||
|
||||
// Update symbols
|
||||
symupdatemodulelist();
|
||||
SymUpdateModuleList();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -112,10 +112,10 @@ void ModClear()
|
|||
// Remove all modules in the list
|
||||
EXCLUSIVE_ACQUIRE(LockModules);
|
||||
modinfo.clear();
|
||||
EXCLUSIVE_RELEASE(LockModules);
|
||||
EXCLUSIVE_RELEASE();
|
||||
|
||||
// Tell the symbol updater
|
||||
symupdatemodulelist();
|
||||
SymUpdateModuleList();
|
||||
}
|
||||
|
||||
MODINFO* ModInfoFromAddr(uint addr)
|
||||
|
|
|
@ -11,45 +11,41 @@ struct SYMBOLCBDATA
|
|||
void* user;
|
||||
};
|
||||
|
||||
static BOOL CALLBACK EnumSymbols(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext)
|
||||
static BOOL CALLBACK EnumSymbols(PSYMBOL_INFO SymInfo, ULONG SymbolSize, PVOID UserContext)
|
||||
{
|
||||
int len = (int)strlen(pSymInfo->Name);
|
||||
SYMBOLINFO curSymbol;
|
||||
memset(&curSymbol, 0, sizeof(SYMBOLINFO));
|
||||
curSymbol.addr = (duint)pSymInfo->Address;
|
||||
curSymbol.decoratedSymbol = (char*)BridgeAlloc(len + 1);
|
||||
strcpy_s(curSymbol.decoratedSymbol, len + 1, pSymInfo->Name);
|
||||
|
||||
curSymbol.addr = (duint)SymInfo->Address;
|
||||
curSymbol.decoratedSymbol = (char*)BridgeAlloc(strlen(SymInfo->Name) + 1);
|
||||
curSymbol.undecoratedSymbol = (char*)BridgeAlloc(MAX_SYM_NAME);
|
||||
if(strstr(pSymInfo->Name, "Ordinal"))
|
||||
strcpy_s(curSymbol.decoratedSymbol, strlen(SymInfo->Name) + 1, SymInfo->Name);
|
||||
|
||||
// Skip bad ordinals
|
||||
if(strstr(SymInfo->Name, "Ordinal"))
|
||||
{
|
||||
//skip bad ordinals
|
||||
if(pSymInfo->Address == pSymInfo->ModBase)
|
||||
// Does the symbol point to the module base?
|
||||
if(SymInfo->Address == SymInfo->ModBase)
|
||||
return TRUE;
|
||||
}
|
||||
if(!UnDecorateSymbolName(pSymInfo->Name, curSymbol.undecoratedSymbol, MAX_SYM_NAME, UNDNAME_COMPLETE))
|
||||
|
||||
// Convert a mangled/decorated C++ name to a readable format
|
||||
if(!UnDecorateSymbolName(SymInfo->Name, curSymbol.undecoratedSymbol, MAX_SYM_NAME, UNDNAME_COMPLETE))
|
||||
{
|
||||
BridgeFree(curSymbol.undecoratedSymbol);
|
||||
curSymbol.undecoratedSymbol = 0;
|
||||
curSymbol.undecoratedSymbol = nullptr;
|
||||
}
|
||||
else if(!strcmp(curSymbol.decoratedSymbol, curSymbol.undecoratedSymbol))
|
||||
{
|
||||
BridgeFree(curSymbol.undecoratedSymbol);
|
||||
curSymbol.undecoratedSymbol = 0;
|
||||
curSymbol.undecoratedSymbol = nullptr;
|
||||
}
|
||||
|
||||
SYMBOLCBDATA* cbData = (SYMBOLCBDATA*)UserContext;
|
||||
cbData->cbSymbolEnum(&curSymbol, cbData->user);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void symenum(uint base, CBSYMBOLENUM cbSymbolEnum, void* user)
|
||||
{
|
||||
SYMBOLCBDATA symbolCbData;
|
||||
symbolCbData.cbSymbolEnum = cbSymbolEnum;
|
||||
symbolCbData.user = user;
|
||||
char mask[] = "*";
|
||||
SymEnumSymbols(fdProcessInfo->hProcess, base, mask, EnumSymbols, &symbolCbData);
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
static BOOL CALLBACK EnumModules(LPCTSTR ModuleName, DWORD64 BaseOfDll, PVOID UserContext)
|
||||
#else
|
||||
|
@ -57,120 +53,171 @@ static BOOL CALLBACK EnumModules(LPCTSTR ModuleName, ULONG BaseOfDll, PVOID User
|
|||
#endif //_WIN64
|
||||
{
|
||||
SYMBOLMODULEINFO curModule;
|
||||
memset(&curModule, 0, sizeof(SYMBOLMODULEINFO));
|
||||
curModule.base = BaseOfDll;
|
||||
ModNameFromAddr(BaseOfDll, curModule.name, true);
|
||||
|
||||
((std::vector<SYMBOLMODULEINFO>*)UserContext)->push_back(curModule);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void symupdatemodulelist()
|
||||
void SymEnum(uint Base, CBSYMBOLENUM EnumCallback, void* UserData)
|
||||
{
|
||||
std::vector<SYMBOLMODULEINFO> modList;
|
||||
modList.clear();
|
||||
SymEnumerateModules(fdProcessInfo->hProcess, EnumModules, &modList);
|
||||
int modcount = (int)modList.size();
|
||||
SYMBOLMODULEINFO* modListBridge = (SYMBOLMODULEINFO*)BridgeAlloc(sizeof(SYMBOLMODULEINFO) * modcount);
|
||||
for(int i = 0; i < modcount; i++)
|
||||
memcpy(&modListBridge[i], &modList.at(i), sizeof(SYMBOLMODULEINFO));
|
||||
GuiSymbolUpdateModuleList(modcount, modListBridge);
|
||||
SYMBOLCBDATA symbolCbData;
|
||||
symbolCbData.cbSymbolEnum = EnumCallback;
|
||||
symbolCbData.user = UserData;
|
||||
|
||||
// Enumerate every single symbol for the module in 'base'
|
||||
if(!SymEnumSymbols(fdProcessInfo->hProcess, Base, "*", EnumSymbols, &symbolCbData))
|
||||
dputs("SymEnumSymbols failed!");
|
||||
}
|
||||
|
||||
void symdownloadallsymbols(const char* szSymbolStore)
|
||||
void SymUpdateModuleList()
|
||||
{
|
||||
if(!szSymbolStore)
|
||||
szSymbolStore = "http://msdl.microsoft.com/download/symbols";
|
||||
// Build the vector of modules
|
||||
std::vector<SYMBOLMODULEINFO> modList;
|
||||
modList.clear();
|
||||
SymEnumerateModules(fdProcessInfo->hProcess, EnumModules, &modList);
|
||||
int modcount = (int)modList.size();
|
||||
if(!modcount)
|
||||
|
||||
if(!SymEnumerateModules(fdProcessInfo->hProcess, EnumModules, &modList))
|
||||
dputs("SymEnumerateModules failed!");
|
||||
|
||||
// Send the module data to the GUI for updating
|
||||
GuiSymbolUpdateModuleList((int)modList.size(), modList.data());
|
||||
}
|
||||
|
||||
void SymDownloadAllSymbols(const char* SymbolStore)
|
||||
{
|
||||
// Default to Microsoft's symbol server
|
||||
if(!SymbolStore)
|
||||
SymbolStore = "http://msdl.microsoft.com/download/symbols";
|
||||
|
||||
// Build the vector of modules
|
||||
std::vector<SYMBOLMODULEINFO> modList;
|
||||
|
||||
if(!SymEnumerateModules(fdProcessInfo->hProcess, EnumModules, &modList))
|
||||
dputs("SymEnumerateModules failed!");
|
||||
|
||||
// Skip loading if there aren't any found modules
|
||||
if(modList.size() <= 0)
|
||||
return;
|
||||
char szOldSearchPath[MAX_PATH] = "";
|
||||
if(!SymGetSearchPath(fdProcessInfo->hProcess, szOldSearchPath, MAX_PATH)) //backup current path
|
||||
|
||||
// Backup the current symbol search path
|
||||
char oldSearchPath[MAX_PATH];
|
||||
|
||||
if(!SymGetSearchPath(fdProcessInfo->hProcess, oldSearchPath, MAX_PATH))
|
||||
{
|
||||
dputs("SymGetSearchPath failed!");
|
||||
return;
|
||||
}
|
||||
char szServerSearchPath[MAX_PATH * 2] = "";
|
||||
sprintf_s(szServerSearchPath, "SRV*%s*%s", szSymbolCachePath, szSymbolStore);
|
||||
if(!SymSetSearchPath(fdProcessInfo->hProcess, szServerSearchPath)) //update search path
|
||||
|
||||
// Use the custom server path and directory
|
||||
char customSearchPath[MAX_PATH * 2];
|
||||
sprintf_s(customSearchPath, "SRV*%s*%s", szSymbolCachePath, SymbolStore);
|
||||
|
||||
if(!SymSetSearchPath(fdProcessInfo->hProcess, customSearchPath))
|
||||
{
|
||||
dputs("SymSetSearchPath (1) failed!");
|
||||
return;
|
||||
}
|
||||
for(int i = 0; i < modcount; i++) //reload all modules
|
||||
|
||||
// Reload all modules
|
||||
for(auto & module : modList)
|
||||
{
|
||||
dprintf("downloading symbols for %s...\n", modList.at(i).name);
|
||||
uint modbase = modList.at(i).base;
|
||||
wchar_t szModulePath[MAX_PATH] = L"";
|
||||
if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)modbase, szModulePath, MAX_PATH))
|
||||
dprintf("Downloading symbols for %s...\n", module.name);
|
||||
|
||||
wchar_t modulePath[MAX_PATH];
|
||||
if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)module.base, modulePath, MAX_PATH))
|
||||
{
|
||||
dprintf("GetModuleFileNameExW("fhex") failed!\n", modbase);
|
||||
dprintf("GetModuleFileNameExW("fhex") failed!\n", module.base);
|
||||
continue;
|
||||
}
|
||||
if(!SymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)modbase))
|
||||
|
||||
if(!SymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)module.base))
|
||||
{
|
||||
dprintf("SymUnloadModule64("fhex") failed!\n", modbase);
|
||||
dprintf("SymUnloadModule64("fhex") failed!\n", module.base);
|
||||
continue;
|
||||
}
|
||||
if(!SymLoadModuleEx(fdProcessInfo->hProcess, 0, StringUtils::Utf16ToUtf8(szModulePath).c_str(), 0, (DWORD64)modbase, 0, 0, 0))
|
||||
|
||||
if(!SymLoadModuleEx(fdProcessInfo->hProcess, 0, StringUtils::Utf16ToUtf8(modulePath).c_str(), 0, (DWORD64)module.base, 0, 0, 0))
|
||||
{
|
||||
dprintf("SymLoadModuleEx("fhex") failed!\n", modbase);
|
||||
dprintf("SymLoadModuleEx("fhex") failed!\n", module.base);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(!SymSetSearchPath(fdProcessInfo->hProcess, szOldSearchPath)) //restore search path
|
||||
{
|
||||
|
||||
// Restore the old search path
|
||||
if(!SymSetSearchPath(fdProcessInfo->hProcess, oldSearchPath))
|
||||
dputs("SymSetSearchPath (2) failed!");
|
||||
}
|
||||
}
|
||||
|
||||
bool symfromname(const char* name, uint* addr)
|
||||
bool SymAddrFromName(const char* Name, uint* Address)
|
||||
{
|
||||
if(!name or !strlen(name) or !addr or !_strnicmp(name, "ordinal", 7)) //skip 'OrdinalXXX'
|
||||
if(!Name || Name[0] == '\0')
|
||||
return false;
|
||||
|
||||
if(!Address)
|
||||
return false;
|
||||
|
||||
// Skip 'OrdinalXXX'
|
||||
if(!_strnicmp(Name, "Ordinal", 7))
|
||||
return false;
|
||||
|
||||
// According to MSDN:
|
||||
// Note that the total size of the data is the SizeOfStruct + (MaxNameLen - 1) * sizeof(TCHAR)
|
||||
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)];
|
||||
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
|
||||
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
pSymbol->MaxNameLen = MAX_LABEL_SIZE;
|
||||
if(!SymFromName(fdProcessInfo->hProcess, name, pSymbol))
|
||||
|
||||
PSYMBOL_INFO symbol = (PSYMBOL_INFO)&buffer;
|
||||
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
symbol->MaxNameLen = MAX_LABEL_SIZE;
|
||||
|
||||
if(!SymFromName(fdProcessInfo->hProcess, Name, symbol))
|
||||
return false;
|
||||
*addr = (uint)pSymbol->Address;
|
||||
|
||||
*Address = (uint)symbol->Address;
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* symgetsymbolicname(uint addr)
|
||||
const char* SymGetSymbolicName(uint Address)
|
||||
{
|
||||
//[modname.]symbolname
|
||||
static char symbolicname[MAX_MODULE_SIZE + MAX_SYM_NAME] = "";
|
||||
char label[MAX_SYM_NAME] = "";
|
||||
bool retval = false;
|
||||
if(labelget(addr, label)) //user labels have priority
|
||||
retval = true;
|
||||
else //no user labels
|
||||
//
|
||||
// This resolves an address to a module and symbol:
|
||||
// [modname.]symbolname
|
||||
//
|
||||
char label[MAX_SYM_NAME];
|
||||
|
||||
// User labels have priority, but if one wasn't found,
|
||||
// default to a symbol lookup
|
||||
if(!labelget(Address, label))
|
||||
{
|
||||
DWORD64 displacement = 0;
|
||||
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)];
|
||||
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
|
||||
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
pSymbol->MaxNameLen = MAX_LABEL_SIZE;
|
||||
if(SymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) and !displacement)
|
||||
{
|
||||
pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0';
|
||||
if(!bUndecorateSymbolNames or !UnDecorateSymbolName(pSymbol->Name, label, MAX_SYM_NAME, UNDNAME_COMPLETE))
|
||||
strcpy_s(label, pSymbol->Name);
|
||||
retval = true;
|
||||
}
|
||||
|
||||
PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
|
||||
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
symbol->MaxNameLen = MAX_LABEL_SIZE;
|
||||
|
||||
// Perform a symbol lookup
|
||||
DWORD64 displacement = 0;
|
||||
|
||||
if(!SymFromAddr(fdProcessInfo->hProcess, (DWORD64)Address, &displacement, symbol))
|
||||
return nullptr;
|
||||
|
||||
// If the symbol wasn't at offset 0 (start from the beginning) ignore it
|
||||
if(displacement != 0)
|
||||
return nullptr;
|
||||
|
||||
// Terminate the string for sanity
|
||||
symbol->Name[symbol->MaxNameLen - 1] = '\0';
|
||||
|
||||
if(!bUndecorateSymbolNames || !UnDecorateSymbolName(symbol->Name, label, MAX_SYM_NAME, UNDNAME_COMPLETE))
|
||||
strcpy_s(label, symbol->Name);
|
||||
}
|
||||
if(retval)
|
||||
{
|
||||
char modname[MAX_MODULE_SIZE] = "";
|
||||
if(ModNameFromAddr(addr, modname, false))
|
||||
sprintf(symbolicname, "%s.%s", modname, label);
|
||||
else
|
||||
sprintf(symbolicname, "<%s>", label);
|
||||
return symbolicname;
|
||||
}
|
||||
return 0;
|
||||
|
||||
// TODO: FIXME: STATIC VARIABLE
|
||||
static char symbolicname[MAX_MODULE_SIZE + MAX_SYM_NAME];
|
||||
char modname[MAX_MODULE_SIZE];
|
||||
|
||||
if(ModNameFromAddr(Address, modname, false))
|
||||
sprintf_s(symbolicname, "%s.%s", modname, label);
|
||||
else
|
||||
sprintf_s(symbolicname, "<%s>", label);
|
||||
|
||||
return symbolicname;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
#ifndef _SYMBOLINFO_H
|
||||
#define _SYMBOLINFO_H
|
||||
#pragma once
|
||||
|
||||
#include "_global.h"
|
||||
|
||||
void symenum(uint base, CBSYMBOLENUM cbSymbolEnum, void* user);
|
||||
void symupdatemodulelist();
|
||||
void symdownloadallsymbols(const char* szSymbolStore);
|
||||
bool symfromname(const char* name, uint* addr);
|
||||
const char* symgetsymbolicname(uint addr);
|
||||
|
||||
#endif //_SYMBOLINFO_H
|
||||
void SymEnum(uint Base, CBSYMBOLENUM EnumCallback, void* UserData);
|
||||
void SymUpdateModuleList();
|
||||
void SymDownloadAllSymbols(const char* SymbolStore);
|
||||
bool SymAddrFromName(const char* Name, uint* Address);
|
||||
const char* SymGetSymbolicName(uint Address);
|
|
@ -1559,7 +1559,7 @@ bool valfromstring(const char* string, uint* value, bool silent, bool baseonly,
|
|||
return true;
|
||||
else if(labelfromstring(string, value)) //then come labels
|
||||
return true;
|
||||
else if(symfromname(string, value)) //then come symbols
|
||||
else if(SymAddrFromName(string, value)) //then come symbols
|
||||
return true;
|
||||
else if(varget(string, value, value_size, 0)) //finally variables
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue