1
0
Fork 0
x64dbg/x64_dbg_dbg/breakpoint.cpp

322 lines
10 KiB
C++

#include "breakpoint.h"
#include "debugger.h"
#include "addrinfo.h"
#include "sqlhelper.h"
#include "console.h"
#include "memory.h"
#include "threading.h"
static BREAKPOINT bpall[1000]; //TODO: fix this size
static int bpcount=0;
int bpgetlist(BREAKPOINT** list)
{
if(list)
*list=bpall;
return bpcount;
}
bool bpnew(uint addr, bool enabled, bool singleshoot, short oldbytes, BP_TYPE type, DWORD titantype, const char* name)
{
if(bpget(addr, type, name, 0)) //breakpoint found
return false;
char modname[256]="";
char sql[deflen]="";
char bpname[MAX_BREAKPOINT_SIZE]="";
if(modnamefromaddr(addr, modname, true)) //no module
{
uint modbase=modbasefromaddr(addr);
if(name and *name)
{
sqlstringescape(name, bpname);
sprintf(sql, "INSERT INTO breakpoints (addr,enabled,singleshoot,oldbytes,type,titantype,mod,name) VALUES (%"fext"d,%d,%d,%d,%d,%d,'%s','%s')", addr-modbase, enabled, singleshoot, oldbytes, type, titantype, modname, bpname);
}
else
sprintf(sql, "INSERT INTO breakpoints (addr,enabled,singleshoot,oldbytes,type,titantype,mod) VALUES (%"fext"d,%d,%d,%d,%d,%d,'%s')", addr-modbase, enabled, singleshoot, oldbytes, type, titantype, modname);
}
else
{
if(name and *name)
{
sqlstringescape(name, bpname);
sprintf(sql, "INSERT INTO breakpoints (addr,enabled,singleshoot,oldbytes,type,titantype,name) VALUES (%"fext"d,%d,%d,%d,%d,%d,'%s')", addr, enabled, singleshoot, oldbytes, type, titantype, bpname);
}
else
sprintf(sql, "INSERT INTO breakpoints (addr,enabled,singleshoot,oldbytes,type,titantype) VALUES (%"fext"d,%d,%d,%d,%d,%d)", addr, enabled, singleshoot, oldbytes, type, titantype);
}
if(!sqlexec(userdb, sql))
{
dprintf("SQL Error: %s\nSQL Query: %s\n", sqllasterror(), sql);
return false;
}
bpenumall(0); //update breakpoint list
dbsave();
GuiUpdateBreakpointsView();
return true;
}
bool bpget(uint addr, BP_TYPE type, const char* name, BREAKPOINT* bp)
{
char sql[deflen]="";
char modname[256]="";
char bpname[MAX_BREAKPOINT_SIZE]="";
uint modbase=0;
if(!modnamefromaddr(addr, modname, true)) //no module
{
if(bp)
*bp->mod=0;
if(name and *name)
{
sqlstringescape(name, bpname);
sprintf(sql, "SELECT addr,enabled,singleshoot,oldbytes,type,titantype,mod,name FROM breakpoints WHERE (addr=%"fext"d AND type=%d AND mod IS NULL) OR name='%s'", addr, type, bpname);
}
else
sprintf(sql, "SELECT addr,enabled,singleshoot,oldbytes,type,titantype,mod,name FROM breakpoints WHERE (addr=%"fext"d AND type=%d AND mod IS NULL)", addr, type);
}
else
{
if(bp)
strcpy(bp->mod, modname);
modbase=modbasefromaddr(addr);
if(name and *name)
{
sqlstringescape(name, bpname);
sprintf(sql, "SELECT addr,enabled,singleshoot,oldbytes,type,titantype,mod,name FROM breakpoints WHERE (addr=%"fext"d AND type=%d AND mod='%s') OR name='%s'", addr-modbase, type, modname, bpname);
}
else
sprintf(sql, "SELECT addr,enabled,singleshoot,oldbytes,type,titantype,mod,name FROM breakpoints WHERE (addr=%"fext"d AND type=%d AND mod='%s')", addr-modbase, type, modname);
}
sqlite3_stmt* stmt;
lock(WAITID_USERDB);
if(sqlite3_prepare_v2(userdb, sql, -1, &stmt, 0)!=SQLITE_OK)
{
sqlite3_finalize(stmt);
unlock(WAITID_USERDB);
return false;
}
if(sqlite3_step(stmt)!=SQLITE_ROW)
{
sqlite3_finalize(stmt);
unlock(WAITID_USERDB);
return false;
}
if(!bp) //just check if a breakpoint exists
{
sqlite3_finalize(stmt);
unlock(WAITID_USERDB);
return true;
}
memset(bp, 0, sizeof(BREAKPOINT));
if(!modbase)
{
const char* mod=(const char*)sqlite3_column_text(stmt, 6); //mod
if(mod)
modbase=modbasefromname(mod);
}
#ifdef _WIN64
bp->addr=sqlite3_column_int64(stmt, 0)+modbase; //addr
#else
bp->addr=sqlite3_column_int(stmt, 0)+modbase; //addr
#endif // _WIN64
if(sqlite3_column_int(stmt, 1)) //enabled
bp->enabled=true;
else
bp->enabled=false;
if(sqlite3_column_int(stmt, 2)) //singleshoot
bp->singleshoot=true;
else
bp->singleshoot=false;
bp->oldbytes=(short)(sqlite3_column_int(stmt, 3)&0xFFFF); //oldbytes
bp->type=(BP_TYPE)sqlite3_column_int(stmt, 4); //type
bp->titantype=sqlite3_column_int(stmt, 5); //titantype
const char* bpname_=(const char*)sqlite3_column_text(stmt, 7); //name
if(bpname_)
strcpy(bp->name, bpname_);
else
*bp->name=0;
//TODO: fix this
if(memisvalidreadptr(fdProcessInfo->hProcess, bp->addr))
bp->active=true;
sqlite3_finalize(stmt);
unlock(WAITID_USERDB);
return true;
}
bool bpdel(uint addr, BP_TYPE type)
{
BREAKPOINT found;
if(!bpget(addr, type, 0, &found))
return false;
char modname[256]="";
char sql[deflen]="";
if(!modnamefromaddr(addr, modname, true)) //no module
sprintf(sql, "DELETE FROM breakpoints WHERE addr=%"fext"d AND mod IS NULL AND type=%d", addr, type);
else
sprintf(sql, "DELETE FROM breakpoints WHERE addr=%"fext"d AND mod='%s' AND type=%d", addr-modbasefromaddr(addr), modname, type);
if(!sqlexec(userdb, sql))
{
dprintf("SQL Error: %s\nSQL Query: %s\n", sqllasterror(), sql);
return false;
}
bpenumall(0); //update breakpoint list
dbsave();
GuiUpdateBreakpointsView();
return true;
}
bool bpenable(uint addr, BP_TYPE type, bool enable)
{
BREAKPOINT found;
if(!bpget(addr, type, 0, &found))
return false;
char modname[256]="";
char sql[deflen]="";
if(!modnamefromaddr(addr, modname, true)) //no module
sprintf(sql, "UPDATE breakpoints SET enabled=%d WHERE addr=%"fext"d AND mod IS NULL AND type=%d", enable, addr, type);
else
sprintf(sql, "UPDATE breakpoints SET enabled=%d WHERE addr=%"fext"d AND mod='%s' AND type=%d", enable, addr-modbasefromaddr(addr), modname, type);
if(!sqlexec(userdb, sql))
{
dprintf("SQL Error: %s\nSQL Query: %s\n", sqllasterror(), sql);
return false;
}
bpenumall(0); //update breakpoint list
dbsave();
GuiUpdateBreakpointsView();
return true;
}
bool bpsetname(uint addr, BP_TYPE type, const char* name)
{
if(!name)
return false;
char modname[256]="";
char sql[deflen]="";
char bpname[MAX_BREAKPOINT_SIZE]="";
sqlstringescape(name, bpname);
if(!modnamefromaddr(addr, modname, true)) //no module
sprintf(sql, "UPDATE breakpoints SET name='%s' WHERE addr=%"fext"d AND mod IS NULL AND type=%d", bpname, addr, type);
else
sprintf(sql, "UPDATE breakpoints SET name='%s' WHERE addr=%"fext"d AND mod='%s' AND type=%d", bpname, addr-modbasefromaddr(addr), modname, type);
if(!sqlexec(userdb, sql))
{
dprintf("SQL Error: %s\nSQL Query: %s\n", sqllasterror(), sql);
return false;
}
bpenumall(0); //update breakpoint list
dbsave();
GuiUpdateBreakpointsView();
return true;
}
bool bpenumall(BPENUMCALLBACK cbEnum, const char* module)
{
bool retval=true;
if(!cbEnum)
bpcount=0;
char sql[deflen]="";
if(!module)
sprintf(sql, "SELECT addr,enabled,singleshoot,oldbytes,type,titantype,mod,name FROM breakpoints");
else
sprintf(sql, "SELECT addr,enabled,singleshoot,oldbytes,type,titantype,mod,name FROM breakpoints WHERE mod='%s'", module);
sqlite3_stmt* stmt;
lock(WAITID_USERDB);
if(sqlite3_prepare_v2(userdb, sql, -1, &stmt, 0)!=SQLITE_OK)
{
sqlite3_finalize(stmt);
unlock(WAITID_USERDB);
return false;
}
if(sqlite3_step(stmt)!=SQLITE_ROW)
{
sqlite3_finalize(stmt);
unlock(WAITID_USERDB);
return false;
}
BREAKPOINT curbp;
do
{
#ifdef _WIN64
uint rva=sqlite3_column_int64(stmt, 0); //addr
#else
uint rva=sqlite3_column_int(stmt, 0); //addr
#endif // _WIN64
if(sqlite3_column_int(stmt, 1)) //enabled
curbp.enabled=true;
else
curbp.enabled=false;
if(sqlite3_column_int(stmt, 2)) //singleshoot
curbp.singleshoot=true;
else
curbp.singleshoot=false;
curbp.oldbytes=(short)(sqlite3_column_int(stmt, 3)&0xFFFF); //oldbytes
curbp.type=(BP_TYPE)sqlite3_column_int(stmt, 4); //type
curbp.titantype=sqlite3_column_int(stmt, 5); //titantype
const char* modname=(const char*)sqlite3_column_text(stmt, 6); //mod
if(modname)
strcpy(curbp.mod, modname);
else
*curbp.mod=0;
const char* bpname=(const char*)sqlite3_column_text(stmt, 7); //name
if(bpname)
strcpy(curbp.name, bpname);
else
*curbp.name=0;
uint modbase=modbasefromname(modname);
if(!modbase) //module not loaded
*curbp.mod=0;
curbp.addr=modbase+rva;
if(cbEnum)
{
if(!cbEnum(&curbp))
retval=false;
}
else if(bpcount<1000)
{
memcpy(&bpall[bpcount], &curbp, sizeof(BREAKPOINT));
bpcount++;
}
}
while(sqlite3_step(stmt)==SQLITE_ROW);
sqlite3_finalize(stmt);
unlock(WAITID_USERDB);
return retval;
}
bool bpenumall(BPENUMCALLBACK cbEnum)
{
return bpenumall(cbEnum, 0);
}
int bpgetcount(BP_TYPE type)
{
char sql[deflen]="";
sprintf(sql, "SELECT * FROM breakpoints WHERE type=%d", type);
return sqlrowcount(userdb, sql);
}
void bptobridge(const BREAKPOINT* bp, BRIDGEBP* bridge)
{
if(!bp or !bridge)
return;
memset(bridge, 0, sizeof(BRIDGEBP));
bridge->active=bp->active;
bridge->addr=bp->addr;
bridge->enabled=bp->enabled;
strcpy(bridge->mod, bp->mod);
strcpy(bridge->name, bp->name);
bridge->singleshoot=bp->singleshoot;
switch(bp->type)
{
case BPNORMAL:
bridge->type=bp_normal;
break;
case BPHARDWARE:
bridge->type=bp_hardware;
break;
case BPMEMORY:
bridge->type=bp_memory;
default:
bridge->type=bp_none;
}
}