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:
Mr. eXoDia 2014-03-10 21:49:08 +01:00
parent accc3ff1c1
commit 584042455f
7 changed files with 176 additions and 74 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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