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:
parent
09756946c6
commit
b36bfed6f2
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue