1
0
Fork 0

Fix : Reverted back DbgSymbolEnum Signature to default to keep SDK compatibility. Added DbgSymbolEnumFromCache to use Cache first if found.

Dbg + SymbolView : Added import symbols per module. Gets cached in memory after being retrieved first time.
CPUDump : Small sprintf format fix.
This commit is contained in:
Herzeh 2015-12-06 22:30:30 +01:00
parent 09756946c6
commit b36bfed6f2
11 changed files with 337 additions and 69 deletions

View File

@ -566,13 +566,23 @@ BRIDGE_IMPEXP bool DbgScriptGetBranchInfo(int line, SCRIPTBRANCH* info)
}
// FIXME all
BRIDGE_IMPEXP void DbgSymbolEnum(duint base, CBSYMBOLENUM cbSymbolEnum, void* user, bool bUseCache)
BRIDGE_IMPEXP void DbgSymbolEnum(duint base, CBSYMBOLENUM cbSymbolEnum, void* user)
{
SYMBOLCBINFO cbInfo;
cbInfo.base = base;
cbInfo.cbSymbolEnum = cbSymbolEnum;
cbInfo.user = user;
_dbg_sendmessage(DBG_SYMBOL_ENUM, &cbInfo, (void*)(duint)bUseCache);
_dbg_sendmessage(DBG_SYMBOL_ENUM, &cbInfo, 0);
}
// FIXME all
BRIDGE_IMPEXP void DbgSymbolEnumFromCache(duint base, CBSYMBOLENUM cbSymbolEnum, void* user)
{
SYMBOLCBINFO cbInfo;
cbInfo.base = base;
cbInfo.cbSymbolEnum = cbSymbolEnum;
cbInfo.user = user;
_dbg_sendmessage(DBG_SYMBOL_ENUM_FROMCACHE, &cbInfo, 0);
}
BRIDGE_IMPEXP bool DbgAssembleAt(duint addr, const char* instruction)

View File

@ -59,6 +59,7 @@ BRIDGE_IMPEXP int BridgeGetDbgVersion();
#define MAX_LABEL_SIZE 256
#define MAX_COMMENT_SIZE 512
#define MAX_MODULE_SIZE 256
#define MAX_IMPORT_SIZE 256
#define MAX_BREAKPOINT_SIZE 256
#define MAX_SCRIPT_LINE_SIZE 2048
#define MAX_THREAD_NAME_SIZE 256
@ -144,6 +145,7 @@ typedef enum
DBG_SCRIPT_SETIP, // param1=int line, param2=unused
DBG_SCRIPT_GETBRANCHINFO, // param1=int line, param2=SCRIPTBRANCH* info
DBG_SYMBOL_ENUM, // param1=SYMBOLCBINFO* cbInfo, param2=unused
DBG_SYMBOL_ENUM_FROMCACHE, // param1=SYMBOLCBINFO* cbInfo, param2=unused
DBG_ASSEMBLE_AT, // param1=duint addr, param2=const char* instruction
DBG_MODBASE_FROM_NAME, // param1=const char* modname, param2=unused
DBG_DISASM_AT, // param1=duint addr, param2=DISASM_INSTR* instr
@ -349,6 +351,7 @@ struct SYMBOLINFO_
duint addr;
char* decoratedSymbol;
char* undecoratedSymbol;
bool isImported;
};
typedef struct
@ -661,7 +664,8 @@ BRIDGE_IMPEXP void DbgScriptAbort();
BRIDGE_IMPEXP SCRIPTLINETYPE DbgScriptGetLineType(int line);
BRIDGE_IMPEXP void DbgScriptSetIp(int line);
BRIDGE_IMPEXP bool DbgScriptGetBranchInfo(int line, SCRIPTBRANCH* info);
BRIDGE_IMPEXP void DbgSymbolEnum(duint base, CBSYMBOLENUM cbSymbolEnum, void* user, bool bUseCache);
BRIDGE_IMPEXP void DbgSymbolEnum(duint base, CBSYMBOLENUM cbSymbolEnum, void* user);
BRIDGE_IMPEXP void DbgSymbolEnumFromCache(duint base, CBSYMBOLENUM cbSymbolEnum, void* user);
BRIDGE_IMPEXP bool DbgAssembleAt(duint addr, const char* instruction);
BRIDGE_IMPEXP duint DbgModBaseFromName(const char* name);
BRIDGE_IMPEXP void DbgDisasmAt(duint addr, DISASM_INSTR* instr);

