mirror of
https://github.com/x64dbg/x64dbg.git
synced 2024-11-23 04:50:07 +00:00
fixed various bugs + added internal sqlite database for exports
This commit is contained in:
parent
c525e3397e
commit
d80b5cf1c3
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -3,6 +3,7 @@
|
||||
#include "debugger.h"
|
||||
#include "value.h"
|
||||
#include "addrinfo.h"
|
||||
#include "console.h"
|
||||
|
||||
extern "C" DLL_EXPORT duint _dbg_memfindbaseaddr(duint addr, duint* size)
|
||||
{
|
||||
@ -32,12 +33,8 @@ extern "C" DLL_EXPORT bool _dbg_memmap(MEMMAP* memmap)
|
||||
if(mbi.State==MEM_COMMIT)
|
||||
{
|
||||
MEMPAGE curPage;
|
||||
IMAGEHLP_MODULE64 nfo;
|
||||
nfo.SizeOfStruct=sizeof(IMAGEHLP_MODULE64);
|
||||
if(SymGetModuleInfo64(fdProcessInfo->hProcess, MyAddress, &nfo))
|
||||
memcpy(curPage.mod, nfo.ModuleName, sizeof(curPage.mod));
|
||||
else
|
||||
memset(curPage.mod, 0, sizeof(curPage.mod));
|
||||
*curPage.mod=0;
|
||||
modnamefromaddr(MyAddress, curPage.mod);
|
||||
memcpy(&curPage.mbi, &mbi, sizeof(mbi));
|
||||
pageVector.push_back(curPage);
|
||||
memmap->count++;
|
||||
@ -109,22 +106,62 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
|
||||
retval=true;
|
||||
}
|
||||
}
|
||||
if(addrinfo->flags&flaglabel) //TODO: get label
|
||||
if(addrinfo->flags&flaglabel)
|
||||
{
|
||||
if(labelget(addr, addrinfo->label))
|
||||
retval=true;
|
||||
else
|
||||
{
|
||||
//TODO: label exports
|
||||
//TODO: auto-labels
|
||||
/*const char* apiname=(const char*)ImporterGetAPINameFromDebugee(fdProcessInfo->hProcess, addr);
|
||||
if(apiname)
|
||||
{
|
||||
strcpy(addrinfo->label, apiname);
|
||||
retval=true;
|
||||
}
|
||||
uint addr_dw=0;
|
||||
if(memread(fdProcessInfo->hProcess, (const void*)addr, &addr_dw, sizeof(uint), 0))
|
||||
{
|
||||
const char* apiname=(const char*)ImporterGetAPINameFromDebugee(fdProcessInfo->hProcess, addr_dw);
|
||||
if(apiname)
|
||||
{
|
||||
strcpy(addrinfo->label, apiname);
|
||||
retval=true;
|
||||
}
|
||||
}*/
|
||||
if(!retval)
|
||||
{
|
||||
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)
|
||||
{
|
||||
strcpy(addrinfo->label, pSymbol->Name);
|
||||
retval=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(addrinfo->flags&flagcomment) //TODO: get comment
|
||||
if(addrinfo->flags&flagcomment)
|
||||
{
|
||||
if(commentget(addr, addrinfo->comment))
|
||||
retval=true;
|
||||
//TODO: auto-comments
|
||||
else
|
||||
{
|
||||
//TODO: auto-comments
|
||||
if(!retval)
|
||||
{
|
||||
DWORD dwDisplacement;
|
||||
IMAGEHLP_LINE64 line;
|
||||
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
||||
if(SymGetLineFromAddr64(fdProcessInfo->hProcess, (DWORD64)addr, &dwDisplacement, &line) and !dwDisplacement)
|
||||
{
|
||||
sprintf(addrinfo->comment, "line: %u", line.LineNumber);
|
||||
retval=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
|
@ -4,9 +4,12 @@
|
||||
#include "memory.h"
|
||||
|
||||
static sqlite3* db;
|
||||
static sqlite3* internaldb;
|
||||
|
||||
///basic database functions
|
||||
void dbinit()
|
||||
{
|
||||
//initialize user database
|
||||
if(sqlite3_open(":memory:", &db))
|
||||
{
|
||||
dputs("failed to open database!");
|
||||
@ -27,6 +30,18 @@ void dbinit()
|
||||
dprintf("SQL Error: %s\n", errorText);
|
||||
sqlite3_free(errorText);
|
||||
}
|
||||
//initialize internal database
|
||||
if(sqlite3_open(":memory:", &internaldb))
|
||||
{
|
||||
dputs("failed to open database!");
|
||||
return;
|
||||
}
|
||||
strcpy(sql, "CREATE TABLE IF NOT EXISTS exports (id INTEGER PRIMARY KEY AUTOINCREMENT, base INT64 NOT NULL, mod TEXT, name TEXT NOT NULL, addr INT64 NOT NULL)");
|
||||
if(sqlite3_exec(internaldb, sql, 0, 0, &errorText)!=SQLITE_OK) //error
|
||||
{
|
||||
dprintf("SQL Error: %s\n", errorText);
|
||||
sqlite3_free(errorText);
|
||||
}
|
||||
}
|
||||
|
||||
static int loadOrSaveDb(sqlite3* memory, const char* file, bool save)
|
||||
@ -63,6 +78,9 @@ bool dbload()
|
||||
|
||||
bool dbsave()
|
||||
{
|
||||
DeleteFileA("internal.db");
|
||||
loadOrSaveDb(internaldb, "internal.db", true);
|
||||
|
||||
CreateDirectoryA(sqlitedb_basedir, 0); //create database directory
|
||||
if(loadOrSaveDb(db, dbpath, true)!=SQLITE_OK)
|
||||
return false;
|
||||
@ -72,31 +90,160 @@ bool dbsave()
|
||||
void dbclose()
|
||||
{
|
||||
dbsave();
|
||||
sqlite3_close(db);
|
||||
sqlite3_close(db); //close program database
|
||||
sqlite3_close(internaldb); //close internal database
|
||||
}
|
||||
|
||||
///module functions
|
||||
|
||||
static std::vector<MODINFO> modinfo;
|
||||
|
||||
bool modnamefromaddr(uint addr, char* modname)
|
||||
{
|
||||
IMAGEHLP_MODULE64 modInfo;
|
||||
memset(&modInfo, 0, sizeof(modInfo));
|
||||
modInfo.SizeOfStruct=sizeof(IMAGEHLP_MODULE64);
|
||||
if(!SymGetModuleInfo64(fdProcessInfo->hProcess, (DWORD64)addr, &modInfo) or !modname)
|
||||
return false;
|
||||
_strlwr(modInfo.ModuleName);
|
||||
strcpy(modname, modInfo.ModuleName);
|
||||
return true;
|
||||
int total=modinfo.size();
|
||||
for(int i=0; i<total; i++)
|
||||
{
|
||||
if(addr>=modinfo.at(i).start and addr<modinfo.at(i).end)
|
||||
{
|
||||
strcpy(modname, modinfo.at(i).name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint modbasefromaddr(uint addr)
|
||||
{
|
||||
IMAGEHLP_MODULE64 modInfo;
|
||||
memset(&modInfo, 0, sizeof(modInfo));
|
||||
modInfo.SizeOfStruct=sizeof(IMAGEHLP_MODULE64);
|
||||
if(!SymGetModuleInfo64(fdProcessInfo->hProcess, (DWORD64)addr, &modInfo))
|
||||
return 0;
|
||||
return (uint)modInfo.BaseOfImage;
|
||||
int total=modinfo.size();
|
||||
for(int i=0; i<total; i++)
|
||||
{
|
||||
if(addr>=modinfo.at(i).start and addr<modinfo.at(i).end)
|
||||
{
|
||||
return modinfo.at(i).start;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cbExport(uint base, const char* mod, const char* name, uint addr)
|
||||
{
|
||||
char sql[deflen]="";
|
||||
sprintf(sql, "INSERT INTO exports (base,mod,name,addr) VALUES (%"fext"d,'%s','%s',%"fext"d)", base, mod, name, addr);
|
||||
char* errorText=0;
|
||||
if(sqlite3_exec(internaldb, sql, 0, 0, &errorText)!=SQLITE_OK) //error
|
||||
{
|
||||
dprintf("SQL Error: %s\n", errorText);
|
||||
sqlite3_free(errorText);
|
||||
}
|
||||
}
|
||||
|
||||
bool modload(uint base, uint size, const char* name)
|
||||
{
|
||||
if(!base or !size or !name or strlen(name)>=31)
|
||||
return false;
|
||||
MODINFO info;
|
||||
info.start=base;
|
||||
info.end=base+size;
|
||||
strcpy(info.name, name);
|
||||
_strlwr(info.name);
|
||||
modinfo.push_back(info);
|
||||
apienumexports(base, cbExport);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool modunload(uint base)
|
||||
{
|
||||
if(!base)
|
||||
return false;
|
||||
int total=modinfo.size();
|
||||
for(int i=0; i<total; i++)
|
||||
{
|
||||
if(modinfo.at(i).start==base)
|
||||
{
|
||||
modinfo.erase(modinfo.begin()+i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///api functions
|
||||
bool apienumexports(uint base, EXPORTENUMCALLBACK cbEnum)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
VirtualQueryEx(fdProcessInfo->hProcess, (const void*)base, &mbi, sizeof(mbi));
|
||||
uint size=mbi.RegionSize;
|
||||
void* buffer=emalloc(size);
|
||||
if(!memread(fdProcessInfo->hProcess, (const void*)base, buffer, size, 0))
|
||||
{
|
||||
efree(buffer);
|
||||
return false;
|
||||
}
|
||||
IMAGE_NT_HEADERS* pnth=(IMAGE_NT_HEADERS*)((uint)buffer+GetPE32DataFromMappedFile((ULONG_PTR)buffer, 0, UE_PE_OFFSET));
|
||||
uint export_dir_rva=pnth->OptionalHeader.DataDirectory[0].VirtualAddress;
|
||||
uint export_dir_size=pnth->OptionalHeader.DataDirectory[0].Size;
|
||||
efree(buffer);
|
||||
IMAGE_EXPORT_DIRECTORY export_dir;
|
||||
memset(&export_dir, 0, sizeof(export_dir));
|
||||
memread(fdProcessInfo->hProcess, (const void*)(export_dir_rva+base), &export_dir, sizeof(export_dir), 0);
|
||||
unsigned int NumberOfNames=export_dir.NumberOfNames;
|
||||
if(!export_dir.NumberOfFunctions or !NumberOfNames) //no named exports
|
||||
return false;
|
||||
char modname[256]="";
|
||||
modnamefromaddr(base, modname);
|
||||
uint original_name_va=export_dir.Name+base;
|
||||
char original_name[deflen]="";
|
||||
memset(original_name, 0, sizeof(original_name));
|
||||
memread(fdProcessInfo->hProcess, (const void*)original_name_va, original_name, deflen, 0);
|
||||
char* AddrOfFunctions_va=(char*)(export_dir.AddressOfFunctions+base);
|
||||
char* AddrOfNames_va=(char*)(export_dir.AddressOfNames+base);
|
||||
char* AddrOfNameOrdinals_va=(char*)(export_dir.AddressOfNameOrdinals+base);
|
||||
for(DWORD i=0; i<NumberOfNames; i++)
|
||||
{
|
||||
DWORD curAddrOfName=0;
|
||||
memread(fdProcessInfo->hProcess, AddrOfNames_va+sizeof(DWORD)*i, &curAddrOfName, sizeof(DWORD), 0);
|
||||
char* cur_name_va=(char*)(curAddrOfName+base);
|
||||
char cur_name[deflen]="";
|
||||
memset(cur_name, 0, deflen);
|
||||
memread(fdProcessInfo->hProcess, cur_name_va, cur_name, deflen, 0);
|
||||
WORD curAddrOfNameOrdinals=0;
|
||||
memread(fdProcessInfo->hProcess, AddrOfNameOrdinals_va+sizeof(WORD)*i, &curAddrOfNameOrdinals, sizeof(WORD), 0);
|
||||
DWORD curFunctionRva=0;
|
||||
memread(fdProcessInfo->hProcess, AddrOfFunctions_va+sizeof(DWORD)*curAddrOfNameOrdinals, &curFunctionRva, sizeof(DWORD), 0);
|
||||
|
||||
if(curFunctionRva>=export_dir_rva and curFunctionRva<export_dir_rva+export_dir_size)
|
||||
{
|
||||
char forwarded_api[deflen]="";
|
||||
memset(forwarded_api, 0, deflen);
|
||||
memread(fdProcessInfo->hProcess, (void*)(curFunctionRva+base), forwarded_api, deflen, 0);
|
||||
int len=strlen(forwarded_api);
|
||||
int j=0;
|
||||
while(forwarded_api[j]!='.' and j<len)
|
||||
j++;
|
||||
if(forwarded_api[j]=='.')
|
||||
{
|
||||
forwarded_api[j]=0;
|
||||
HINSTANCE hTempDll=LoadLibraryExA(forwarded_api, 0, DONT_RESOLVE_DLL_REFERENCES|LOAD_LIBRARY_AS_DATAFILE);
|
||||
if(hTempDll)
|
||||
{
|
||||
uint local_addr=(uint)GetProcAddress(hTempDll, forwarded_api+j+1);
|
||||
if(local_addr)
|
||||
{
|
||||
uint remote_addr=ImporterGetRemoteAPIAddress(fdProcessInfo->hProcess, local_addr);
|
||||
cbEnum(base, modname, cur_name, remote_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cbEnum(base, modname, cur_name, curFunctionRva+base);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
///comment functions
|
||||
bool commentset(uint addr, const char* text)
|
||||
{
|
||||
if(!IsFileBeingDebugged() or !memisvalidreadptr(fdProcessInfo->hProcess, addr) or !text or strlen(text)>=MAX_COMMENT_SIZE-1)
|
||||
@ -118,29 +265,33 @@ bool commentset(uint addr, const char* text)
|
||||
sqlite3_stmt* stmt;
|
||||
if(!modnamefromaddr(addr, modname)) //comments without module
|
||||
{
|
||||
sprintf(sql, "SELECT text FROM comments WHERE mod IS NULL AND addr=%"fext"u", addr);
|
||||
sprintf(sql, "SELECT text FROM comments WHERE mod IS NULL AND addr=%"fext"d", addr);
|
||||
if(sqlite3_prepare_v2(db, sql, -1, &stmt, 0)!=SQLITE_OK)
|
||||
{
|
||||
sqlite3_finalize(stmt);
|
||||
efree(newtext);
|
||||
return false;
|
||||
}
|
||||
if(sqlite3_step(stmt)==SQLITE_ROW) //there is a comment already
|
||||
sprintf(sql, "UPDATE comments SET text='%s' WHERE mod IS NULL AND addr=%"fext"u", newtext, addr);
|
||||
sprintf(sql, "UPDATE comments SET text='%s' WHERE mod IS NULL AND addr=%"fext"d", newtext, addr);
|
||||
else //insert
|
||||
sprintf(sql, "INSERT INTO comments (addr,text) VALUES (%"fext"u,'%s')", addr, newtext);
|
||||
sprintf(sql, "INSERT INTO comments (addr,text) VALUES (%"fext"d,'%s')", addr, newtext);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint modbase=modbasefromaddr(addr);
|
||||
uint rva=addr-modbase;
|
||||
sprintf(sql, "SELECT text FROM comments WHERE mod='%s' AND addr=%"fext"u", modname, rva);
|
||||
sprintf(sql, "SELECT text FROM comments WHERE mod='%s' AND addr=%"fext"d", modname, rva);
|
||||
if(sqlite3_prepare_v2(db, sql, -1, &stmt, 0)!=SQLITE_OK)
|
||||
{
|
||||
sqlite3_finalize(stmt);
|
||||
efree(newtext);
|
||||
return false;
|
||||
}
|
||||
if(sqlite3_step(stmt)==SQLITE_ROW) //there is a comment already
|
||||
sprintf(sql, "UPDATE comments SET text='%s' WHERE mod='%s' AND addr=%"fext"u", newtext, modname, rva);
|
||||
sprintf(sql, "UPDATE comments SET text='%s' WHERE mod='%s' AND addr=%"fext"d", newtext, modname, rva);
|
||||
else //insert
|
||||
sprintf(sql, "INSERT INTO comments (mod,addr,text) VALUES ('%s',%"fext"u,'%s')", modname, rva, newtext);
|
||||
sprintf(sql, "INSERT INTO comments (mod,addr,text) VALUES ('%s',%"fext"d,'%s')", modname, rva, newtext);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
efree(newtext);
|
||||
@ -164,15 +315,17 @@ bool commentget(uint addr, char* text)
|
||||
char sql[256]="";
|
||||
sqlite3_stmt* stmt;
|
||||
if(!modnamefromaddr(addr, modname)) //comments without module
|
||||
sprintf(sql, "SELECT text FROM comments WHERE mod IS NULL AND addr=%"fext"u", addr);
|
||||
sprintf(sql, "SELECT text FROM comments WHERE mod IS NULL AND addr=%"fext"d", addr);
|
||||
else
|
||||
sprintf(sql, "SELECT text FROM comments WHERE mod='%s' AND addr=%"fext"u", modname, addr-modbasefromaddr(addr));
|
||||
sprintf(sql, "SELECT text FROM comments WHERE mod='%s' AND addr=%"fext"d", modname, addr-modbasefromaddr(addr));
|
||||
if(sqlite3_prepare_v2(db, sql, -1, &stmt, 0)!=SQLITE_OK)
|
||||
{
|
||||
sqlite3_finalize(stmt);
|
||||
return false;
|
||||
}
|
||||
if(sqlite3_step(stmt)!=SQLITE_ROW) //there is a comment already
|
||||
{
|
||||
sqlite3_finalize(stmt);
|
||||
return false;
|
||||
}
|
||||
strcpy(text, (const char*)sqlite3_column_text(stmt, 0));
|
||||
@ -188,19 +341,23 @@ bool commentdel(uint addr)
|
||||
char sql[256]="";
|
||||
sqlite3_stmt* stmt;
|
||||
if(!modnamefromaddr(addr, modname)) //comments without module
|
||||
sprintf(sql, "SELECT id FROM comments WHERE mod IS NULL AND addr=%"fext"u", addr);
|
||||
sprintf(sql, "SELECT id FROM comments WHERE mod IS NULL AND addr=%"fext"d", addr);
|
||||
else
|
||||
{
|
||||
uint modbase=modbasefromaddr(addr);
|
||||
uint rva=addr-modbase;
|
||||
sprintf(sql, "SELECT id FROM comments WHERE mod='%s' AND addr=%"fext"u", modname, rva);
|
||||
sprintf(sql, "SELECT id FROM comments WHERE mod='%s' AND addr=%"fext"d", modname, rva);
|
||||
}
|
||||
if(sqlite3_prepare_v2(db, sql, -1, &stmt, 0)!=SQLITE_OK)
|
||||
{
|
||||
sqlite3_finalize(stmt);
|
||||
return false;
|
||||
}
|
||||
if(sqlite3_step(stmt)!=SQLITE_ROW) //no comment to delete
|
||||
{
|
||||
sqlite3_finalize(stmt);
|
||||
return false;
|
||||
}
|
||||
int del_id=sqlite3_column_int(stmt, 0);
|
||||
sqlite3_finalize(stmt);
|
||||
char* errorText=0;
|
||||
@ -216,6 +373,7 @@ bool commentdel(uint addr)
|
||||
return true;
|
||||
}
|
||||
|
||||
///label functions
|
||||
bool labelset(uint addr, const char* text)
|
||||
{
|
||||
if(!IsFileBeingDebugged() or !memisvalidreadptr(fdProcessInfo->hProcess, addr) or !text or strlen(text)>=MAX_LABEL_SIZE-1)
|
||||
@ -237,29 +395,31 @@ bool labelset(uint addr, const char* text)
|
||||
sqlite3_stmt* stmt;
|
||||
if(!modnamefromaddr(addr, modname)) //labels without module
|
||||
{
|
||||
sprintf(sql, "SELECT text FROM labels WHERE mod IS NULL AND addr=%"fext"u", addr);
|
||||
sprintf(sql, "SELECT text FROM labels WHERE mod IS NULL AND addr=%"fext"d", addr);
|
||||
if(sqlite3_prepare_v2(db, sql, -1, &stmt, 0)!=SQLITE_OK)
|
||||
{
|
||||
sqlite3_finalize(stmt);
|
||||
return false;
|
||||
}
|
||||
if(sqlite3_step(stmt)==SQLITE_ROW) //there is a label already
|
||||
sprintf(sql, "UPDATE labels SET text='%s' WHERE mod IS NULL AND addr=%"fext"u", newtext, addr);
|
||||
sprintf(sql, "UPDATE labels SET text='%s' WHERE mod IS NULL AND addr=%"fext"d", newtext, addr);
|
||||
else //insert
|
||||
sprintf(sql, "INSERT INTO labels (addr,text) VALUES (%"fext"u,'%s')", addr, newtext);
|
||||
sprintf(sql, "INSERT INTO labels (addr,text) VALUES (%"fext"d,'%s')", addr, newtext);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint modbase=modbasefromaddr(addr);
|
||||
uint rva=addr-modbase;
|
||||
sprintf(sql, "SELECT text FROM labels WHERE mod='%s' AND addr=%"fext"u", modname, rva);
|
||||
sprintf(sql, "SELECT text FROM labels WHERE mod='%s' AND addr=%"fext"d", modname, rva);
|
||||
if(sqlite3_prepare_v2(db, sql, -1, &stmt, 0)!=SQLITE_OK)
|
||||
{
|
||||
sqlite3_finalize(stmt);
|
||||
return false;
|
||||
}
|
||||
if(sqlite3_step(stmt)==SQLITE_ROW) //there is a label already
|
||||
sprintf(sql, "UPDATE labels SET text='%s' WHERE mod='%s' AND addr=%"fext"u", newtext, modname, rva);
|
||||
sprintf(sql, "UPDATE labels SET text='%s' WHERE mod='%s' AND addr=%"fext"d", newtext, modname, rva);
|
||||
else //insert
|
||||
sprintf(sql, "INSERT INTO labels (mod,addr,text) VALUES ('%s',%"fext"u,'%s')", modname, rva, newtext);
|
||||
sprintf(sql, "INSERT INTO labels (mod,addr,text) VALUES ('%s',%"fext"d,'%s')", modname, rva, newtext);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
efree(newtext);
|
||||
@ -283,15 +443,17 @@ bool labelget(uint addr, char* text)
|
||||
char sql[256]="";
|
||||
sqlite3_stmt* stmt;
|
||||
if(!modnamefromaddr(addr, modname)) //labels without module
|
||||
sprintf(sql, "SELECT text FROM labels WHERE mod IS NULL AND addr=%"fext"u", addr);
|
||||
sprintf(sql, "SELECT text FROM labels WHERE mod IS NULL AND addr=%"fext"d", addr);
|
||||
else
|
||||
sprintf(sql, "SELECT text FROM labels WHERE mod='%s' AND addr=%"fext"u", modname, addr-modbasefromaddr(addr));
|
||||
sprintf(sql, "SELECT text FROM labels WHERE mod='%s' AND addr=%"fext"d", modname, addr-modbasefromaddr(addr));
|
||||
if(sqlite3_prepare_v2(db, sql, -1, &stmt, 0)!=SQLITE_OK)
|
||||
{
|
||||
sqlite3_finalize(stmt);
|
||||
return false;
|
||||
}
|
||||
if(sqlite3_step(stmt)!=SQLITE_ROW) //there is a label already
|
||||
{
|
||||
sqlite3_finalize(stmt);
|
||||
return false;
|
||||
}
|
||||
strcpy(text, (const char*)sqlite3_column_text(stmt, 0));
|
||||
@ -307,19 +469,23 @@ bool labeldel(uint addr)
|
||||
char sql[256]="";
|
||||
sqlite3_stmt* stmt;
|
||||
if(!modnamefromaddr(addr, modname)) //labels without module
|
||||
sprintf(sql, "SELECT id FROM labels WHERE mod IS NULL AND addr=%"fext"u", addr);
|
||||
sprintf(sql, "SELECT id FROM labels WHERE mod IS NULL AND addr=%"fext"d", addr);
|
||||
else
|
||||
{
|
||||
uint modbase=modbasefromaddr(addr);
|
||||
uint rva=addr-modbase;
|
||||
sprintf(sql, "SELECT id FROM labels WHERE mod='%s' AND addr=%"fext"u", modname, rva);
|
||||
sprintf(sql, "SELECT id FROM labels WHERE mod='%s' AND addr=%"fext"d", modname, rva);
|
||||
}
|
||||
if(sqlite3_prepare_v2(db, sql, -1, &stmt, 0)!=SQLITE_OK)
|
||||
{
|
||||
sqlite3_finalize(stmt);
|
||||
return false;
|
||||
}
|
||||
if(sqlite3_step(stmt)!=SQLITE_ROW) //no label to delete
|
||||
{
|
||||
sqlite3_finalize(stmt);
|
||||
return false;
|
||||
}
|
||||
int del_id=sqlite3_column_int(stmt, 0);
|
||||
sqlite3_finalize(stmt);
|
||||
char* errorText=0;
|
||||
|
@ -3,11 +3,26 @@
|
||||
|
||||
#include "_global.h"
|
||||
|
||||
//typedefs
|
||||
typedef void (*EXPORTENUMCALLBACK)(uint base, const char* mod, const char* name, uint addr);
|
||||
|
||||
//structures
|
||||
struct MODINFO
|
||||
{
|
||||
uint start;
|
||||
uint end;
|
||||
char name[32];
|
||||
};
|
||||
|
||||
void dbinit();
|
||||
bool dbsave();
|
||||
bool dbload();
|
||||
void dbclose();
|
||||
bool modnamefromaddr(uint addr, char* modname);
|
||||
uint modbasefromaddr(uint addr);
|
||||
bool modload(uint base, uint size, const char* name);
|
||||
bool modunload(uint base);
|
||||
bool apienumexports(uint base, EXPORTENUMCALLBACK cbEnum);
|
||||
bool commentset(uint addr, const char* text);
|
||||
bool commentget(uint addr, char* text);
|
||||
bool commentdel(uint addr);
|
||||
|
@ -223,6 +223,38 @@ static void cbException(void* ExceptionData)
|
||||
wait(WAITID_RUN);
|
||||
}
|
||||
|
||||
BOOL
|
||||
CALLBACK
|
||||
SymRegisterCallbackProc64(
|
||||
__in HANDLE hProcess,
|
||||
__in ULONG ActionCode,
|
||||
__in_opt ULONG64 CallbackData,
|
||||
__in_opt ULONG64 UserContext
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(hProcess);
|
||||
UNREFERENCED_PARAMETER(UserContext);
|
||||
|
||||
PIMAGEHLP_CBA_EVENT evt;
|
||||
|
||||
// If SYMOPT_DEBUG is set, then the symbol handler will pass
|
||||
// verbose information on its attempt to load symbols.
|
||||
// This information be delivered as text strings.
|
||||
|
||||
switch (ActionCode)
|
||||
{
|
||||
case CBA_EVENT:
|
||||
evt = (PIMAGEHLP_CBA_EVENT)CallbackData;
|
||||
printf("%s", (PTSTR)evt->desc);
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
|
||||
{
|
||||
void* base=LoadDll->lpBaseOfDll;
|
||||
@ -233,6 +265,11 @@ static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
|
||||
DevicePathToPath(DLLDebugFileName, DLLDebugFileName, deflen);
|
||||
dprintf("DLL Loaded: "fhex" %s\n", base, DLLDebugFileName);
|
||||
SymLoadModuleEx(fdProcessInfo->hProcess, LoadDll->hFile, DLLDebugFileName, 0, (DWORD64)base, 0, 0, 0);
|
||||
IMAGEHLP_MODULE64 modInfo;
|
||||
memset(&modInfo, 0, sizeof(modInfo));
|
||||
modInfo.SizeOfStruct=sizeof(IMAGEHLP_MODULE64);
|
||||
if(SymGetModuleInfo64(fdProcessInfo->hProcess, (DWORD64)base, &modInfo))
|
||||
modload(modInfo.BaseOfImage, modInfo.ImageSize, modInfo.ModuleName);
|
||||
}
|
||||
|
||||
static void cbUnloadDll(UNLOAD_DLL_DEBUG_INFO* UnloadDll)
|
||||
@ -245,6 +282,7 @@ static void cbUnloadDll(UNLOAD_DLL_DEBUG_INFO* UnloadDll)
|
||||
DevicePathToPath(DLLDebugFileName, DLLDebugFileName, deflen);
|
||||
dprintf("DLL Unloaded: "fhex" %s\n", base, DLLDebugFileName);
|
||||
SymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)base);
|
||||
modunload((uint)base);
|
||||
}
|
||||
|
||||
static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
|
||||
@ -257,14 +295,6 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
|
||||
DevicePathToPath(DebugFileName, DebugFileName, deflen);
|
||||
dprintf("Process Started: "fhex" %s\n", base, DebugFileName);
|
||||
|
||||
SymInitialize(fdProcessInfo->hProcess, 0, false); //initialize symbols
|
||||
SymLoadModuleEx(fdProcessInfo->hProcess, CreateProcessInfo->hFile, DebugFileName, 0, (DWORD64)base, 0, 0, 0);
|
||||
}
|
||||
|
||||
static void cbSystemBreakpoint(void* ExceptionData)
|
||||
{
|
||||
//TODO: handle stuff (TLS, main entry, etc)
|
||||
SetCustomHandler(UE_CH_SYSTEMBREAKPOINT, 0);
|
||||
//init program database
|
||||
int len=strlen(szFileName);
|
||||
while(szFileName[len]!='\\' && len!=0)
|
||||
@ -280,6 +310,23 @@ static void cbSystemBreakpoint(void* ExceptionData)
|
||||
sprintf(dbpath, "%s\\%s", sqlitedb_basedir, sqlitedb);
|
||||
dprintf("Database file: %s\n", dbpath);
|
||||
dbinit();
|
||||
|
||||
//SymSetOptions(SYMOPT_DEBUG|SYMOPT_LOAD_LINES);
|
||||
SymInitialize(fdProcessInfo->hProcess, 0, false); //initialize symbols
|
||||
//SymRegisterCallback64(fdProcessInfo->hProcess, SymRegisterCallbackProc64, 0);
|
||||
SymLoadModuleEx(fdProcessInfo->hProcess, CreateProcessInfo->hFile, DebugFileName, 0, (DWORD64)base, 0, 0, 0);
|
||||
|
||||
IMAGEHLP_MODULE64 modInfo;
|
||||
memset(&modInfo, 0, sizeof(modInfo));
|
||||
modInfo.SizeOfStruct=sizeof(IMAGEHLP_MODULE64);
|
||||
if(SymGetModuleInfo64(fdProcessInfo->hProcess, (DWORD64)base, &modInfo))
|
||||
modload(modInfo.BaseOfImage, modInfo.ImageSize, modInfo.ModuleName);
|
||||
}
|
||||
|
||||
static void cbSystemBreakpoint(void* ExceptionData)
|
||||
{
|
||||
//TODO: handle stuff (TLS, main entry, etc)
|
||||
SetCustomHandler(UE_CH_SYSTEMBREAKPOINT, 0);
|
||||
//log message
|
||||
dputs("system breakpoint reached!");
|
||||
//update GUI
|
||||
@ -1104,13 +1151,11 @@ CMDRESULT cbBenchmark(const char* cmd)
|
||||
if(!valfromstring(arg1, &addr, 0, 0, false, 0))
|
||||
return STATUS_ERROR;
|
||||
uint ticks=GetTickCount();
|
||||
char comment[MAX_COMMENT_SIZE]="";
|
||||
commentset(addr, "benchmark");
|
||||
for(int i=0; i<1000; i++)
|
||||
for(int i=0; i<100000; i++)
|
||||
{
|
||||
char comment[MAX_COMMENT_SIZE]="";
|
||||
commentget(addr, comment);
|
||||
unsigned char dest[0x1000];
|
||||
_dbg_memread(addr, dest, 0x1000, 0);
|
||||
}
|
||||
commentdel(addr);
|
||||
dprintf("%ums\n", GetTickCount()-ticks);
|
||||
|
@ -26,9 +26,23 @@ uint memfindbaseaddr(HANDLE hProcess, uint addr, uint* size)
|
||||
|
||||
bool memread(HANDLE hProcess, const void* lpBaseAddress, void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead)
|
||||
{
|
||||
//TODO: there are bugs in this function
|
||||
if(!hProcess or !lpBaseAddress or !lpBuffer or !nSize)
|
||||
return false;
|
||||
|
||||
SIZE_T read1=0;
|
||||
DWORD oldprotect=0;
|
||||
VirtualProtectEx(hProcess, (void*)lpBaseAddress, nSize, PAGE_EXECUTE_READWRITE, &oldprotect);
|
||||
bool test=ReadProcessMemory(hProcess, (void*)lpBaseAddress, lpBuffer, nSize, &read1);
|
||||
VirtualProtectEx(hProcess, (void*)lpBaseAddress, nSize, oldprotect, &oldprotect);
|
||||
if(test and read1==nSize)
|
||||
{
|
||||
if(lpNumberOfBytesRead)
|
||||
*lpNumberOfBytesRead=read1;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint addr=(uint)lpBaseAddress;
|
||||
uint startRva=addr&(PAGE_SIZE-1); //get start rva
|
||||
uint addrStart=addr-startRva; //round down one page
|
||||
@ -44,7 +58,6 @@ bool memread(HANDLE hProcess, const void* lpBaseAddress, void* lpBuffer, SIZE_T
|
||||
bool ret=ReadProcessMemory(hProcess, curAddr, curPage, PAGE_SIZE, &readBytes);
|
||||
if(!ret or readBytes!=PAGE_SIZE)
|
||||
{
|
||||
DWORD oldprotect=0;
|
||||
VirtualProtectEx(hProcess, curAddr, PAGE_SIZE, PAGE_EXECUTE_READWRITE, &oldprotect);
|
||||
ret=ReadProcessMemory(hProcess, curAddr, curPage, PAGE_SIZE, &readBytes);
|
||||
VirtualProtectEx(hProcess, curAddr, PAGE_SIZE, oldprotect, &oldprotect);
|
||||
|
@ -117,7 +117,13 @@ QString Disassembly::paintContent(QPainter* painter, int_t rowBase, int rowOffse
|
||||
int_t cur_addr=mInstBuffer.at(rowOffset).rva+mMemPage->getBase();
|
||||
QString addrText=QString("%1").arg(cur_addr, sizeof(int_t)*2, 16, QChar('0')).toUpper();
|
||||
if(DbgGetLabelAt(cur_addr, SEG_DEFAULT, label)) //has label
|
||||
addrText+=" <"+QString(label)+">";
|
||||
{
|
||||
char module[MAX_LABEL_SIZE]="";
|
||||
if(DbgGetModuleAt(cur_addr, module))
|
||||
addrText+=" <"+QString(module)+"."+QString(label)+">";
|
||||
else
|
||||
addrText+=" <"+QString(label)+">";
|
||||
}
|
||||
else
|
||||
*label=0;
|
||||
BPXTYPE bpxtype=DbgGetBpxTypeAt(cur_addr);
|
||||
|
@ -39,13 +39,13 @@ void HexDump::printDumpAt(int_t parVA)
|
||||
|
||||
void HexDump::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
qDebug() << "HexDump::mouseMoveEvent";
|
||||
//qDebug() << "HexDump::mouseMoveEvent";
|
||||
|
||||
bool wAccept = true;
|
||||
|
||||
if(mGuiState == HexDump::MultiRowsSelectionState)
|
||||
{
|
||||
qDebug() << "State = MultiRowsSelectionState";
|
||||
//qDebug() << "State = MultiRowsSelectionState";
|
||||
|
||||
if((transY(event->y()) >= 0) && (transY(event->y()) <= this->getTableHeigth()))
|
||||
{
|
||||
@ -70,7 +70,7 @@ void HexDump::mouseMoveEvent(QMouseEvent* event)
|
||||
|
||||
void HexDump::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
qDebug() << "HexDump::mousePressEvent";
|
||||
//qDebug() << "HexDump::mousePressEvent";
|
||||
|
||||
bool wAccept = false;
|
||||
|
||||
|
@ -87,6 +87,8 @@ bool BeaHighlight::PrintArgument(QList<CustomRichText_t>* richText, const ARGTYP
|
||||
|
||||
//labels
|
||||
uint_t label_addr=Argument->Memory.Displacement;
|
||||
if(Argument->ArgType&RELATIVE_) //rip-relative
|
||||
label_addr=Instruction->AddrValue;
|
||||
char label_text[MAX_LABEL_SIZE]="";
|
||||
if(DbgGetLabelAt(label_addr, ConvertBeaSeg(segmentReg), label_text))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user