fixed various bugs + added internal sqlite database for exports

This commit is contained in:
mr.exodia 2013-11-17 02:43:50 +01:00
parent c525e3397e
commit d80b5cf1c3
12 changed files with 346 additions and 62 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -3,6 +3,7 @@
#include "debugger.h" #include "debugger.h"
#include "value.h" #include "value.h"
#include "addrinfo.h" #include "addrinfo.h"
#include "console.h"
extern "C" DLL_EXPORT duint _dbg_memfindbaseaddr(duint addr, duint* size) 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) if(mbi.State==MEM_COMMIT)
{ {
MEMPAGE curPage; MEMPAGE curPage;
IMAGEHLP_MODULE64 nfo; *curPage.mod=0;
nfo.SizeOfStruct=sizeof(IMAGEHLP_MODULE64); modnamefromaddr(MyAddress, curPage.mod);
if(SymGetModuleInfo64(fdProcessInfo->hProcess, MyAddress, &nfo))
memcpy(curPage.mod, nfo.ModuleName, sizeof(curPage.mod));
else
memset(curPage.mod, 0, sizeof(curPage.mod));
memcpy(&curPage.mbi, &mbi, sizeof(mbi)); memcpy(&curPage.mbi, &mbi, sizeof(mbi));
pageVector.push_back(curPage); pageVector.push_back(curPage);
memmap->count++; memmap->count++;
@ -109,22 +106,62 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
retval=true; retval=true;
} }
} }
if(addrinfo->flags&flaglabel) //TODO: get label if(addrinfo->flags&flaglabel)
{ {
if(labelget(addr, addrinfo->label)) if(labelget(addr, addrinfo->label))
retval=true; retval=true;
else 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)) if(commentget(addr, addrinfo->comment))
retval=true; retval=true;
//TODO: auto-comments
else 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; return retval;

View File

