1
0
Fork 0

Refactor symbolinfo.cpp/.h

This commit is contained in:
Nukem 2015-03-17 16:46:06 -04:00
parent 722665fe53
commit 61c731693c
8 changed files with 158 additions and 114 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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] = "";

View File

@ -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;

View File

@ -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)

View File

@ -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;
}

View File

@ -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);

View File

@ -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
{