View File

@ -762,8 +762,14 @@ extern "C" DLL_EXPORT duint _dbg_sendmessage(DBGMSG type, void* param1, void* pa
case DBG_SYMBOL_ENUM:
{
SYMBOLCBINFO* cbInfo = (SYMBOLCBINFO*)param1;
bool bUseCache = (bool)param2;
SymEnum(cbInfo->base, cbInfo->cbSymbolEnum, cbInfo->user, bUseCache);
SymEnum(cbInfo->base, cbInfo->cbSymbolEnum, cbInfo->user);
}
break;
case DBG_SYMBOL_ENUM_FROMCACHE:
{
SYMBOLCBINFO* cbInfo = (SYMBOLCBINFO*)param1;
SymEnumFromCache(cbInfo->base, cbInfo->cbSymbolEnum, cbInfo->user);
}
break;

View File

@ -87,5 +87,91 @@ bool apienumexports(duint base, EXPORTENUMCALLBACK cbEnum)
cbEnum(base, modname, cur_name, curFunctionRva + base);
}
}
return true;
}
bool apienumimports(duint base, IMPORTENUMCALLBACK cbEnum)
{
// Variables
bool readSuccess;
char importName[MAX_IMPORT_SIZE];
char importModuleName[MAX_MODULE_SIZE];
duint regionSize, importNameLen;
ULONG_PTR importTableRva, importTableSize;
MEMORY_BASIC_INFORMATION mbi;
PIMAGE_IMPORT_DESCRIPTOR importTableVa;
IMAGE_IMPORT_DESCRIPTOR importDescriptor;
PIMAGE_THUNK_DATA imageIATVa, imageINTVa;
IMAGE_THUNK_DATA imageOftThunkData, imageFtThunkData;
PIMAGE_IMPORT_BY_NAME pImageImportByNameVa;
// Get page size
VirtualQueryEx(fdProcessInfo->hProcess, (const void*)base, &mbi, sizeof(mbi));
regionSize = mbi.RegionSize;
Memory<void* > buffer(regionSize, "apienumimports:buffer");
// Read first page into buffer
if (!MemRead(base, buffer(), regionSize))
return false;
// Import Table address and size
importTableRva = GetPE32DataFromMappedFile((duint)buffer(), 0, UE_IMPORTTABLEADDRESS);
importTableSize = GetPE32DataFromMappedFile((duint)buffer(), 0, UE_IMPORTTABLESIZE);
// Return if no imports
if (!importTableSize)
return false;
importTableVa = (PIMAGE_IMPORT_DESCRIPTOR)(base + importTableRva);
readSuccess = MemRead((duint)importTableVa, &importDescriptor, sizeof(importDescriptor));
// Loop through all dlls
while (readSuccess && importDescriptor.FirstThunk)
{
// Copy module name into importModuleName
MemRead((duint)(base + importDescriptor.Name), &importModuleName, MAX_MODULE_SIZE);
imageIATVa = (PIMAGE_THUNK_DATA)(base + importDescriptor.FirstThunk);
imageINTVa = (PIMAGE_THUNK_DATA)(base + importDescriptor.OriginalFirstThunk);
if (!MemRead((duint)imageIATVa, &imageFtThunkData, sizeof(imageFtThunkData)))
return false;
if (!MemRead((duint)imageINTVa, &imageOftThunkData, sizeof(imageOftThunkData)))
return false;
// Loop through all imported function in this dll
while (imageFtThunkData.u1.Function)
{
pImageImportByNameVa = (PIMAGE_IMPORT_BY_NAME)(base + imageOftThunkData.u1.AddressOfData);
// Read every IMPORT_BY_NAME.name
if (!MemRead((duint)pImageImportByNameVa + sizeof(WORD), buffer(), regionSize))
return false;
// Alloc buffer for name and copy name import name to buffer
importNameLen = strlen((char*)buffer());
strcpy_s(importName, MAX_IMPORT_SIZE, (char*)buffer());
// Callback
cbEnum(base, imageFtThunkData.u1.Function, importName, importModuleName);
// Move to next address in the INT
imageINTVa++;
if(!MemRead((duint)imageINTVa, &imageOftThunkData, sizeof(imageOftThunkData)))
return false;
// Move to next address in the IAT and read it into imageFtThunkData
imageIATVa++;
if (!MemRead((duint)imageIATVa, &imageFtThunkData, sizeof(imageFtThunkData)))
return false;
}
importTableVa++;
readSuccess = MemRead((duint)importTableVa, &importDescriptor, sizeof(importDescriptor));
}
return true;
}