@ -4,9 +4,12 @@
#include "memory.h" #include "memory.h"
static sqlite3* db; static sqlite3* db;
static sqlite3* internaldb;
///basic database functions
void dbinit() void dbinit()
{ {
//initialize user database
if(sqlite3_open(":memory:", &db)) if(sqlite3_open(":memory:", &db))
{ {
dputs("failed to open database!"); dputs("failed to open database!");
@ -27,6 +30,18 @@ void dbinit()
dprintf("SQL Error: %s\n", errorText); dprintf("SQL Error: %s\n", errorText);
sqlite3_free(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) static int loadOrSaveDb(sqlite3* memory, const char* file, bool save)
@ -63,6 +78,9 @@ bool dbload()
bool dbsave() bool dbsave()
{ {
DeleteFileA("internal.db");
loadOrSaveDb(internaldb, "internal.db", true);
CreateDirectoryA(sqlitedb_basedir, 0); //create database directory CreateDirectoryA(sqlitedb_basedir, 0); //create database directory
if(loadOrSaveDb(db, dbpath, true)!=SQLITE_OK) if(loadOrSaveDb(db, dbpath, true)!=SQLITE_OK)
return false; return false;
@ -72,31 +90,160 @@ bool dbsave()
void dbclose() void dbclose()
{ {
dbsave(); 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) bool modnamefromaddr(uint addr, char* modname)
{ {
IMAGEHLP_MODULE64 modInfo; int total=modinfo.size();
memset(&modInfo, 0, sizeof(modInfo)); for(int i=0; i<total; i++)
modInfo.SizeOfStruct=sizeof(IMAGEHLP_MODULE64); {
if(!SymGetModuleInfo64(fdProcessInfo->hProcess, (DWORD64)addr, &modInfo) or !modname) if(addr>=modinfo.at(i).start and addr<modinfo.at(i).end)
return false; {
_strlwr(modInfo.ModuleName); strcpy(modname, modinfo.at(i).name);
strcpy(modname, modInfo.ModuleName); return true;
return true; }
}
return false;
} }
uint modbasefromaddr(uint addr) uint modbasefromaddr(uint addr)
{ {
IMAGEHLP_MODULE64 modInfo; int total=modinfo.size();
memset(&modInfo, 0, sizeof(modInfo)); for(int i=0; i<total; i++)
modInfo.SizeOfStruct=sizeof(IMAGEHLP_MODULE64); {
if(!SymGetModuleInfo64(fdProcessInfo->hProcess, (DWORD64)addr, &modInfo)) if(addr>=modinfo.at(i).start and addr<modinfo.at(i).end)
return 0; {
return (uint)modInfo.BaseOfImage; 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) bool commentset(uint addr, const char* text)
{ {
if(!IsFileBeingDebugged() or !memisvalidreadptr(fdProcessInfo->hProcess, addr) or !text or strlen(text)>=MAX_COMMENT_SIZE-1) 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; sqlite3_stmt* stmt;
if(!modnamefromaddr(addr, modname)) //comments without module 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) if(sqlite3_prepare_v2(db, sql, -1, &stmt, 0)!=SQLITE_OK)
{ {
sqlite3_finalize(stmt);
efree(newtext);
return false; return false;
} }
if(sqlite3_step(stmt)==SQLITE_ROW) //there is a comment already 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 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 else
{ {
uint modbase=modbasefromaddr(addr); uint modbase=modbasefromaddr(addr);
uint rva=addr-modbase; 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) if(sqlite3_prepare_v2(db, sql, -1, &stmt, 0)!=SQLITE_OK)
{ {
sqlite3_finalize(stmt);
efree(newtext);
return false; return false;
} }
if(sqlite3_step(stmt)==SQLITE_ROW) //there is a comment already 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 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); sqlite3_finalize(stmt);
efree(newtext); efree(newtext);
@ -164,15 +315,17 @@ bool commentget(uint addr, char* text)
char sql[256]=""; char sql[256]="";
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
if(!modnamefromaddr(addr, modname)) //comments without module 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 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) if(sqlite3_prepare_v2(db, sql, -1, &stmt, 0)!=SQLITE_OK)
{ {
sqlite3_finalize(stmt);
return false; return false;
} }
if(sqlite3_step(stmt)!=SQLITE_ROW) //there is a comment already if(sqlite3_step(stmt)!=SQLITE_ROW) //there is a comment already
{ {
sqlite3_finalize(stmt);
return false; return false;
} }
strcpy(text, (const char*)sqlite3_column_text(stmt, 0)); strcpy(text, (const char*)sqlite3_column_text(stmt, 0));
@ -188,19 +341,23 @@ bool commentdel(uint addr)
char sql[256]=""; char sql[256]="";
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
if(!modnamefromaddr(addr, modname)) //comments without module 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 else
{ {
uint modbase=modbasefromaddr(addr); uint modbase=modbasefromaddr(addr);
uint rva=addr-modbase; 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) if(sqlite3_prepare_v2(db, sql, -1, &stmt, 0)!=SQLITE_OK)
{ {
sqlite3_finalize(stmt);
return false; return false;
} }
if(sqlite3_step(stmt)!=SQLITE_ROW) //no comment to delete if(sqlite3_step(stmt)!=SQLITE_ROW) //no comment to delete
{
sqlite3_finalize(stmt);
return false; return false;
}
int del_id=sqlite3_column_int(stmt, 0); int del_id=sqlite3_column_int(stmt, 0);
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
char* errorText=0; char* errorText=0;
@ -216,6 +373,7 @@ bool commentdel(uint addr)
return true; return true;
} }
///label functions
bool labelset(uint addr, const char* text) bool labelset(uint addr, const char* text)
{ {
if(!IsFileBeingDebugged() or !memisvalidreadptr(fdProcessInfo->hProcess, addr) or !text or strlen(text)>=MAX_LABEL_SIZE-1) 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; sqlite3_stmt* stmt;
if(!modnamefromaddr(addr, modname)) //labels without module 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) if(sqlite3_prepare_v2(db, sql, -1, &stmt, 0)!=SQLITE_OK)
{ {
sqlite3_finalize(stmt);
return false; return false;
} }
if(sqlite3_step(stmt)==SQLITE_ROW) //there is a label already 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 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 else
{ {
uint modbase=modbasefromaddr(addr); uint modbase=modbasefromaddr(addr);
uint rva=addr-modbase; 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) if(sqlite3_prepare_v2(db, sql, -1, &stmt, 0)!=SQLITE_OK)
{ {
sqlite3_finalize(stmt);
return false; return false;
} }
if(sqlite3_step(stmt)==SQLITE_ROW) //there is a label already 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 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); sqlite3_finalize(stmt);
efree(newtext); efree(newtext);
@ -283,15 +443,17 @@ bool labelget(uint addr, char* text)
char sql[256]=""; char sql[256]="";
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
if(!modnamefromaddr(addr, modname)) //labels without module 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 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) if(sqlite3_prepare_v2(db, sql, -1, &stmt, 0)!=SQLITE_OK)
{ {
sqlite3_finalize(stmt);
return false; return false;
} }
if(sqlite3_step(stmt)!=SQLITE_ROW) //there is a label already if(sqlite3_step(stmt)!=SQLITE_ROW) //there is a label already
{ {
sqlite3_finalize(stmt);
return false; return false;
} }
strcpy(text, (const char*)sqlite3_column_text(stmt, 0)); strcpy(text, (const char*)sqlite3_column_text(stmt, 0));
@ -307,19 +469,23 @@ bool labeldel(uint addr)
char sql[256]=""; char sql[256]="";
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
if(!modnamefromaddr(addr, modname)) //labels without module 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 else
{ {
uint modbase=modbasefromaddr(addr); uint modbase=modbasefromaddr(addr);
uint rva=addr-modbase; 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) if(sqlite3_prepare_v2(db, sql, -1, &stmt, 0)!=SQLITE_OK)
{ {
sqlite3_finalize(stmt);
return false; return false;
} }
if(sqlite3_step(stmt)!=SQLITE_ROW) //no label to delete if(sqlite3_step(stmt)!=SQLITE_ROW) //no label to delete
{
sqlite3_finalize(stmt);
return false; return false;
}
int del_id=sqlite3_column_int(stmt, 0); int del_id=sqlite3_column_int(stmt, 0);
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
char* errorText=0; char* errorText=0;

View File

@ -3,11 +3,26 @@
#include "_global.h" #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(); void dbinit();
bool dbsave(); bool dbsave();
bool dbload(); bool dbload();
void dbclose(); void dbclose();
bool modnamefromaddr(uint addr, char* modname); 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 commentset(uint addr, const char* text);
bool commentget(uint addr, char* text); bool commentget(uint addr, char* text);
bool commentdel(uint addr); bool commentdel(uint addr);

View File

@ -223,6 +223,38 @@ static void cbException(void* ExceptionData)
wait(WAITID_RUN); 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) static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
{ {
void* base=LoadDll->lpBaseOfDll; void* base=LoadDll->lpBaseOfDll;
@ -233,6 +265,11 @@ static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
DevicePathToPath(DLLDebugFileName, DLLDebugFileName, deflen); DevicePathToPath(DLLDebugFileName, DLLDebugFileName, deflen);
dprintf("DLL Loaded: "fhex" %s\n", base, DLLDebugFileName); dprintf("DLL Loaded: "fhex" %s\n", base, DLLDebugFileName);
SymLoadModuleEx(fdProcessInfo->hProcess, LoadDll->hFile, DLLDebugFileName, 0, (DWORD64)base, 0, 0, 0); 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) static void cbUnloadDll(UNLOAD_DLL_DEBUG_INFO* UnloadDll)
@ -245,6 +282,7 @@ static void cbUnloadDll(UNLOAD_DLL_DEBUG_INFO* UnloadDll)
DevicePathToPath(DLLDebugFileName, DLLDebugFileName, deflen); DevicePathToPath(DLLDebugFileName, DLLDebugFileName, deflen);
dprintf("DLL Unloaded: "fhex" %s\n", base, DLLDebugFileName); dprintf("DLL Unloaded: "fhex" %s\n", base, DLLDebugFileName);
SymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)base); SymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)base);
modunload((uint)base);
} }
static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo) static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
@ -257,14 +295,6 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
DevicePathToPath(DebugFileName, DebugFileName, deflen); DevicePathToPath(DebugFileName, DebugFileName, deflen);
dprintf("Process Started: "fhex" %s\n", base, DebugFileName); 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 //init program database
int len=strlen(szFileName); int len=strlen(szFileName);
while(szFileName[len]!='\\' && len!=0) while(szFileName[len]!='\\' && len!=0)
@ -280,6 +310,23 @@ static void cbSystemBreakpoint(void* ExceptionData)
sprintf(dbpath, "%s\\%s", sqlitedb_basedir, sqlitedb); sprintf(dbpath, "%s\\%s", sqlitedb_basedir, sqlitedb);
dprintf("Database file: %s\n", dbpath); dprintf("Database file: %s\n", dbpath);
dbinit(); 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 //log message
dputs("system breakpoint reached!"); dputs("system breakpoint reached!");
//update GUI //update GUI
@ -1104,13 +1151,11 @@ CMDRESULT cbBenchmark(const char* cmd)
if(!valfromstring(arg1, &addr, 0, 0, false, 0)) if(!valfromstring(arg1, &addr, 0, 0, false, 0))
return STATUS_ERROR; return STATUS_ERROR;
uint ticks=GetTickCount(); uint ticks=GetTickCount();
char comment[MAX_COMMENT_SIZE]="";
commentset(addr, "benchmark"); 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); commentget(addr, comment);
unsigned char dest[0x1000];
_dbg_memread(addr, dest, 0x1000, 0);
} }
commentdel(addr); commentdel(addr);
dprintf("%ums\n", GetTickCount()-ticks); dprintf("%ums\n", GetTickCount()-ticks);

View File

@ -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) 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) if(!hProcess or !lpBaseAddress or !lpBuffer or !nSize)
return false; 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 addr=(uint)lpBaseAddress;
uint startRva=addr&(PAGE_SIZE-1); //get start rva uint startRva=addr&(PAGE_SIZE-1); //get start rva
uint addrStart=addr-startRva; //round down one page 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); bool ret=ReadProcessMemory(hProcess, curAddr, curPage, PAGE_SIZE, &readBytes);
if(!ret or readBytes!=PAGE_SIZE) if(!ret or readBytes!=PAGE_SIZE)
{ {
DWORD oldprotect=0;
VirtualProtectEx(hProcess, curAddr, PAGE_SIZE, PAGE_EXECUTE_READWRITE, &oldprotect); VirtualProtectEx(hProcess, curAddr, PAGE_SIZE, PAGE_EXECUTE_READWRITE, &oldprotect);
ret=ReadProcessMemory(hProcess, curAddr, curPage, PAGE_SIZE, &readBytes); ret=ReadProcessMemory(hProcess, curAddr, curPage, PAGE_SIZE, &readBytes);
VirtualProtectEx(hProcess, curAddr, PAGE_SIZE, oldprotect, &oldprotect); VirtualProtectEx(hProcess, curAddr, PAGE_SIZE, oldprotect, &oldprotect);

View File

@ -117,7 +117,13 @@ QString Disassembly::paintContent(QPainter* painter, int_t rowBase, int rowOffse
int_t cur_addr=mInstBuffer.at(rowOffset).rva+mMemPage->getBase(); 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(); QString addrText=QString("%1").arg(cur_addr, sizeof(int_t)*2, 16, QChar('0')).toUpper();
if(DbgGetLabelAt(cur_addr, SEG_DEFAULT, label)) //has label 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 else
*label=0; *label=0;
BPXTYPE bpxtype=DbgGetBpxTypeAt(cur_addr); BPXTYPE bpxtype=DbgGetBpxTypeAt(cur_addr);

View File

@ -39,13 +39,13 @@ void HexDump::printDumpAt(int_t parVA)
void HexDump::mouseMoveEvent(QMouseEvent* event) void HexDump::mouseMoveEvent(QMouseEvent* event)
{ {
qDebug() << "HexDump::mouseMoveEvent"; //qDebug() << "HexDump::mouseMoveEvent";
bool wAccept = true; bool wAccept = true;
if(mGuiState == HexDump::MultiRowsSelectionState) if(mGuiState == HexDump::MultiRowsSelectionState)
{ {
qDebug() << "State = MultiRowsSelectionState"; //qDebug() << "State = MultiRowsSelectionState";
if((transY(event->y()) >= 0) && (transY(event->y()) <= this->getTableHeigth())) if((transY(event->y()) >= 0) && (transY(event->y()) <= this->getTableHeigth()))
{ {
@ -70,7 +70,7 @@ void HexDump::mouseMoveEvent(QMouseEvent* event)
void HexDump::mousePressEvent(QMouseEvent* event) void HexDump::mousePressEvent(QMouseEvent* event)
{ {
qDebug() << "HexDump::mousePressEvent"; //qDebug() << "HexDump::mousePressEvent";
bool wAccept = false; bool wAccept = false;

View File

@ -87,6 +87,8 @@ bool BeaHighlight::PrintArgument(QList<CustomRichText_t>* richText, const ARGTYP
//labels //labels
uint_t label_addr=Argument->Memory.Displacement; uint_t label_addr=Argument->Memory.Displacement;
if(Argument->ArgType&RELATIVE_) //rip-relative
label_addr=Instruction->AddrValue;
char label_text[MAX_LABEL_SIZE]=""; char label_text[MAX_LABEL_SIZE]="";
if(DbgGetLabelAt(label_addr, ConvertBeaSeg(segmentReg), label_text)) if(DbgGetLabelAt(label_addr, ConvertBeaSeg(segmentReg), label_text))
{ {