DBG: fixed a nasty bug in modbasefromname (thanks Artic!)
DBG: added draft of loop display GUI: simple status bar API
This commit is contained in:
parent
4ef078d463
commit
4d5a8f3749
|
@ -52,5 +52,7 @@ Rogers </DIV>
|
|||
<LI>
|
||||
<DIV>TEAM DVT </DIV>
|
||||
<LI>
|
||||
<DIV> Artic </DIV>
|
||||
<LI>
|
||||
<DIV>Sorry if I forgot
|
||||
you! </DIV></LI></UL></head>
|
||||
you! </DIV></LI></UL></BODY></HTML>
|
|
@ -76,6 +76,7 @@ The icon is taken from VisualPharm (http://www.visualpharm.com/)
|
|||
- Tuts4You community
|
||||
- DMichael
|
||||
- TEAM DVT
|
||||
- Artic
|
||||
- Sorry if I forgot you!
|
||||
|
||||
>Lead developers:
|
||||
|
|
|
@ -417,41 +417,19 @@ BRIDGE_IMPEXP FUNCTYPE DbgGetFunctionTypeAt(duint addr)
|
|||
|
||||
BRIDGE_IMPEXP LOOPTYPE DbgGetLoopTypeAt(duint addr, int depth)
|
||||
{
|
||||
//NOTE: test code for 'function.exe'
|
||||
/*if(depth==0)
|
||||
{
|
||||
if(addr==0x00401348)
|
||||
return LOOP_BEGIN;
|
||||
else if(addr==0x004013A8)
|
||||
return LOOP_ENTRY;
|
||||
else if(addr>0x00401348 && addr<0x004013B3)
|
||||
return LOOP_MIDDLE;
|
||||
else if(addr==0x004013B3)
|
||||
return LOOP_END;
|
||||
}
|
||||
else if(depth==1)
|
||||
{
|
||||
if(addr==0x00401351)
|
||||
return LOOP_BEGIN;
|
||||
else if(addr==0x00401398)
|
||||
return LOOP_ENTRY;
|
||||
else if(addr>0x00401351 && addr<0x004013A3)
|
||||
return LOOP_MIDDLE;
|
||||
else if(addr==0x004013A3)
|
||||
return LOOP_END;
|
||||
}
|
||||
else if(depth==2)
|
||||
{
|
||||
if(addr==0x0040135A)
|
||||
return LOOP_BEGIN;
|
||||
else if(addr==0x00401388)
|
||||
return LOOP_ENTRY;
|
||||
else if(addr>0x0040135A && addr<0x00401393)
|
||||
return LOOP_MIDDLE;
|
||||
else if(addr==0x00401393)
|
||||
return LOOP_END;
|
||||
}*/
|
||||
return LOOP_NONE;
|
||||
ADDRINFO info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.flags=flagloop;
|
||||
info.loop.depth=depth;
|
||||
if(!_dbg_addrinfoget(addr, SEG_DEFAULT, &info))
|
||||
return LOOP_NONE;
|
||||
duint start=info.loop.start;
|
||||
duint end=info.loop.end;
|
||||
if(addr==start)
|
||||
return LOOP_BEGIN;
|
||||
else if(addr==end)
|
||||
return LOOP_END;
|
||||
return LOOP_MIDDLE;
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP duint DbgGetBranchDestination(duint addr)
|
||||
|
@ -849,6 +827,11 @@ BRIDGE_IMPEXP void GuiAutoCompleteClearAll()
|
|||
_gui_sendmessage(GUI_AUTOCOMPLETE_CLEARALL, 0, 0);
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP void GuiAddStatusBarMessage(const char* msg)
|
||||
{
|
||||
_gui_sendmessage(GUI_ADD_MSG_TO_STATUSBAR, (void*)msg, 0);
|
||||
}
|
||||
|
||||
//Main
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
|
|
|
@ -83,7 +83,8 @@ enum ADDRINFOFLAGS
|
|||
flaglabel=2,
|
||||
flagcomment=4,
|
||||
flagbookmark=8,
|
||||
flagfunction=16
|
||||
flagfunction=16,
|
||||
flagloop=32
|
||||
};
|
||||
|
||||
enum BPXTYPE
|
||||
|
@ -278,18 +279,26 @@ struct BPMAP
|
|||
|
||||
struct FUNCTION
|
||||
{
|
||||
duint start;
|
||||
duint end;
|
||||
duint start; //OUT
|
||||
duint end; //OUT
|
||||
};
|
||||
|
||||
struct LOOP
|
||||
{
|
||||
int depth; //IN
|
||||
duint start; //OUT
|
||||
duint end; //OUT
|
||||
};
|
||||
|
||||
struct ADDRINFO
|
||||
{
|
||||
int flags; //ADDRINFOFLAGS
|
||||
int flags; //ADDRINFOFLAGS (IN)
|
||||
char module[MAX_MODULE_SIZE]; //module the address is in
|
||||
char label[MAX_LABEL_SIZE];
|
||||
char comment[MAX_COMMENT_SIZE];
|
||||
bool isbookmark;
|
||||
FUNCTION function;
|
||||
LOOP loop;
|
||||
};
|
||||
|
||||
struct SYMBOLINFO
|
||||
|
@ -553,7 +562,8 @@ enum GUIMSG
|
|||
GUI_AUTOCOMPLETE_ADDCMD, // param1=const char* cmd, param2=ununsed
|
||||
GUI_AUTOCOMPLETE_DELCMD, // param1=const char* cmd, param2=ununsed
|
||||
GUI_AUTOCOMPLETE_CLEARALL, // param1=ununsed, param2=unused
|
||||
GUI_SCRIPT_ENABLEHIGHLIGHTING // param1=bool enable, param2=unused
|
||||
GUI_SCRIPT_ENABLEHIGHLIGHTING, // param1=bool enable, param2=unused
|
||||
GUI_ADD_MSG_TO_STATUSBAR // param1=const char* msg, param2=unused
|
||||
};
|
||||
|
||||
//GUI structures
|
||||
|
@ -621,6 +631,7 @@ BRIDGE_IMPEXP bool GuiGetLineWindow(const char* title, char* text);
|
|||
BRIDGE_IMPEXP void GuiAutoCompleteAddCmd(const char* cmd);
|
||||
BRIDGE_IMPEXP void GuiAutoCompleteDelCmd(const char* cmd);
|
||||
BRIDGE_IMPEXP void GuiAutoCompleteClearAll();
|
||||
BRIDGE_IMPEXP void GuiAddStatusBarMessage(const char* msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -377,6 +377,11 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
|
|||
if(functionget(addr, &addrinfo->function.start, &addrinfo->function.end))
|
||||
retval=true;
|
||||
}
|
||||
if(addrinfo->flags&flagloop)
|
||||
{
|
||||
if(loopget(addrinfo->loop.depth, addr, &addrinfo->loop.start, &addrinfo->loop.end))
|
||||
retval=true;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@ void dbinit()
|
|||
dprintf("SQL Error: %s\n", sqllasterror());
|
||||
if(!sqlexec(userdb, "CREATE TABLE IF NOT EXISTS functions (id INTEGER PRIMARY KEY AUTOINCREMENT, mod TEXT, start INT64 NOT NULL, end INT64 NOT NULL, manual BOOL NOT NULL)"))
|
||||
dprintf("SQL Error: %s\n", sqllasterror());
|
||||
if(!sqlexec(userdb, "CREATE TABLE IF NOT EXISTS loops (id INTEGER PRIMARY KEY AUTOINCREMENT, mod TEXT, start INT64 NOT NULL, end INT64 NOT NULL, parent INT, depth INT NOT NULL, manual BOOL NOT NULL)"))
|
||||
dprintf("SQL Error: %s\n", sqllasterror());
|
||||
dbsave();
|
||||
bpenumall(0); //update breakpoint list
|
||||
GuiUpdateBreakpointsView();
|
||||
|
@ -165,16 +167,13 @@ uint modbasefromname(const char* modname)
|
|||
int modname_len=strlen(modname);
|
||||
if(modname_len>=MAX_MODULE_SIZE)
|
||||
return 0;
|
||||
char newmodname[MAX_MODULE_SIZE]="";
|
||||
strcpy(newmodname, modname);
|
||||
_strlwr(newmodname);
|
||||
for(int i=0; i<total; i++)
|
||||
{
|
||||
int cur_len=strlen(modinfo.at(i).name);
|
||||
int cmp_len=modname_len;
|
||||
if(cur_len<cmp_len)
|
||||
cmp_len=cur_len;
|
||||
if(!memcmp(modinfo.at(i).name, newmodname, cmp_len))
|
||||
char curmodname[MAX_MODULE_SIZE]="";
|
||||
sprintf(curmodname, "%s%s", modinfo.at(i).name, modinfo.at(i).extension);
|
||||
if(!_stricmp(curmodname, modname)) //with extension
|
||||
return modinfo.at(i).base;
|
||||
if(!_stricmp(modinfo.at(i).name, modname)) //without extension
|
||||
return modinfo.at(i).base;
|
||||
}
|
||||
return 0;
|
||||
|
@ -649,3 +648,89 @@ bool functiondel(uint addr)
|
|||
dbsave();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool loopget(int depth, uint addr, uint* start, uint* end)
|
||||
{
|
||||
if(!DbgIsDebugging() or !memisvalidreadptr(fdProcessInfo->hProcess, addr))
|
||||
return false;
|
||||
char modname[MAX_MODULE_SIZE]="";
|
||||
char sql[deflen]="";
|
||||
uint modbase=0;
|
||||
if(!modnamefromaddr(addr, modname, true))
|
||||
sprintf(sql, "SELECT start,end FROM loops WHERE mod IS NULL AND start<=%"fext"d AND end>=%"fext"d AND depth=%d", addr, addr, depth);
|
||||
else
|
||||
{
|
||||
modbase=modbasefromaddr(addr);
|
||||
uint rva=addr-modbase;
|
||||
sprintf(sql, "SELECT start,end FROM loops WHERE mod='%s' AND start<=%"fext"d AND end>=%"fext"d AND depth=%d", modname, rva, rva, depth);
|
||||
}
|
||||
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;
|
||||
}
|
||||
#ifdef _WIN64
|
||||
uint dbstart=sqlite3_column_int64(stmt, 0)+modbase; //start
|
||||
uint dbend=sqlite3_column_int64(stmt, 1)+modbase; //end
|
||||
#else
|
||||
uint dbstart=sqlite3_column_int(stmt, 0)+modbase; //addr
|
||||
uint dbend=sqlite3_column_int(stmt, 1)+modbase; //end
|
||||
#endif // _WIN64
|
||||
sqlite3_finalize(stmt);
|
||||
if(start)
|
||||
*start=dbstart;
|
||||
if(end)
|
||||
*end=dbend;
|
||||
unlock(WAITID_USERDB);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool loopadd(uint start, uint end, bool manual)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//check if a loop overlaps a range, inside is not overlapping
|
||||
bool loopoverlaps(int depth, uint start, uint end)
|
||||
{
|
||||
char sql[deflen]="";
|
||||
char modname[MAX_MODULE_SIZE]="";
|
||||
|
||||
//check if the new loop fits in the old loop
|
||||
if(!modnamefromaddr(start, modname, true))
|
||||
sprintf(sql, "SELECT manual FROM loops WHERE mod IS NULL AND start<%"fext"d AND end>%"fext"d AND depth=%d", start, end, depth);
|
||||
else
|
||||
{
|
||||
uint modbase=modbasefromaddr(start);
|
||||
sprintf(sql, "SELECT manual FROM loops WHERE mod='%s' AND start<%"fext"d AND end>%"fext"d AND depth=%d", modname, start-modbase, end-modbase, depth);
|
||||
}
|
||||
if(sqlhasresult(userdb, sql)) //new loop fits in the old loop
|
||||
return loopoverlaps(depth+1, start, end); //check the next depth
|
||||
|
||||
//check for loop overlaps
|
||||
if(!modnamefromaddr(start, modname, true))
|
||||
sprintf(sql, "SELECT manual FROM loops WHERE mod IS NULL AND start<=%"fext"d AND end>=%"fext"d AND depth=%d", end, start, depth);
|
||||
else
|
||||
{
|
||||
uint modbase=modbasefromaddr(start);
|
||||
sprintf(sql, "SELECT manual FROM loops WHERE mod='%s' AND start<=%"fext"d AND end>=%"fext"d AND depth=%d", modname, end-modbase, start-modbase, depth);
|
||||
}
|
||||
if(sqlhasresult(userdb, sql)) //loops overlap
|
||||
return true;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool loopdel(uint addr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -43,5 +43,9 @@ bool functionget(duint addr, duint* start, duint* end);
|
|||
bool functionoverlaps(uint start, uint end);
|
||||
bool functionadd(uint start, uint end, bool manual);
|
||||
bool functiondel(uint addr);
|
||||
bool loopget(int depth, uint addr, uint* start, uint* end);
|
||||
bool loopoverlaps(int depth, uint start, uint end);
|
||||
bool loopadd(uint start, uint end, bool manual);
|
||||
bool loopdel(uint addr);
|
||||
|
||||
#endif // _ADDRINFO_H
|
||||
|
|
|
@ -261,6 +261,11 @@ void Bridge::emitMenuClearMenu(int hMenu)
|
|||
emit menuClearMenu(hMenu);
|
||||
}
|
||||
|
||||
void Bridge::emitAddMsgToStatusBar(QString msg)
|
||||
{
|
||||
emit addMsgToStatusBar(msg);
|
||||
}
|
||||
|
||||
bool Bridge::emitSelectionGet(int hWindow, SELECTIONDATA* selection)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
|
@ -690,6 +695,12 @@ __declspec(dllexport) void* _gui_sendmessage(GUIMSG type, void* param1, void* pa
|
|||
}
|
||||
break;
|
||||
|
||||
case GUI_ADD_MSG_TO_STATUSBAR:
|
||||
{
|
||||
Bridge::getBridge()->emitAddMsgToStatusBar(QString((const char*)param1));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@ public:
|
|||
void emitAutoCompleteAddCmd(const QString cmd);
|
||||
void emitAutoCompleteDelCmd(const QString cmd);
|
||||
void emitAutoCompleteClearAll();
|
||||
void emitAddMsgToStatusBar(QString msg);
|
||||
|
||||
//Public variables
|
||||
void* winId;
|
||||
|
@ -130,6 +131,7 @@ signals:
|
|||
void autoCompleteAddCmd(const QString cmd);
|
||||
void autoCompleteDelCmd(const QString cmd);
|
||||
void autoCompleteClearAll();
|
||||
void addMsgToStatusBar(QString msg);
|
||||
|
||||
private:
|
||||
QMutex mBridgeMutex;
|
||||
|
|
|
@ -14,7 +14,10 @@ StatusLabel::StatusLabel(QStatusBar* parent) : QLabel(parent)
|
|||
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(debugStateChangedSlot(DBGSTATE)));
|
||||
}
|
||||
else //last log message
|
||||
{
|
||||
connect(Bridge::getBridge(), SIGNAL(addMsgToLog(QString)), this, SLOT(logUpdate(QString)));
|
||||
connect(Bridge::getBridge(), SIGNAL(addMsgToStatusBar(QString)), this, SLOT(logUpdate(QString)));
|
||||
}
|
||||
}
|
||||
|
||||
void StatusLabel::debugStateChangedSlot(DBGSTATE state)
|
||||
|
|
Loading…
Reference in New Issue