View File

@ -55,7 +55,10 @@ struct DepthModuleRangeCompare
//typedefs
typedef std::function<void (duint base, const char* mod, const char* name, duint addr)> EXPORTENUMCALLBACK;
typedef std::function<void (duint base, duint addr, char* name, char* moduleName)> IMPORTENUMCALLBACK;
bool apienumexports(duint base, EXPORTENUMCALLBACK cbEnum);
bool apienumimports(duint base, IMPORTENUMCALLBACK cbEnum);
#endif // _ADDRINFO_H

View File

@ -45,6 +45,9 @@ void GetModuleInfo(MODINFO & Info, ULONG_PTR FileMapVA)
// Add entry to the vector
Info.sections.push_back(curSection);
}
// Clear imports by default
Info.imports.clear();
}
bool ModLoad(duint Base, duint Size, const char* FullPath)
@ -292,6 +295,20 @@ bool ModSectionsFromAddr(duint Address, std::vector<MODSECTIONINFO>* Sections)
return true;
}
bool ModImportsFromAddr(duint Address, std::vector<MODIMPORTINFO>* Imports)
{
SHARED_ACQUIRE(LockModules);
auto module = ModInfoFromAddr(Address);
if (!module)
return false;
// Copy vector <-> vector
*Imports = module->imports;
return true;
}
duint ModEntryFromAddr(duint Address)
{
SHARED_ACQUIRE(LockModules);
@ -328,4 +345,33 @@ void ModGetList(std::vector<MODINFO> & list)
list.clear();
for(const auto & mod : modinfo)
list.push_back(mod.second);
}
bool ModAddImportToModule(duint Base, MODIMPORTINFO importInfo)
{
SHARED_ACQUIRE(LockModules);
if (!Base || !importInfo.addr)
return false;
auto module = ModInfoFromAddr(Base);
if (!module)
return false;
// Search in Import Vector
std::vector<MODIMPORTINFO> *pImports = &(module->imports);
auto it = std::find_if(pImports->begin(), pImports->end(), [&importInfo](MODIMPORTINFO currentImportInfo)->bool
{
return (importInfo.addr == currentImportInfo.addr);
});
// Import in the list already
if (it != pImports->end())
return false;
// Add import to imports vector
pImports->push_back(importInfo);
return true;
}

View File

@ -9,6 +9,13 @@ struct MODSECTIONINFO
char name[MAX_SECTION_SIZE * 5]; // Escaped section name
};
struct MODIMPORTINFO
{
duint addr; // Virtual address
char name[MAX_IMPORT_SIZE];
char moduleName[MAX_MODULE_SIZE];
};
struct MODINFO
{
duint base; // Module base
@ -21,6 +28,7 @@ struct MODINFO
char path[MAX_PATH]; // File path (in UTF8)
std::vector<MODSECTIONINFO> sections;
std::vector<MODIMPORTINFO> imports;
};
bool ModLoad(duint Base, duint Size, const char* FullPath);
@ -34,7 +42,9 @@ duint ModHashFromName(const char* Module);
duint ModBaseFromName(const char* Module);
duint ModSizeFromAddr(duint Address);
bool ModSectionsFromAddr(duint Address, std::vector<MODSECTIONINFO>* Sections);
bool ModImportsFromAddr(duint Address, std::vector<MODIMPORTINFO>* Imports);
duint ModEntryFromAddr(duint Address);
int ModPathFromAddr(duint Address, char* Path, int Size);
int ModPathFromName(const char* Module, char* Path, int Size);
void ModGetList(std::vector<MODINFO> & list);
void ModGetList(std::vector<MODINFO> & list);
bool ModAddImportToModule(duint Base, MODIMPORTINFO importInfo);

View File

@ -9,6 +9,7 @@
#include "console.h"
#include "module.h"
#include "label.h"
#include "addrinfo.h"
struct SYMBOLCBDATA
{
@ -20,35 +21,18 @@ typedef std::vector<SYMBOLINFO> SYMBOLINFOVECTOR;
typedef std::map<ULONG64, SYMBOLINFOVECTOR> SYMBOLINFOMAP;
SYMBOLINFOMAP modulesCacheList;
BOOL CALLBACK EnumSymbols(PSYMBOL_INFO SymInfo, ULONG SymbolSize, PVOID UserContext)
{
bool returnValue;
SYMBOLINFO curSymbol;
memset(&curSymbol, 0, sizeof(SYMBOLINFO));
curSymbol.addr = (duint)SymInfo->Address;
curSymbol.decoratedSymbol = (char*)BridgeAlloc(strlen(SymInfo->Name) + 1);
curSymbol.undecoratedSymbol = (char*)BridgeAlloc(MAX_SYM_NAME);
strcpy_s(curSymbol.decoratedSymbol, strlen(SymInfo->Name) + 1, SymInfo->Name);
// Convert from SYMBOL_INFO to SYMBOLINFO
returnValue = SymGetSymbolInfo(SymInfo, &curSymbol, false);
// Skip bad ordinals
if(strstr(SymInfo->Name, "Ordinal"))
{
// Does the symbol point to the module base?
if(SymInfo->Address == SymInfo->ModBase)
return TRUE;
}
// Convert a mangled/decorated C++ name to a readable format
if(!SafeUnDecorateSymbolName(SymInfo->Name, curSymbol.undecoratedSymbol, MAX_SYM_NAME, UNDNAME_COMPLETE))
{
BridgeFree(curSymbol.undecoratedSymbol);
curSymbol.undecoratedSymbol = nullptr;
}
else if(!strcmp(curSymbol.decoratedSymbol, curSymbol.undecoratedSymbol))
{
BridgeFree(curSymbol.undecoratedSymbol);
curSymbol.undecoratedSymbol = nullptr;
}
if (!returnValue)
return false;
// Add to the cache
modulesCacheList[SymInfo->ModBase].push_back(curSymbol);
@ -58,48 +42,41 @@ BOOL CALLBACK EnumSymbols(PSYMBOL_INFO SymInfo, ULONG SymbolSize, PVOID UserCont
return TRUE;
}
void SymEnum(duint Base, CBSYMBOLENUM EnumCallback, void* UserData, bool useCache)
void SymEnum(duint Base, CBSYMBOLENUM EnumCallback, void* UserData)
{
SYMBOLCBDATA symbolCbData;
symbolCbData.cbSymbolEnum = EnumCallback;
symbolCbData.user = UserData;
// Retrieve from cache
if (useCache)
{
// Check if this module is cached in the list
if (modulesCacheList.find(Base) != modulesCacheList.end())
{
for (duint i = 0; i < modulesCacheList[Base].size(); i++)
{
symbolCbData.cbSymbolEnum(&modulesCacheList[Base].at(i), symbolCbData.user);
}
return;
}
}
else
{
// Check if this module is cached in the list
if (modulesCacheList.find(Base) != modulesCacheList.end())
{
// Free up previously allocated memory
for (duint i = 0; i < modulesCacheList[Base].size(); i++)
{
BridgeFree(modulesCacheList[Base].at(i).decoratedSymbol);
BridgeFree(modulesCacheList[Base].at(i).undecoratedSymbol);
}
// Clear the SYMBOLINFOVECTOR
modulesCacheList[Base].clear();
}
}
SymEnumImports(Base, &symbolCbData);
// Enumerate every single symbol for the module in 'base'
if(!SafeSymEnumSymbols(fdProcessInfo->hProcess, Base, "*", EnumSymbols, &symbolCbData))
dputs("SymEnumSymbols failed!");
}
void SymEnumFromCache(duint Base, CBSYMBOLENUM EnumCallback, void* UserData)
{
SYMBOLCBDATA symbolCbData;
symbolCbData.cbSymbolEnum = EnumCallback;
symbolCbData.user = UserData;
// Check if this module is cached in the list
if (modulesCacheList.find(Base) != modulesCacheList.end())
{
SymEnumImports(Base, &symbolCbData);
// Callback
for (duint i = 0; i < modulesCacheList[Base].size(); i++)
symbolCbData.cbSymbolEnum(&modulesCacheList[Base].at(i), symbolCbData.user);
}
else
{
// Then get the symbols and cache them
SymEnum(Base, EnumCallback, UserData);
}
}
bool SymGetModuleList(std::vector<SYMBOLMODULEINFO>* List)
{
//
@ -358,4 +335,114 @@ void SymClearMemoryCache()
// Clear the whole map
modulesCacheList.clear();
}
bool SymGetSymbolInfo(PSYMBOL_INFO SymInfo, SYMBOLINFO* curSymbol, bool isImported)
{
// SYMBOL_INFO is a structure used by Sym* functions
// SYMBOLINFO is the custom structure used by the debugger
// This functions fills SYMBOLINFO fields from SYMBOL_INFO data
curSymbol->addr = (duint)SymInfo->Address;
curSymbol->decoratedSymbol = (char*)BridgeAlloc(strlen(SymInfo->Name) + 1);
curSymbol->undecoratedSymbol = (char*)BridgeAlloc(MAX_SYM_NAME);
strcpy_s(curSymbol->decoratedSymbol, strlen(SymInfo->Name) + 1, SymInfo->Name);
// Skip bad ordinals
if (strstr(SymInfo->Name, "Ordinal"))
{
// Does the symbol point to the module base?
if (SymInfo->Address == SymInfo->ModBase)
return FALSE;
}
// Convert a mangled/decorated C++ name to a readable format
if (!SafeUnDecorateSymbolName(SymInfo->Name, curSymbol->undecoratedSymbol, MAX_SYM_NAME, UNDNAME_COMPLETE))
{
BridgeFree(curSymbol->undecoratedSymbol);
curSymbol->undecoratedSymbol = nullptr;
}
else if (!strcmp(curSymbol->decoratedSymbol, curSymbol->undecoratedSymbol))
{
BridgeFree(curSymbol->undecoratedSymbol);
curSymbol->undecoratedSymbol = nullptr;
}
// Symbol is exported
curSymbol->isImported = isImported;
return true;
}
void SymEnumImports(duint Base, SYMBOLCBDATA* pSymbolCbData)
{
char buf[MAX_IMPORT_SIZE];
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME]; // Reserve enough space for symbol name, see msdn for this
SYMBOLINFO curSymbol;
PSYMBOL_INFO pSymInfo;
std::vector<MODIMPORTINFO> imports;
// SizeOfStruct and MaxNameLen need to be set or SymFromAddr() returns INVALID_PARAMETER
pSymInfo = (PSYMBOL_INFO)buffer;
pSymInfo->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymInfo->MaxNameLen = MAX_SYM_NAME;
// Enum imports if none found
if (ModImportsFromAddr(Base, &imports) && !imports.size())
{
// Enum imports from current module
apienumimports(Base, [](duint Base, duint Address, char* name, char* moduleName)
{
MODIMPORTINFO importInfo;
importInfo.addr = Address;
strcpy_s(importInfo.name, MAX_IMPORT_SIZE, name);
strcpy_s(importInfo.moduleName, MAX_MODULE_SIZE, moduleName);
// Add import to the module structure
ModAddImportToModule(Base, importInfo);
});
}
// Get imports
if (ModImportsFromAddr(Base, &imports) && imports.size())
{
for (duint i = 0; i < imports.size(); i++)
{
// Can we get symbol for the import address
if (SafeSymFromAddr(fdProcessInfo->hProcess, (duint)imports[i].addr, 0, pSymInfo))
{
// Does the symbol point to the module base?
if (!SymGetSymbolInfo(pSymInfo, &curSymbol, true))
continue;
}
// Otherwise just use import info from module itself
else
{
curSymbol.addr = imports[i].addr;
curSymbol.isImported = true;
curSymbol.undecoratedSymbol = nullptr;
curSymbol.decoratedSymbol = imports[i].name;
}
// Format so that we get : moduleName.importSymbol
duint lenWithoutExt = strlen(imports[i].moduleName) - 3; // Remove extension
strncpy_s(buf, lenWithoutExt, imports[i].moduleName, _TRUNCATE);
strcat_s(buf , ".");
if (curSymbol.undecoratedSymbol)
{
strcat(buf, curSymbol.undecoratedSymbol);
curSymbol.undecoratedSymbol = buf;
}
if (curSymbol.decoratedSymbol)
{
strcat(buf, curSymbol.decoratedSymbol);
curSymbol.decoratedSymbol = buf;
}
// Callback
pSymbolCbData->cbSymbolEnum(&curSymbol, pSymbolCbData->user);
}
}
}

View File

@ -2,13 +2,18 @@
#include "_global.h"
void SymEnum(duint Base, CBSYMBOLENUM EnumCallback, void* UserData, bool bUseCache);
struct SYMBOLCBDATA;
void SymEnum(duint Base, CBSYMBOLENUM EnumCallback, void* UserData);
void SymEnumFromCache(duint Base, CBSYMBOLENUM EnumCallback, void* UserData);
bool SymGetModuleList(std::vector<SYMBOLMODULEINFO>* List);
void SymUpdateModuleList();
void SymDownloadAllSymbols(const char* SymbolStore);
bool SymAddrFromName(const char* Name, duint* Address);
const char* SymGetSymbolicName(duint Address);
void SymClearMemoryCache();
bool SymGetSymbolInfo(PSYMBOL_INFO SymInfo, SYMBOLINFO* curSymbol, bool isImported);
void SymEnumImports(duint Base, SYMBOLCBDATA* pSymbolCbData);
/**
\brief Gets the source code file name and line from an address.

View File

@ -251,7 +251,7 @@ void CPUDump::setupContextMenu()
mMemoryAccessSingleshoot = new QAction("&Singleshoot", this);
connect(mMemoryAccessSingleshoot, SIGNAL(triggered()), this, SLOT(memoryAccessSingleshootSlot()));
mMemoryAccessMenu->addAction(mMemoryAccessSingleshoot);
mMemoryAccessRestore = new QAction("&Restore", this);
mMemoryAccessRestore = new QAction("&Restore on hit", this);
connect(mMemoryAccessRestore, SIGNAL(triggered()), this, SLOT(memoryAccessRestoreSlot()));
mMemoryAccessMenu->addAction(mMemoryAccessRestore);
mBreakpointMenu->addMenu(mMemoryAccessMenu);
@ -261,7 +261,7 @@ void CPUDump::setupContextMenu()
mMemoryWriteSingleshoot = new QAction("&Singleshoot", this);
connect(mMemoryWriteSingleshoot, SIGNAL(triggered()), this, SLOT(memoryWriteSingleshootSlot()));
mMemoryWriteMenu->addAction(mMemoryWriteSingleshoot);
mMemoryWriteRestore = new QAction("&Restore", this);
mMemoryWriteRestore = new QAction("&Restore on hit", this);
connect(mMemoryWriteRestore, SIGNAL(triggered()), this, SLOT(memoryWriteRestoreSlot()));
mMemoryWriteMenu->addAction(mMemoryWriteRestore);
mBreakpointMenu->addMenu(mMemoryWriteMenu);
@ -271,7 +271,7 @@ void CPUDump::setupContextMenu()
mMemoryExecuteSingleshoot = new QAction("&Singleshoot", this);
connect(mMemoryExecuteSingleshoot, SIGNAL(triggered()), this, SLOT(memoryExecuteSingleshootSlot()));
mMemoryExecuteMenu->addAction(mMemoryExecuteSingleshoot);
mMemoryExecuteRestore = new QAction("&Restore", this);
mMemoryExecuteRestore = new QAction("&Restore on hit", this);
connect(mMemoryExecuteRestore, SIGNAL(triggered()), this, SLOT(memoryExecuteRestoreSlot()));
mMemoryExecuteMenu->addAction(mMemoryExecuteRestore);
mBreakpointMenu->addMenu(mMemoryExecuteMenu);
@ -721,9 +721,9 @@ void CPUDump::mouseMoveEvent(QMouseEvent *event)
// Format text like this : [ptr] = ptrValue
QString strPtrValue;
#ifdef _WIN64
strPtrValue.sprintf("[%#016X] = %#016X", ptr, ptrValue)
strPtrValue.sprintf("[0x%016X] = 0x%016X", ptr, ptrValue);
#else
strPtrValue.sprintf("[%#08X] = %#08X", ptr, ptrValue);
strPtrValue.sprintf("[0x%08X] = 0x%08X", ptr, ptrValue);
#endif
// Show tooltip

View File

@ -31,11 +31,13 @@ SymbolView::SymbolView(QWidget* parent) : QWidget(parent), ui(new Ui::SymbolView
// Setup symbol list
mSearchListView->mList->addColumnAt(charwidth * 2 * sizeof(dsint) + 8, "Address", true);
mSearchListView->mList->addColumnAt(charwidth * 2 * sizeof(dsint) + 8, "Type", true);
mSearchListView->mList->addColumnAt(charwidth * 80, "Symbol", true);
mSearchListView->mList->addColumnAt(2000, "Symbol (undecorated)", true);
// Setup search list
mSearchListView->mSearchList->addColumnAt(charwidth * 2 * sizeof(dsint) + 8, "Address", true);
mSearchListView->mSearchList->addColumnAt(charwidth * 2 * sizeof(dsint) + 8, "Type", true);
mSearchListView->mSearchList->addColumnAt(charwidth * 80, "Symbol", true);
mSearchListView->mSearchList->addColumnAt(2000, "Symbol (undecorated)", true);
@ -173,11 +175,20 @@ void SymbolView::cbSymbolEnum(SYMBOLINFO* symbol, void* user)
symbolList->setCellContent(index, 0, QString("%1").arg(symbol->addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper());
if(symbol->decoratedSymbol)
{
symbolList->setCellContent(index, 1, symbol->decoratedSymbol);
symbolList->setCellContent(index, 2, symbol->decoratedSymbol);
}
if(symbol->undecoratedSymbol)
{
symbolList->setCellContent(index, 2, symbol->undecoratedSymbol);
symbolList->setCellContent(index, 3, symbol->undecoratedSymbol);
}
if(symbol->isImported)
{
symbolList->setCellContent(index, 1, "Import");
}
else
{
symbolList->setCellContent(index, 1, "Export");
}
}
@ -187,7 +198,7 @@ void SymbolView::moduleSelectionChanged(int index)
if(!mModuleBaseList.count(mod))
return;
mSearchListView->mList->setRowCount(0);
DbgSymbolEnum(mModuleBaseList[mod], cbSymbolEnum, mSearchListView->mList, true);
DbgSymbolEnumFromCache(mModuleBaseList[mod], cbSymbolEnum, mSearchListView->mList);
mSearchListView->mList->reloadData();
mSearchListView->mList->setSingleSelection(0);
mSearchListView->mList->setTableOffset(0);