mirror of
https://github.com/x64dbg/x64dbg.git
synced 2025-02-22 22:11:55 +00:00
DBG: added function symgetsymbolicname
DBG: fixed some bugs in valapifromstring (no longer uses TitanEngine, saves a lot of time) DBG: moved symfromname to symbolinfo.cpp DBG: better breakpoint callbacks (symbolic name resolving + type resolving)
This commit is contained in:
parent
accc3ff1c1
commit
584042455f
@ -591,7 +591,7 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
|
||||
case DBG_SYMBOL_ENUM:
|
||||
{
|
||||
SYMBOLCBINFO* cbInfo=(SYMBOLCBINFO*)param1;
|
||||
symbolenum(cbInfo->base, cbInfo->cbSymbolEnum, cbInfo->user);
|
||||
symenum(cbInfo->base, cbInfo->cbSymbolEnum, cbInfo->user);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -96,7 +96,7 @@ bool modload(uint base, uint size, const char* fullpath)
|
||||
strcpy(info.name, name);
|
||||
_strlwr(info.name);
|
||||
modinfo.push_back(info);
|
||||
symbolupdatemodulelist();
|
||||
symupdatemodulelist();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ bool modunload(uint base)
|
||||
if(modinfo.at(i).base==base)
|
||||
{
|
||||
modinfo.erase(modinfo.begin()+i);
|
||||
symbolupdatemodulelist();
|
||||
symupdatemodulelist();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -118,7 +118,7 @@ bool modunload(uint base)
|
||||
void modclear()
|
||||
{
|
||||
std::vector<MODINFO>().swap(modinfo);
|
||||
symbolupdatemodulelist();
|
||||
symupdatemodulelist();
|
||||
}
|
||||
|
||||
bool modnamefromaddr(uint addr, char* modname, bool extension)
|
||||
@ -530,21 +530,6 @@ bool bookmarkdel(uint addr)
|
||||
return true;
|
||||
}
|
||||
|
||||
///symbol functions
|
||||
bool symfromname(const char* name, uint* addr)
|
||||
{
|
||||
if(!name or !strlen(name) or !addr)
|
||||
return false;
|
||||
char buffer[sizeof(SYMBOL_INFO) + MAX_LABEL_SIZE * sizeof(char)];
|
||||
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
|
||||
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
pSymbol->MaxNameLen = MAX_LABEL_SIZE;
|
||||
if(!SymFromName(fdProcessInfo->hProcess, name, pSymbol))
|
||||
return false;
|
||||
*addr=(uint)pSymbol->Address;
|
||||
return true;
|
||||
}
|
||||
|
||||
///function database
|
||||
bool functionget(duint addr, duint* start, duint* end)
|
||||
{
|
||||
|
@ -39,7 +39,6 @@ bool labeldel(uint addr);
|
||||
bool bookmarkset(uint addr);
|
||||
bool bookmarkget(uint addr);
|
||||
bool bookmarkdel(uint addr);
|
||||
bool symfromname(const char* name, uint* addr);
|
||||
bool functionget(duint addr, duint* start, duint* end);
|
||||
bool functionoverlaps(uint start, uint end);
|
||||
bool functionadd(uint start, uint end, bool manual);
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "plugin_loader.h"
|
||||
#include "x64_dbg.h"
|
||||
#include "disasm_helper.h"
|
||||
#include "symbolinfo.h"
|
||||
|
||||
#include "BeaEngine\BeaEngine.h"
|
||||
|
||||
@ -102,34 +103,21 @@ static void cbUserBreakpoint()
|
||||
bptype="UD2";
|
||||
else if((titantype&UE_BREAKPOINT_TYPE_LONG_INT3)==UE_BREAKPOINT_TYPE_LONG_INT3)
|
||||
bptype="LONG INT3";
|
||||
const char* apiname=(const char*)ImporterGetAPINameFromDebugee(fdProcessInfo->hProcess, bp.addr);
|
||||
char log[deflen]="";
|
||||
if(apiname)
|
||||
const char* symbolicname=symgetsymbolicname(bp.addr);
|
||||
if(symbolicname)
|
||||
{
|
||||
const char* dllname_=(const char*)ImporterGetDLLNameFromDebugee(fdProcessInfo->hProcess, bp.addr);
|
||||
char dllname[256]="";
|
||||
strcpy(dllname, dllname_);
|
||||
_strlwr(dllname);
|
||||
int len=strlen(dllname);
|
||||
for(int i=len-1; i!=0; i--)
|
||||
if(dllname[i]=='.')
|
||||
{
|
||||
dllname[i]=0;
|
||||
break;
|
||||
}
|
||||
if(*bp.name)
|
||||
sprintf(log, "%s breakpoint \"%s\" at %s.%s ("fhex")!", bptype, bp.name, dllname, apiname, bp.addr);
|
||||
dprintf("%s breakpoint \"%s\" at %s ("fhex")!\n", bptype, bp.name, symbolicname, bp.addr);
|
||||
else
|
||||
sprintf(log, "%s breakpoint at %s.%s ("fhex")!", bptype, dllname, apiname, bp.addr);
|
||||
dprintf("%s breakpoint at %s ("fhex")!\n", bptype, symbolicname, bp.addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(*bp.name)
|
||||
sprintf(log, "%s breakpoint \"%s\" at "fhex"!", bptype, bp.name, bp.addr);
|
||||
dprintf("%s breakpoint \"%s\" at "fhex"!\n", bptype, bp.name, bp.addr);
|
||||
else
|
||||
sprintf(log, "%s breakpoint at "fhex"!", bptype, bp.addr);
|
||||
dprintf("%s breakpoint at "fhex"!\n", bptype, bp.addr);
|
||||
}
|
||||
dputs(log);
|
||||
if(bp.singleshoot)
|
||||
bpdel(bp.addr, BPNORMAL);
|
||||
bptobridge(&bp, &pluginBp);
|
||||
@ -150,22 +138,62 @@ static void cbUserBreakpoint()
|
||||
static void cbHardwareBreakpoint(void* ExceptionAddress)
|
||||
{
|
||||
uint cip=GetContextData(UE_CIP);
|
||||
BREAKPOINT found;
|
||||
BREAKPOINT bp;
|
||||
BRIDGEBP pluginBp;
|
||||
PLUG_CB_BREAKPOINT bpInfo;
|
||||
bpInfo.breakpoint=0;
|
||||
if(!bpget((uint)ExceptionAddress, BPHARDWARE, 0, &found))
|
||||
if(!bpget((uint)ExceptionAddress, BPHARDWARE, 0, &bp))
|
||||
dputs("hardware breakpoint reached not in list!");
|
||||
else
|
||||
{
|
||||
//TODO: type
|
||||
char log[deflen]="";
|
||||
if(*found.name)
|
||||
sprintf(log, "hardware breakpoint \"%s\" "fhex"!", found.name, found.addr);
|
||||
const char* bpsize="";
|
||||
switch(bp.titantype&0xF) //size
|
||||
{
|
||||
case UE_HARDWARE_SIZE_1:
|
||||
bpsize="byte, ";
|
||||
break;
|
||||
case UE_HARDWARE_SIZE_2:
|
||||
bpsize="word, ";
|
||||
break;
|
||||
case UE_HARDWARE_SIZE_4:
|
||||
bpsize="dword, ";
|
||||
break;
|
||||
#ifdef _WIN64
|
||||
case UE_HARDWARE_SIZE_8:
|
||||
bpsize="qword, ";
|
||||
break;
|
||||
#endif //_WIN64
|
||||
}
|
||||
const char* bptype="";
|
||||
switch((bp.titantype>>4)&0xF) //type
|
||||
{
|
||||
case UE_HARDWARE_EXECUTE:
|
||||
bptype="execute";
|
||||
bpsize="";
|
||||
break;
|
||||
case UE_HARDWARE_READWRITE:
|
||||
bptype="read/write";
|
||||
break;
|
||||
case UE_HARDWARE_WRITE:
|
||||
bptype="write";
|
||||
break;
|
||||
}
|
||||
const char* symbolicname=symgetsymbolicname(bp.addr);
|
||||
if(symbolicname)
|
||||
{
|
||||
if(*bp.name)
|
||||
dprintf("hardware breakpoint (%s%s) \"%s\" at %s ("fhex")!\n", bpsize, bptype, bp.name, symbolicname, bp.addr);
|
||||
else
|
||||
dprintf("hardware breakpoint (%s%s) at %s ("fhex")!\n", bpsize, bptype, symbolicname, bp.addr);
|
||||
}
|
||||
else
|
||||
sprintf(log, "hardware breakpoint "fhex"!", found.addr);
|
||||
dputs(log);
|
||||
bptobridge(&found, &pluginBp);
|
||||
{
|
||||
if(*bp.name)
|
||||
dprintf("hardware breakpoint (%s%s) \"%s\" at "fhex"!\n", bpsize, bptype, bp.name, bp.addr);
|
||||
else
|
||||
dprintf("hardware breakpoint (%s%s) at "fhex"!\n", bpsize, bptype, bp.addr);
|
||||
}
|
||||
bptobridge(&bp, &pluginBp);
|
||||
bpInfo.breakpoint=&pluginBp;
|
||||
}
|
||||
DebugUpdateGui(cip, true);
|
||||
@ -185,26 +213,50 @@ static void cbMemoryBreakpoint(void* ExceptionAddress)
|
||||
uint cip=GetContextData(UE_CIP);
|
||||
uint size;
|
||||
uint base=memfindbaseaddr(fdProcessInfo->hProcess, (uint)ExceptionAddress, &size);
|
||||
BREAKPOINT found;
|
||||
BREAKPOINT bp;
|
||||
BRIDGEBP pluginBp;
|
||||
PLUG_CB_BREAKPOINT bpInfo;
|
||||
bpInfo.breakpoint=0;
|
||||
if(!bpget(base, BPMEMORY, 0, &found))
|
||||
if(!bpget(base, BPMEMORY, 0, &bp))
|
||||
dputs("memory breakpoint reached not in list!");
|
||||
else
|
||||
{
|
||||
//unsigned char type=cur->oldbytes&0xF;
|
||||
char log[50]="";
|
||||
if(*found.name)
|
||||
sprintf(log, "memory breakpoint \"%s\" on "fhex"!", found.name, found.addr);
|
||||
const char* bptype="";
|
||||
switch(bp.titantype)
|
||||
{
|
||||
case UE_MEMORY_READ:
|
||||
bptype=" (read)";
|
||||
break;
|
||||
case UE_MEMORY_WRITE:
|
||||
bptype=" (write)";
|
||||
break;
|
||||
case UE_MEMORY_EXECUTE:
|
||||
bptype=" (execute)";
|
||||
break;
|
||||
case UE_MEMORY:
|
||||
bptype=" (read/write/execute)";
|
||||
break;
|
||||
}
|
||||
const char* symbolicname=symgetsymbolicname(bp.addr);
|
||||
if(symbolicname)
|
||||
{
|
||||
if(*bp.name)
|
||||
dprintf("memory breakpoint%s \"%s\" at %s ("fhex", "fhex")!\n", bptype, bp.name, symbolicname, bp.addr, ExceptionAddress);
|
||||
else
|
||||
dprintf("memory breakpoint%s at %s ("fhex", "fhex")!\n", bptype, symbolicname, bp.addr, ExceptionAddress);
|
||||
}
|
||||
else
|
||||
sprintf(log, "memory breakpoint on "fhex"!", found.addr);
|
||||
dputs(log);
|
||||
bptobridge(&found, &pluginBp);
|
||||
{
|
||||
if(*bp.name)
|
||||
dprintf("memory breakpoint%s \"%s\" at "fhex" ("fhex")!\n", bptype, bp.name, bp.addr, ExceptionAddress);
|
||||
else
|
||||
dprintf("memory breakpoint%s at "fhex" ("fhex")!\n", bptype, bp.addr, ExceptionAddress);
|
||||
}
|
||||
bptobridge(&bp, &pluginBp);
|
||||
bpInfo.breakpoint=&pluginBp;
|
||||
}
|
||||
if(found.singleshoot)
|
||||
bpdel(found.addr, BPMEMORY); //delete from breakpoint list
|
||||
if(bp.singleshoot)
|
||||
bpdel(bp.addr, BPMEMORY); //delete from breakpoint list
|
||||
DebugUpdateGui(cip, true);
|
||||
GuiSetDebugState(paused);
|
||||
//lock
|
||||
@ -1743,4 +1795,4 @@ CMDRESULT cbDebugStackDump(int argc, char* argv[])
|
||||
}
|
||||
GuiStackDumpAt(addr, GetContextData(UE_CSP));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ static BOOL CALLBACK EnumSymbols(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void symbolenum(uint base, CBSYMBOLENUM cbSymbolEnum, void* user)
|
||||
void symenum(uint base, CBSYMBOLENUM cbSymbolEnum, void* user)
|
||||
{
|
||||
SYMBOLCBDATA symbolCbData;
|
||||
symbolCbData.cbSymbolEnum=cbSymbolEnum;
|
||||
@ -55,7 +55,7 @@ static BOOL CALLBACK EnumModules(PCTSTR ModuleName, ULONG BaseOfDll, PVOID UserC
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void symbolupdatemodulelist()
|
||||
void symupdatemodulelist()
|
||||
{
|
||||
std::vector<SYMBOLMODULEINFO> modList;
|
||||
modList.clear();
|
||||
@ -66,3 +66,52 @@ void symbolupdatemodulelist()
|
||||
memcpy(&modListBridge[i], &modList.at(i), sizeof(SYMBOLMODULEINFO));
|
||||
GuiSymbolUpdateModuleList(modcount, modListBridge);
|
||||
}
|
||||
|
||||
bool symfromname(const char* name, uint* addr)
|
||||
{
|
||||
if(!name or !strlen(name) or !addr)
|
||||
return false;
|
||||
char buffer[sizeof(SYMBOL_INFO) + MAX_LABEL_SIZE * sizeof(char)];
|
||||
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
|
||||
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
pSymbol->MaxNameLen = MAX_LABEL_SIZE;
|
||||
if(!SymFromName(fdProcessInfo->hProcess, name, pSymbol))
|
||||
return false;
|
||||
*addr=(uint)pSymbol->Address;
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* symgetsymbolicname(uint addr)
|
||||
{
|
||||
//[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
|
||||
{
|
||||
DWORD64 displacement=0;
|
||||
char buffer[sizeof(SYMBOL_INFO) + MAX_LABEL_SIZE * 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)
|
||||
{
|
||||
//TODO: user preference
|
||||
if(!UnDecorateSymbolName(pSymbol->Name, label, MAX_SYM_NAME, UNDNAME_COMPLETE))
|
||||
strcpy(label, pSymbol->Name);
|
||||
retval=true;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -3,7 +3,9 @@
|
||||
|
||||
#include "_global.h"
|
||||
|
||||
void symbolenum(uint base, CBSYMBOLENUM cbSymbolEnum, void* user);
|
||||
void symbolupdatemodulelist();
|
||||
void symenum(uint base, CBSYMBOLENUM cbSymbolEnum, void* user);
|
||||
void symupdatemodulelist();
|
||||
bool symfromname(const char* name, uint* addr);
|
||||
const char* symgetsymbolicname(uint addr);
|
||||
|
||||
#endif //_SYMBOLINFO_H
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "math.h"
|
||||
#include "memory.h"
|
||||
#include "addrinfo.h"
|
||||
#include "symbolinfo.h"
|
||||
#include <psapi.h>
|
||||
|
||||
static bool dosignedcalc=false;
|
||||
@ -995,8 +996,11 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
|
||||
apiname++;
|
||||
uint modbase=modbasefromname(modname);
|
||||
char szModName[MAX_PATH];
|
||||
if(!GetModuleFileNameEx(fdProcessInfo->hProcess, (HMODULE)modbase, szModName, MAX_PATH) and !silent)
|
||||
dprintf("could not get filename of module "fhex"\n", modbase);
|
||||
if(!GetModuleFileNameEx(fdProcessInfo->hProcess, (HMODULE)modbase, szModName, MAX_PATH))
|
||||
{
|
||||
if(!silent)
|
||||
dprintf("could not get filename of module "fhex"\n", modbase);
|
||||
}
|
||||
else
|
||||
{
|
||||
char szBaseName[256]="";
|
||||
@ -1005,8 +1009,11 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
|
||||
len--;
|
||||
strcpy(szBaseName, szModName+len+1);
|
||||
HMODULE mod=LoadLibraryExA(szModName, 0, DONT_RESOLVE_DLL_REFERENCES|LOAD_LIBRARY_AS_DATAFILE);
|
||||
if(!mod and !silent)
|
||||
dprintf("unable to load library %s\n", szBaseName);
|
||||
if(!mod)
|
||||
{
|
||||
if(!silent)
|
||||
dprintf("unable to load library %s\n", szBaseName);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint addr=(uint)GetProcAddress(mod, apiname);
|
||||
@ -1017,7 +1024,8 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
|
||||
*value_size=sizeof(uint);
|
||||
if(hexonly)
|
||||
*hexonly=true;
|
||||
*value=ImporterGetRemoteAPIAddressEx(szBaseName, (char*)apiname);
|
||||
uint rva=addr-(uint)mod;
|
||||
*value=modbase+rva;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1029,8 +1037,11 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
|
||||
for(unsigned int i=0; i<(cbNeeded/sizeof(HMODULE)); i++)
|
||||
{
|
||||
char szModName[MAX_PATH];
|
||||
if(!GetModuleFileNameEx(fdProcessInfo->hProcess, hMods[i], szModName, MAX_PATH) and !silent)
|
||||
dprintf("could not get filename of module "fhex"\n", hMods[i]);
|
||||
if(!GetModuleFileNameEx(fdProcessInfo->hProcess, hMods[i], szModName, MAX_PATH))
|
||||
{
|
||||
if(!silent)
|
||||
dprintf("could not get filename of module "fhex"\n", hMods[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
char szBaseName[256]="";
|
||||
@ -1039,8 +1050,11 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
|
||||
len--;
|
||||
strcpy(szBaseName, szModName+len+1);
|
||||
HMODULE mod=LoadLibraryExA(szModName, 0, DONT_RESOLVE_DLL_REFERENCES|LOAD_LIBRARY_AS_DATAFILE);
|
||||
if(!mod and !silent)
|
||||
dprintf("unable to load library %s\n", szBaseName);
|
||||
if(!mod)
|
||||
{
|
||||
if(!silent)
|
||||
dprintf("unable to load library %s\n", szBaseName);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint addr=(uint)GetProcAddress(mod, name);
|
||||
@ -1049,7 +1063,8 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
|
||||
{
|
||||
if(!_stricmp(szBaseName, "kernelbase") or !_stricmp(szBaseName, "kernelbase.dll"))
|
||||
kernelbase=found;
|
||||
addrfound[found]=ImporterGetRemoteAPIAddressEx(szBaseName, (char*)name);
|
||||
uint rva=addr-(uint)mod;
|
||||
addrfound[found]=(uint)hMods[i]+rva;
|
||||
found++;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user