From 4c2f73518a92ef5f14f88c6956e57620f3102c38 Mon Sep 17 00:00:00 2001 From: "mr.exodia" Date: Wed, 20 Nov 2013 22:28:20 +0100 Subject: [PATCH] DBG: added bplist DBG: added bookmark GUI: many improbments --- x64_dbg_bridge/_global.cpp | 1 + x64_dbg_bridge/_global.h | 2 + x64_dbg_bridge/bridgemain.cpp | 32 +++++ x64_dbg_bridge/bridgemain.h | 24 +++- x64_dbg_dbg/_exports.cpp | 74 ++++++++++- x64_dbg_dbg/_exports.h | 1 + x64_dbg_dbg/addrinfo.cpp | 80 ++++++++++- x64_dbg_dbg/addrinfo.h | 3 + x64_dbg_dbg/breakpoint.cpp | 6 +- x64_dbg_dbg/breakpoint.h | 4 +- x64_dbg_dbg/instruction.cpp | 53 ++++++++ x64_dbg_dbg/instruction.h | 2 + x64_dbg_dbg/x64_dbg.cpp | 2 + x64_dbg_gui/Project/DebuggerX64.pro | 9 +- .../Project/Src/BasicView/Disassembly.cpp | 81 +++++++----- .../Project/Src/BasicView/Disassembly.h | 2 +- .../Project/Src/BasicView/LineEditDialog.cpp | 27 ++++ .../Project/Src/BasicView/LineEditDialog.h | 27 ++++ .../Project/Src/BasicView/LineEditDialog.ui | 107 +++++++++++++++ .../Project/Src/BasicView/RegistersView.cpp | 2 +- .../Project/Src/BasicView/RegistersView.h | 1 + .../Project/Src/Gui/CPUDisassembly.cpp | 125 +++++++++++++++--- x64_dbg_gui/Project/Src/Gui/CPUDisassembly.h | 12 +- x64_dbg_gui/Project/Src/Gui/GotoDialog.cpp | 4 +- x64_dbg_gui/Project/Src/Gui/MainWindow.cpp | 2 +- x64_dbg_gui/Project/images/compile-error.png | Bin 0 -> 638 bytes x64_dbg_gui/Project/resource.qrc | 1 + 27 files changed, 617 insertions(+), 67 deletions(-) create mode 100644 x64_dbg_gui/Project/Src/BasicView/LineEditDialog.cpp create mode 100644 x64_dbg_gui/Project/Src/BasicView/LineEditDialog.h create mode 100644 x64_dbg_gui/Project/Src/BasicView/LineEditDialog.ui create mode 100644 x64_dbg_gui/Project/images/compile-error.png diff --git a/x64_dbg_bridge/_global.cpp b/x64_dbg_bridge/_global.cpp index 91dd66e3..acf9a37a 100644 --- a/x64_dbg_bridge/_global.cpp +++ b/x64_dbg_bridge/_global.cpp @@ -29,3 +29,4 @@ DBGBPGETTYPEAT _dbg_bpgettypeat; DBGGETREGDUMP _dbg_getregdump; DBGVALTOSTRING _dbg_valtostring; DBGMEMISVALIDREADPTR _dbg_memisvalidreadptr; +DBGGETBPLIST _dbg_getbplist; diff --git a/x64_dbg_bridge/_global.h b/x64_dbg_bridge/_global.h index 4beac1f4..a2938d51 100644 --- a/x64_dbg_bridge/_global.h +++ b/x64_dbg_bridge/_global.h @@ -61,6 +61,7 @@ typedef BPXTYPE (*DBGBPGETTYPEAT)(duint addr); typedef bool (*DBGGETREGDUMP)(REGDUMP* regdump); typedef bool (*DBGVALTOSTRING)(const char* string, duint* value); typedef bool (*DBGMEMISVALIDREADPTR)(duint addr); +typedef int (*DBGGETBPLIST)(BPXTYPE type, BPMAP* bplist); //DBG functions extern DBGDBGINIT _dbg_dbginit; @@ -78,5 +79,6 @@ extern DBGBPGETTYPEAT _dbg_bpgettypeat; extern DBGGETREGDUMP _dbg_getregdump; extern DBGVALTOSTRING _dbg_valtostring; extern DBGMEMISVALIDREADPTR _dbg_memisvalidreadptr; +extern DBGGETBPLIST _dbg_getbplist; #endif // _GLOBAL_H diff --git a/x64_dbg_bridge/bridgemain.cpp b/x64_dbg_bridge/bridgemain.cpp index d3a02884..8f8d7e2c 100644 --- a/x64_dbg_bridge/bridgemain.cpp +++ b/x64_dbg_bridge/bridgemain.cpp @@ -123,6 +123,10 @@ DLL_IMPEXP const char* BridgeInit() _dbg_memisvalidreadptr=(DBGMEMISVALIDREADPTR)GetProcAddress(hInstDbg, "_dbg_memisvalidreadptr"); if(!_dbg_memisvalidreadptr) return "Export \"_dbg_memisvalidreadptr\" could not be found!"; + //_dbg_getbplist + _dbg_getbplist=(DBGGETBPLIST)GetProcAddress(hInstDbg, "_dbg_getbplist"); + if(!_dbg_getbplist) + return "Export \"_dbg_getbplist\" could not be found!"; return 0; } @@ -313,6 +317,29 @@ DLL_IMPEXP bool DbgGetModuleAt(duint addr, char* text) return true; } +DLL_IMPEXP bool DbgGetBookmarkAt(duint addr) +{ + if(!addr) + return false; + ADDRINFO info; + memset(&info, 0, sizeof(info)); + info.flags=flagbookmark; + if(!_dbg_addrinfoget(addr, SEG_DEFAULT, &info)) + return false; + return info.isbookmark; +} + +DLL_IMPEXP bool DbgSetBookmarkAt(duint addr, bool isbookmark) +{ + if(!addr) + return false; + ADDRINFO info; + memset(&info, 0, sizeof(info)); + info.flags=flagbookmark; + info.isbookmark=isbookmark; + return _dbg_addrinfoset(addr, &info); +} + DLL_IMPEXP BPXTYPE DbgGetBpxTypeAt(duint addr) { return _dbg_bpgettypeat(addr); @@ -341,6 +368,11 @@ DLL_IMPEXP bool DbgMemIsValidReadPtr(duint addr) return _dbg_memisvalidreadptr(addr); } +DLL_IMPEXP int DbgGetBpList(BPXTYPE type, BPMAP* list) +{ + return _dbg_getbplist(type, list); +} + //GUI DLL_IMPEXP void GuiDisasmAt(duint addr, duint cip) { diff --git a/x64_dbg_bridge/bridgemain.h b/x64_dbg_bridge/bridgemain.h index 5519ec69..198f6a88 100644 --- a/x64_dbg_bridge/bridgemain.h +++ b/x64_dbg_bridge/bridgemain.h @@ -41,6 +41,7 @@ DLL_IMPEXP bool BridgeSettingSetUint(const char* section, const char* key, duint #define MAX_LABEL_SIZE 256 #define MAX_COMMENT_SIZE 256 #define MAX_MODULE_SIZE 256 +#define MAX_BREAKPOINT_SIZE 256 //Debugger enums enum DBGSTATE @@ -66,7 +67,8 @@ enum ADDRINFOFLAGS { flagmodule=1, flaglabel=2, - flagcomment=4 + flagcomment=4, + flagbookmark=8 }; enum BPXTYPE @@ -90,11 +92,28 @@ struct MEMMAP MEMPAGE* page; }; +struct BRIDGEBP +{ + BPXTYPE type; + duint addr; + bool enabled; + bool singleshoot; + char name[MAX_BREAKPOINT_SIZE]; + char mod[MAX_MODULE_SIZE]; +}; + +struct BPMAP +{ + int count; + BRIDGEBP* bp; +}; + struct ADDRINFO { char module[MAX_MODULE_SIZE]; //module the address is in char label[MAX_LABEL_SIZE]; char comment[MAX_COMMENT_SIZE]; + bool isbookmark; int flags; //ADDRINFOFLAGS }; @@ -162,12 +181,15 @@ DLL_IMPEXP bool DbgGetLabelAt(duint addr, SEGMENTREG segment, char* text); DLL_IMPEXP bool DbgSetLabelAt(duint addr, const char* text); DLL_IMPEXP bool DbgGetCommentAt(duint addr, char* text); DLL_IMPEXP bool DbgSetCommentAt(duint addr, const char* text); +DLL_IMPEXP bool DbgGetBookmarkAt(duint addr); +DLL_IMPEXP bool DbgSetBookmarkAt(duint addr, bool isbookmark); DLL_IMPEXP bool DbgGetModuleAt(duint addr, char* text); DLL_IMPEXP BPXTYPE DbgGetBpxTypeAt(duint addr); DLL_IMPEXP duint DbgValFromString(const char* string); DLL_IMPEXP bool DbgGetRegDump(REGDUMP* regdump); DLL_IMPEXP bool DbgValToString(const char* string, duint value); DLL_IMPEXP bool DbgMemIsValidReadPtr(duint addr); +DLL_IMPEXP BPXTYPE DbgGetBpxTypeAt(duint addr); //GUI functions DLL_IMPEXP void GuiDisasmAt(duint addr, duint cip); diff --git a/x64_dbg_dbg/_exports.cpp b/x64_dbg_dbg/_exports.cpp index 48dd91b0..e12a5e08 100644 --- a/x64_dbg_dbg/_exports.cpp +++ b/x64_dbg_dbg/_exports.cpp @@ -161,6 +161,11 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR } } } + if(addrinfo->flags&flagbookmark) + { + addrinfo->isbookmark=bookmarkget(addr); + retval=true; + } return retval; } @@ -172,11 +177,18 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoset(duint addr, ADDRINFO* addrinfo) if(labelset(addr, addrinfo->label)) retval=true; } - else if(addrinfo->flags&flagcomment) //set comment + if(addrinfo->flags&flagcomment) //set comment { if(commentset(addr, addrinfo->comment)) retval=true; } + if(addrinfo->flags&flagbookmark) //set bookmark + { + if(addrinfo->isbookmark) + retval=bookmarkset(addr); + else + retval=bookmarkdel(addr); + } return retval; } @@ -305,3 +317,63 @@ extern "C" DLL_EXPORT bool _dbg_valtostring(const char* string, duint* value) { return valtostring(string, value, true); } + +extern "C" DLL_EXPORT int _dbg_getbplist(BPXTYPE type, BPMAP* bplist) +{ + if(!bplist) + return 0; + BREAKPOINT* list; + int bpcount=bpgetlist(&list); + if(!bpcount) + return 0; + int retcount=0; + std::vector bridgeList; + BRIDGEBP curBp; + for(int i=0; icount=retcount; + bplist->bp=(BRIDGEBP*)BridgeAlloc(sizeof(BRIDGEBP)*retcount); + for(int i=0; ibp[i], &bridgeList.at(i), sizeof(BRIDGEBP)); + return retcount; +} diff --git a/x64_dbg_dbg/_exports.h b/x64_dbg_dbg/_exports.h index 63aea797..0f7f6648 100644 --- a/x64_dbg_dbg/_exports.h +++ b/x64_dbg_dbg/_exports.h @@ -20,6 +20,7 @@ DLL_EXPORT bool _dbg_addrinfoset(duint addr, ADDRINFO* addrinfo); DLL_EXPORT int _dbg_bpgettypeat(duint addr); DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump); DLL_EXPORT bool _dbg_valtostring(const char* string, duint* value); +DLL_EXPORT int _dbg_getbplist(BPXTYPE type, BPMAP* bplist); #ifdef __cplusplus } diff --git a/x64_dbg_dbg/addrinfo.cpp b/x64_dbg_dbg/addrinfo.cpp index 2c9ce016..5be62fb2 100644 --- a/x64_dbg_dbg/addrinfo.cpp +++ b/x64_dbg_dbg/addrinfo.cpp @@ -17,9 +17,11 @@ void dbinit() return; } sqlloadsavedb(userdb, dbpath, false); + if(!sqlexec(userdb, "CREATE TABLE IF NOT EXISTS labels (id INTEGER PRIMARY KEY AUTOINCREMENT, mod TEXT, addr INT64 NOT NULL, text TEXT NOT NULL)")) + dprintf("SQL Error: %s\n", sqllasterror()); if(!sqlexec(userdb, "CREATE TABLE IF NOT EXISTS comments (id INTEGER PRIMARY KEY AUTOINCREMENT, mod TEXT, addr INT64 NOT NULL, text TEXT NOT NULL)")) dprintf("SQL Error: %s\n", sqllasterror()); - if(!sqlexec(userdb, "CREATE TABLE IF NOT EXISTS labels (id INTEGER PRIMARY KEY AUTOINCREMENT, mod TEXT, addr INT64 NOT NULL, text TEXT NOT NULL)")) + if(!sqlexec(userdb, "CREATE TABLE IF NOT EXISTS bookmarks (id INTEGER PRIMARY KEY AUTOINCREMENT, mod TEXT, addr INT64 NOT NULL)")) dprintf("SQL Error: %s\n", sqllasterror()); if(!sqlexec(userdb, "CREATE TABLE IF NOT EXISTS breakpoints (id INTEGER PRIMARY KEY AUTOINCREMENT, addr INT64 NOT NULL, enabled INT NOT NULL, singleshoot INT NOT NULL, oldbytes INT NOT NULL, type INT NOT NULL, titantype INT NOT NULL, mod TEXT, name TEXT)")) dprintf("SQL Error: %s\n", sqllasterror()); @@ -397,3 +399,79 @@ bool labeldel(uint addr) GuiUpdateAllViews(); return true; } + +///bookmark functions +bool bookmarkset(uint addr) +{ + if(!IsFileBeingDebugged() or !memisvalidreadptr(fdProcessInfo->hProcess, addr)) + return false; + char modname[35]=""; + char sql[deflen]=""; + if(!modnamefromaddr(addr, modname, true)) //bookmarks without module + { + sprintf(sql, "SELECT * FROM bookmarks WHERE mod IS NULL AND addr=%"fext"d", addr); + if(sqlhasresult(userdb, sql)) //there is a bookmark already + return true; + else //insert + sprintf(sql, "INSERT INTO bookmarks (addr) VALUES (%"fext"d)", addr); + } + else + { + uint modbase=modbasefromaddr(addr); + uint rva=addr-modbase; + sprintf(sql, "SELECT * FROM bookmarks WHERE mod='%s' AND addr=%"fext"d", modname, rva); + if(sqlhasresult(userdb, sql)) //there is a bookmark already + return true; + else //insert + sprintf(sql, "INSERT INTO bookmarks (mod,addr) VALUES ('%s',%"fext"d)", modname, rva); + } + if(!sqlexec(userdb, sql)) + { + dprintf("SQL Error: %s\nSQL Query: %s\n", sqllasterror(), sql); + return false; + } + GuiUpdateAllViews(); + dbsave(); + return true; +} + +bool bookmarkget(uint addr) +{ + if(!IsFileBeingDebugged() or !memisvalidreadptr(fdProcessInfo->hProcess, addr)) + return false; + char modname[35]=""; + char sql[deflen]=""; + if(!modnamefromaddr(addr, modname, true)) //bookmarks without module + sprintf(sql, "SELECT * FROM bookmarks WHERE mod IS NULL AND addr=%"fext"d", addr); + else + sprintf(sql, "SELECT * FROM bookmarks WHERE mod='%s' AND addr=%"fext"d", modname, addr-modbasefromaddr(addr)); + return sqlhasresult(userdb, sql); +} + +bool bookmarkdel(uint addr) +{ + if(!IsFileBeingDebugged() or !memisvalidreadptr(fdProcessInfo->hProcess, addr)) + return false; + char modname[35]=""; + char sql[deflen]=""; + if(!modnamefromaddr(addr, modname, true)) //bookmarks without module + sprintf(sql, "SELECT id FROM bookmarks WHERE mod IS NULL AND addr=%"fext"d", addr); + else + { + uint modbase=modbasefromaddr(addr); + uint rva=addr-modbase; + sprintf(sql, "SELECT id FROM bookmarks WHERE mod='%s' AND addr=%"fext"d", modname, rva); + } + int del_id=0; + if(!sqlgetint(userdb, sql, &del_id)) + return false; + sprintf(sql, "DELETE FROM bookmarks WHERE id=%d", del_id); + if(!sqlexec(userdb, sql)) + { + dprintf("SQL Error: %s\nSQL Query: %s\n", sqllasterror(), sql); + return false; + } + dbsave(); + GuiUpdateAllViews(); + return true; +} diff --git a/x64_dbg_dbg/addrinfo.h b/x64_dbg_dbg/addrinfo.h index cf1967f0..02f97d21 100644 --- a/x64_dbg_dbg/addrinfo.h +++ b/x64_dbg_dbg/addrinfo.h @@ -35,5 +35,8 @@ bool commentdel(uint addr); bool labelset(uint addr, const char* text); bool labelget(uint addr, char* text); bool labeldel(uint addr); +bool bookmarkset(uint addr); +bool bookmarkget(uint addr); +bool bookmarkdel(uint addr); #endif // _ADDRINFO_H diff --git a/x64_dbg_dbg/breakpoint.cpp b/x64_dbg_dbg/breakpoint.cpp index 5baffd9f..a5d7b9f4 100644 --- a/x64_dbg_dbg/breakpoint.cpp +++ b/x64_dbg_dbg/breakpoint.cpp @@ -20,7 +20,7 @@ bool bpnew(uint addr, bool enabled, bool singleshoot, short oldbytes, BP_TYPE ty return false; char modname[256]=""; char sql[deflen]=""; - char bpname[MAX_BREAKPOINT_NAME]=""; + char bpname[MAX_BREAKPOINT_SIZE]=""; if(modnamefromaddr(addr, modname, true)) //no module { uint modbase=modbasefromaddr(addr); @@ -56,7 +56,7 @@ bool bpget(uint addr, BP_TYPE type, const char* name, BREAKPOINT* bp) { char sql[deflen]=""; char modname[256]=""; - char bpname[MAX_BREAKPOINT_NAME]=""; + char bpname[MAX_BREAKPOINT_SIZE]=""; uint modbase=0; if(!modnamefromaddr(addr, modname, true)) //no module { @@ -178,7 +178,7 @@ bool bpsetname(uint addr, BP_TYPE type, const char* name) return false; char modname[256]=""; char sql[deflen]=""; - char bpname[MAX_BREAKPOINT_NAME]=""; + 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); diff --git a/x64_dbg_dbg/breakpoint.h b/x64_dbg_dbg/breakpoint.h index 4d146bc7..470023b4 100644 --- a/x64_dbg_dbg/breakpoint.h +++ b/x64_dbg_dbg/breakpoint.h @@ -4,8 +4,6 @@ #include "_global.h" #include "TitanEngine\TitanEngine.h" -#define MAX_BREAKPOINT_NAME 256 - //enums enum BP_TYPE { @@ -24,7 +22,7 @@ struct BREAKPOINT short oldbytes; BP_TYPE type; DWORD titantype; - char name[MAX_BREAKPOINT_NAME]; + char name[MAX_BREAKPOINT_SIZE]; char mod[32]; }; #pragma pack() diff --git a/x64_dbg_dbg/instruction.cpp b/x64_dbg_dbg/instruction.cpp index fda34084..75519c75 100644 --- a/x64_dbg_dbg/instruction.cpp +++ b/x64_dbg_dbg/instruction.cpp @@ -218,7 +218,10 @@ CMDRESULT cbInstrCmt(const char* cmd) return STATUS_ERROR; uint addr=0; if(!valfromstring(arg1, &addr, 0, 0, true, 0)) + { + dprintf("invalid address: \"%s\"\n", arg1); return STATUS_ERROR; + } char arg2[deflen]=""; if(!argget(cmd, arg2, 1, false)) return STATUS_ERROR; @@ -237,7 +240,10 @@ CMDRESULT cbInstrCmtdel(const char* cmd) return STATUS_ERROR; uint addr=0; if(!valfromstring(arg1, &addr, 0, 0, true, 0)) + { + dprintf("invalid address: \"%s\"\n", arg1); return STATUS_ERROR; + } if(!commentdel(addr)) { dputs("error deleting comment"); @@ -253,7 +259,10 @@ CMDRESULT cbInstrLbl(const char* cmd) return STATUS_ERROR; uint addr=0; if(!valfromstring(arg1, &addr, 0, 0, true, 0)) + { + dprintf("invalid address: \"%s\"\n", arg1); return STATUS_ERROR; + } char arg2[deflen]=""; if(!argget(cmd, arg2, 1, false)) return STATUS_ERROR; @@ -272,7 +281,11 @@ CMDRESULT cbInstrLbldel(const char* cmd) return STATUS_ERROR; uint addr=0; if(!valfromstring(arg1, &addr, 0, 0, true, 0)) + { + dprintf("invalid address: \"%s\"\n", arg1); return STATUS_ERROR; + } + if(!labeldel(addr)) { dputs("error deleting label"); @@ -281,6 +294,46 @@ CMDRESULT cbInstrLbldel(const char* cmd) return STATUS_CONTINUE; } +CMDRESULT cbInstrBookmarkSet(const char* cmd) +{ + char arg1[deflen]=""; + if(!argget(cmd, arg1, 0, false)) + return STATUS_ERROR; + uint addr=0; + if(!valfromstring(arg1, &addr, 0, 0, true, 0)) + { + dprintf("invalid address: \"%s\"\n", arg1); + return STATUS_ERROR; + } + if(!bookmarkset(addr)) + { + dputs("failed to set bookmark!"); + return STATUS_ERROR; + } + dputs("bookmark set!"); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrBookmarkDel(const char* cmd) +{ + char arg1[deflen]=""; + if(!argget(cmd, arg1, 0, false)) + return STATUS_ERROR; + uint addr=0; + if(!valfromstring(arg1, &addr, 0, 0, true, 0)) + { + dprintf("invalid address: \"%s\"\n", arg1); + return STATUS_ERROR; + } + if(!bookmarkdel(addr)) + { + dputs("failed to delete bookmark!"); + return STATUS_ERROR; + } + dputs("bookmark deleted!"); + return STATUS_CONTINUE; +} + CMDRESULT cbLoaddb(const char* cmd) { if(!dbload()) diff --git a/x64_dbg_dbg/instruction.h b/x64_dbg_dbg/instruction.h index 2d6efe90..5f106245 100644 --- a/x64_dbg_dbg/instruction.h +++ b/x64_dbg_dbg/instruction.h @@ -15,6 +15,8 @@ CMDRESULT cbInstrCmt(const char* cmd); CMDRESULT cbInstrCmtdel(const char* cmd); CMDRESULT cbInstrLbl(const char* cmd); CMDRESULT cbInstrLbldel(const char* cmd); +CMDRESULT cbInstrBookmarkSet(const char* cmd); +CMDRESULT cbInstrBookmarkDel(const char* cmd); CMDRESULT cbLoaddb(const char* cmd); CMDRESULT cbSavedb(const char* cmd); diff --git a/x64_dbg_dbg/x64_dbg.cpp b/x64_dbg_dbg/x64_dbg.cpp index 2ed4c85b..74d2a67e 100644 --- a/x64_dbg_dbg/x64_dbg.cpp +++ b/x64_dbg_dbg/x64_dbg.cpp @@ -69,6 +69,8 @@ static void registercommands() cmdnew(cmd, "cmtc\1cmtdel\1commentdel", cbInstrCmtdel, true); //delete comment cmdnew(cmd, "lbl\1lblset\1labelset", cbInstrLbl, true); //set/edit label cmdnew(cmd, "lblc\1lbldel\1labeldel", cbInstrLbldel, true); //delete label + cmdnew(cmd, "bookmark\1bookmarkset", cbInstrBookmarkSet, true); //set bookmark + cmdnew(cmd, "bookmarkc\1bookmarkdel", cbInstrBookmarkDel, true); //delete bookmark cmdnew(cmd, "savedb\1dbsave", cbSavedb, true); //save program database cmdnew(cmd, "loaddb\1dbload", cbLoaddb, true); //load program database cmdnew(cmd, "DeleteHardwareBreakpoint\1bphc\1bphwc", cbDebugDeleteHardwareBreakpoint, true); //delete hardware breakpoint diff --git a/x64_dbg_gui/Project/DebuggerX64.pro b/x64_dbg_gui/Project/DebuggerX64.pro index 6271744f..e02e2930 100644 --- a/x64_dbg_gui/Project/DebuggerX64.pro +++ b/x64_dbg_gui/Project/DebuggerX64.pro @@ -46,7 +46,8 @@ SOURCES += \ Src/BasicView/RegistersView.cpp \ Src/Gui/StatusLabel.cpp \ Src/BasicView/WordEditDialog.cpp \ - Src/Gui/CPUDisassembly.cpp + Src/Gui/CPUDisassembly.cpp \ + Src/BasicView/LineEditDialog.cpp HEADERS += \ @@ -73,7 +74,8 @@ HEADERS += \ Src/BasicView/RegistersView.h \ Src/Gui/StatusLabel.h \ Src/BasicView/WordEditDialog.h \ - Src/Gui/CPUDisassembly.h + Src/Gui/CPUDisassembly.h \ + Src/BasicView/LineEditDialog.h INCLUDEPATH += \ Src \ @@ -91,7 +93,8 @@ FORMS += \ Src/Dummy.ui \ Src/Gui/CPUWidget.ui \ Src/Gui/GotoDialog.ui \ - Src/BasicView/WordEditDialog.ui + Src/BasicView/WordEditDialog.ui \ + Src/BasicView/LineEditDialog.ui INCLUDEPATH += $$PWD/Src/Bridge diff --git a/x64_dbg_gui/Project/Src/BasicView/Disassembly.cpp b/x64_dbg_gui/Project/Src/BasicView/Disassembly.cpp index 6e530dd3..7fdebb2c 100644 --- a/x64_dbg_gui/Project/Src/BasicView/Disassembly.cpp +++ b/x64_dbg_gui/Project/Src/BasicView/Disassembly.cpp @@ -126,61 +126,80 @@ QString Disassembly::paintContent(QPainter* painter, int_t rowBase, int rowOffse else *label=0; BPXTYPE bpxtype=DbgGetBpxTypeAt(cur_addr); + bool isbookmark=DbgGetBookmarkAt(cur_addr); painter->save(); if(mInstBuffer.at(rowOffset).rva == mCipRva) //cip { - painter->fillRect(QRect(x, y, w, h), QBrush(QColor(0,0,0))); - if(bpxtype&bp_normal) //breakpoint + painter->fillRect(QRect(x, y, w, h), QBrush(QColor("#000000"))); + if(!isbookmark) { - painter->setPen(QPen(QColor("#ff0000"))); + if(bpxtype&bp_normal) //breakpoint + { + painter->setPen(QPen(QColor("#ff0000"))); + } + else + { + painter->setPen(QPen(QColor("#fffbf0"))); + } } else { - painter->setPen(QPen(QColor("#fffbf0"))); + painter->setPen(QPen(QColor("#fee970"))); } } else //other address { - if(*label) //label + if(!isbookmark) { - if(bpxtype==bp_none) //label only - painter->setPen(QPen(QColor("#ff0000"))); //red -> address + label text - else //label+breakpoint + if(*label) //label { - if(bpxtype&bp_normal) + if(bpxtype==bp_none) //label only + painter->setPen(QPen(QColor("#ff0000"))); //red -> address + label text + else //label+breakpoint { - painter->fillRect(QRect(x, y, w, h), QBrush(QColor("#ff0000"))); //fill red - } - else - { - painter->setPen(QPen(QColor("#000000"))); //black address + if(bpxtype&bp_normal) + { + painter->fillRect(QRect(x, y, w, h), QBrush(QColor("#ff0000"))); //fill red + } + else + { + painter->setPen(QPen(QColor("#000000"))); //black address + } } } - } - else //no label - { - if(bpxtype==bp_none) //no label, no breakpoint + else //no label { - if(wIsSelected) - painter->setPen(QPen(QColor("#000000"))); //black address - else - painter->setPen(QPen(QColor("#808080"))); - } - else //breakpoint only - { - if(bpxtype&bp_normal) - { - painter->fillRect(QRect(x, y, w, h), QBrush(QColor("#ff0000"))); //fill red - } - else + if(bpxtype==bp_none) //no label, no breakpoint { if(wIsSelected) painter->setPen(QPen(QColor("#000000"))); //black address else painter->setPen(QPen(QColor("#808080"))); } + else //breakpoint only + { + if(bpxtype&bp_normal) + { + painter->fillRect(QRect(x, y, w, h), QBrush(QColor("#ff0000"))); //fill red + } + else + { + if(wIsSelected) + painter->setPen(QPen(QColor("#000000"))); //black address + else + painter->setPen(QPen(QColor("#808080"))); + } + } } } + else + { + painter->fillRect(QRect(x, y, w, h), QBrush(QColor("#fee970"))); + if(wIsSelected) + painter->setPen(QPen(QColor("#000000"))); //black address + else + painter->setPen(QPen(QColor("#808080"))); + } } painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, addrText); painter->restore(); @@ -809,7 +828,7 @@ void Disassembly::prepareData() /************************************************************************************ Public Methods ************************************************************************************/ -int_t Disassembly::rvaToVa(int_t rva) +uint_t Disassembly::rvaToVa(int_t rva) { return mBase + rva; } diff --git a/x64_dbg_gui/Project/Src/BasicView/Disassembly.h b/x64_dbg_gui/Project/Src/BasicView/Disassembly.h index 80f259cc..5c62fea2 100644 --- a/x64_dbg_gui/Project/Src/BasicView/Disassembly.h +++ b/x64_dbg_gui/Project/Src/BasicView/Disassembly.h @@ -55,7 +55,7 @@ public: void prepareData(); // Public Methods - int_t rvaToVa(int_t rva); + uint_t rvaToVa(int_t rva); void disassembleClear(); signals: diff --git a/x64_dbg_gui/Project/Src/BasicView/LineEditDialog.cpp b/x64_dbg_gui/Project/Src/BasicView/LineEditDialog.cpp new file mode 100644 index 00000000..d5da7760 --- /dev/null +++ b/x64_dbg_gui/Project/Src/BasicView/LineEditDialog.cpp @@ -0,0 +1,27 @@ +#include "LineEditDialog.h" +#include "ui_LineEditDialog.h" + +LineEditDialog::LineEditDialog(QWidget *parent) : QDialog(parent), ui(new Ui::LineEditDialog) +{ + ui->setupUi(this); + setModal(true); + setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint); + setFixedSize(this->size()); //fixed size + setModal(true); //modal window +} + +LineEditDialog::~LineEditDialog() +{ + delete ui; +} + +void LineEditDialog::setText(const QString &text) +{ + ui->textEdit->setText(text); + ui->textEdit->selectAll(); +} + +void LineEditDialog::on_textEdit_textChanged(const QString &arg1) +{ + editText=arg1; +} diff --git a/x64_dbg_gui/Project/Src/BasicView/LineEditDialog.h b/x64_dbg_gui/Project/Src/BasicView/LineEditDialog.h new file mode 100644 index 00000000..8de68484 --- /dev/null +++ b/x64_dbg_gui/Project/Src/BasicView/LineEditDialog.h @@ -0,0 +1,27 @@ +#ifndef LINEEDITDIALOG_H +#define LINEEDITDIALOG_H + +#include + +namespace Ui { +class LineEditDialog; +} + +class LineEditDialog : public QDialog +{ + Q_OBJECT + +public: + explicit LineEditDialog(QWidget *parent = 0); + ~LineEditDialog(); + QString editText; + void setText(const QString &text); + +private slots: + void on_textEdit_textChanged(const QString &arg1); + +private: + Ui::LineEditDialog *ui; +}; + +#endif // LINEEDITDIALOG_H diff --git a/x64_dbg_gui/Project/Src/BasicView/LineEditDialog.ui b/x64_dbg_gui/Project/Src/BasicView/LineEditDialog.ui new file mode 100644 index 00000000..0467e6e5 --- /dev/null +++ b/x64_dbg_gui/Project/Src/BasicView/LineEditDialog.ui @@ -0,0 +1,107 @@ + + + LineEditDialog + + + + 0 + 0 + 373 + 72 + + + + Dialog + + + + :/icons/images/ui-combo-box-edit.png:/icons/images/ui-combo-box-edit.png + + + + + 10 + 10 + 351 + 53 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + &OK + + + true + + + + + + + &Cancel + + + + + + + + + + + + + + buttonOk + clicked() + LineEditDialog + accept() + + + 243 + 49 + + + 150 + 57 + + + + + buttonCancel + clicked() + LineEditDialog + close() + + + 320 + 51 + + + 150 + 41 + + + + + diff --git a/x64_dbg_gui/Project/Src/BasicView/RegistersView.cpp b/x64_dbg_gui/Project/Src/BasicView/RegistersView.cpp index 1c2f1436..1fc5716f 100644 --- a/x64_dbg_gui/Project/Src/BasicView/RegistersView.cpp +++ b/x64_dbg_gui/Project/Src/BasicView/RegistersView.cpp @@ -278,7 +278,7 @@ void RegistersView::updateRegistersSlot() void RegistersView::displayEditDialog() { - WordEditDialog wEditDial; + WordEditDialog wEditDial(this); QString wReg = mRegList->at(mSelected)->text(); #ifdef _WIN64 diff --git a/x64_dbg_gui/Project/Src/BasicView/RegistersView.h b/x64_dbg_gui/Project/Src/BasicView/RegistersView.h index 29257c91..fad22310 100644 --- a/x64_dbg_gui/Project/Src/BasicView/RegistersView.h +++ b/x64_dbg_gui/Project/Src/BasicView/RegistersView.h @@ -6,6 +6,7 @@ #include #include "Bridge.h" #include "WordEditDialog.h" +#include "LineEditDialog.h" namespace Ui { class RegistersView; diff --git a/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.cpp b/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.cpp index 8bf79a79..8e6b3ebd 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.cpp +++ b/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.cpp @@ -20,7 +20,7 @@ CPUDisassembly::CPUDisassembly(QWidget *parent) : Disassembly(parent) */ void CPUDisassembly::contextMenuEvent(QContextMenuEvent* event) { - int_t wVA = rvaToVa(getInitialSelection()); + uint_t wVA = rvaToVa(getInitialSelection()); BPXTYPE wBpType = DbgGetBpxTypeAt(wVA); if((wBpType & bp_hardware) == bp_hardware) @@ -32,7 +32,7 @@ void CPUDisassembly::contextMenuEvent(QContextMenuEvent* event) mToggleHwBpAction->setText("Set Hardware on Execution"); } - QAction* wAction = mRigthClickContextMenu->exec(event->globalPos()); + QAction* wAction = mRightClickContextMenu->exec(event->globalPos()); } @@ -41,13 +41,43 @@ void CPUDisassembly::contextMenuEvent(QContextMenuEvent* event) ************************************************************************************/ void CPUDisassembly::setupRightClickContextMenu() { - mRigthClickContextMenu = new QMenu(this); + mRightClickContextMenu = new QMenu(this); -//---------------------- Breakpoints ----------------------------- - QMenu* wBPMenu = new QMenu("Breakpoints", this); + //label/comment + mSetLabel = new QAction("Label", this); + mSetLabel->setShortcutContext(Qt::WidgetShortcut); + mSetLabel->setShortcut(QKeySequence(":")); + this->addAction(mSetLabel); + connect(mSetLabel, SIGNAL(triggered()), this, SLOT(setLabel())); - // INT3 BP - mToggleInt3BpAction = new QAction("Toggle INT3", this); + mSetComment = new QAction("Comment", this); + mSetComment->setShortcutContext(Qt::WidgetShortcut); + mSetComment->setShortcut(QKeySequence(";")); + this->addAction(mSetComment); + connect(mSetComment, SIGNAL(triggered()), this, SLOT(setComment())); + + mSetBookmark = new QAction("Bookmark", this); + mSetBookmark->setShortcutContext(Qt::WidgetShortcut); + mSetBookmark->setShortcut(QKeySequence("ctrl+d")); + this->addAction(mSetBookmark); + connect(mSetBookmark, SIGNAL(triggered()), this, SLOT(setBookmark())); + + + //---------------------- Go to ----------------------------------- + QMenu* wGotoMenu = new QMenu("Go to", this); + mGotoOrigin = new QAction("Origin", this); + mGotoOrigin->setShortcutContext(Qt::WidgetShortcut); + mGotoOrigin->setShortcut(QKeySequence("*")); + this->addAction(mGotoOrigin); + connect(mGotoOrigin, SIGNAL(triggered()), this, SLOT(gotoOrigin())); + wGotoMenu->addAction(mGotoOrigin); + + + //---------------------- Breakpoints ----------------------------- + QMenu* wBPMenu = new QMenu("Breakpoint", this); + + // Standard breakpoint (option set using SetBPXOption) + mToggleInt3BpAction = new QAction("Toggle", this); mToggleInt3BpAction->setShortcutContext(Qt::WidgetShortcut); mToggleInt3BpAction->setShortcut(QKeySequence(Qt::Key_F2)); this->addAction(mToggleInt3BpAction); @@ -59,25 +89,32 @@ void CPUDisassembly::setupRightClickContextMenu() connect(mToggleHwBpAction, SIGNAL(triggered()), this, SLOT(toggleHwBpActionSlot())); wBPMenu->addAction(mToggleHwBpAction); - mRigthClickContextMenu->addMenu(wBPMenu); - - // Separator - mRigthClickContextMenu->addSeparator(); - -//---------------------- New origin here ----------------------------- + //---------------------- New origin here ----------------------------- mSetNewOriginHere = new QAction("Set New Origin Here", this); mSetNewOriginHere->setShortcutContext(Qt::WidgetShortcut); mSetNewOriginHere->setShortcut(QKeySequence("ctrl+*")); this->addAction(mSetNewOriginHere); connect(mSetNewOriginHere, SIGNAL(triggered()), this, SLOT(setNewOriginHereActionSlot())); - mRigthClickContextMenu->addAction(mSetNewOriginHere); + //Add to menu + mRightClickContextMenu->addAction(mSetLabel); + mRightClickContextMenu->addAction(mSetComment); + mRightClickContextMenu->addAction(mSetBookmark); + mRightClickContextMenu->addMenu(wBPMenu); //Breakpoint-> + mRightClickContextMenu->addSeparator(); //Seperator + mRightClickContextMenu->addMenu(wGotoMenu); //Go to-> + mRightClickContextMenu->addAction(mSetNewOriginHere); //New origin here +} + +void CPUDisassembly::gotoOrigin() +{ + Bridge::getBridge()->execCmd("d cip"); } void CPUDisassembly::toggleInt3BPAction() { - int_t wVA = rvaToVa(getInitialSelection()); + uint_t wVA = rvaToVa(getInitialSelection()); BPXTYPE wBpType = DbgGetBpxTypeAt(wVA); QString wCmd; @@ -96,7 +133,7 @@ void CPUDisassembly::toggleInt3BPAction() void CPUDisassembly::toggleHwBpActionSlot() { - int_t wVA = rvaToVa(getInitialSelection()); + uint_t wVA = rvaToVa(getInitialSelection()); BPXTYPE wBpType = DbgGetBpxTypeAt(wVA); QString wCmd; @@ -115,7 +152,61 @@ void CPUDisassembly::toggleHwBpActionSlot() void CPUDisassembly::setNewOriginHereActionSlot() { - int_t wVA = rvaToVa(getInitialSelection()); + uint_t wVA = rvaToVa(getInitialSelection()); QString wCmd = "cip=" + QString("%1").arg(wVA, sizeof(int_t) * 2, 16, QChar('0')).toUpper(); Bridge::getBridge()->execCmd(wCmd.toUtf8().constData()); } + +void CPUDisassembly::setLabel() +{ + uint_t wVA = rvaToVa(getInitialSelection()); + LineEditDialog mLineEdit(this); + QString addr_text=QString("%1").arg(wVA, sizeof(int_t) * 2, 16, QChar('0')).toUpper(); + char label_text[MAX_COMMENT_SIZE]=""; + if(DbgGetLabelAt((duint)wVA, SEG_DEFAULT, label_text)) + mLineEdit.setText(QString(label_text)); + mLineEdit.setWindowTitle("Add label at " + addr_text); + if(mLineEdit.exec()!=QDialog::Accepted) + return; + if(!DbgSetLabelAt(wVA, mLineEdit.editText.toUtf8().constData())) + { + QMessageBox msg(QMessageBox::Critical, "Error!", "DbgSetLabelAt failed!"); + msg.setWindowIcon(QIcon(":/icons/images/compile-error.png")); + msg.exec(); + } +} + +void CPUDisassembly::setComment() +{ + uint_t wVA = rvaToVa(getInitialSelection()); + LineEditDialog mLineEdit(this); + QString addr_text=QString("%1").arg(wVA, sizeof(int_t) * 2, 16, QChar('0')).toUpper(); + char comment_text[MAX_COMMENT_SIZE]=""; + if(DbgGetCommentAt((duint)wVA, comment_text)) + mLineEdit.setText(QString(comment_text)); + mLineEdit.setWindowTitle("Add comment at " + addr_text); + if(mLineEdit.exec()!=QDialog::Accepted) + return; + if(!DbgSetCommentAt(wVA, mLineEdit.editText.toUtf8().constData())) + { + QMessageBox msg(QMessageBox::Critical, "Error!", "DbgSetCommentAt failed!"); + msg.setWindowIcon(QIcon(":/icons/images/compile-error.png")); + msg.exec(); + } +} + +void CPUDisassembly::setBookmark() +{ + uint_t wVA = rvaToVa(getInitialSelection()); + bool result; + if(DbgGetBookmarkAt(wVA)) + result=DbgSetBookmarkAt(wVA, false); + else + result=DbgSetBookmarkAt(wVA, true); + if(!result) + { + QMessageBox msg(QMessageBox::Critical, "Error!", "DbgSetBookmarkAt failed!"); + msg.setWindowIcon(QIcon(":/icons/images/compile-error.png")); + msg.exec(); + } +} diff --git a/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.h b/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.h index 04de482c..1d4c5a59 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.h +++ b/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.h @@ -6,7 +6,7 @@ #include "NewTypes.h" #include "Disassembly.h" #include "Bridge.h" - +#include "LineEditDialog.h" class CPUDisassembly : public Disassembly { @@ -26,14 +26,22 @@ public slots: void toggleInt3BPAction(); void toggleHwBpActionSlot(); void setNewOriginHereActionSlot(); + void gotoOrigin(); + void setLabel(); + void setComment(); + void setBookmark(); private: // Rigth Click Context Menu - QMenu* mRigthClickContextMenu; + QMenu* mRightClickContextMenu; QAction* mToggleInt3BpAction; QAction* mToggleHwBpAction; QAction* mSetNewOriginHere; + QAction* mGotoOrigin; + QAction* mSetComment; + QAction* mSetLabel; + QAction* mSetBookmark; }; #endif // CPUDISASSEMBLY_H diff --git a/x64_dbg_gui/Project/Src/Gui/GotoDialog.cpp b/x64_dbg_gui/Project/Src/Gui/GotoDialog.cpp index fb958855..319c44ba 100644 --- a/x64_dbg_gui/Project/Src/Gui/GotoDialog.cpp +++ b/x64_dbg_gui/Project/Src/Gui/GotoDialog.cpp @@ -7,9 +7,9 @@ GotoDialog::GotoDialog(QWidget *parent) : { //setup UI first ui->setupUi(this); - setWindowFlags(Qt::MSWindowsFixedSizeDialogHint); + setModal(true); + setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint); setFixedSize(this->size()); //fixed size - setModal(true); //modal window //initialize stuff if(!DbgIsDebugging()) //not debugging ui->labelError->setText("Not debugging..."); diff --git a/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp b/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp index a3a8d2b1..44aea90f 100644 --- a/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp +++ b/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp @@ -161,7 +161,7 @@ void MainWindow::displayAboutWidget() void MainWindow::on_actionGoto_triggered() { - GotoDialog mGoto; + GotoDialog mGoto(this); if(mGoto.exec()==QDialog::Accepted) { QString cmd; diff --git a/x64_dbg_gui/Project/images/compile-error.png b/x64_dbg_gui/Project/images/compile-error.png new file mode 100644 index 0000000000000000000000000000000000000000..0b32abc2f0721778bf72adf9b76a8dc7ed3790e0 GIT binary patch literal 638 zcmV-^0)hRBP)6S z7Z-gR9=_G18~Y9d)%QzF*(2$6X01>_O4v#TDLUWI=Y2NPjl5DHe*wp-nUC6=;{ov! zmpESlrq46o&l3|SKQLfE<#I;$!b_zTPbXe9#o9Yv;@3CIr`JVs- Y0J;0x5IN^6CIA2c07*qoM6N<$f-h?#%K!iX literal 0 HcmV?d00001 diff --git a/x64_dbg_gui/Project/resource.qrc b/x64_dbg_gui/Project/resource.qrc index 39a018f4..f365ba22 100644 --- a/x64_dbg_gui/Project/resource.qrc +++ b/x64_dbg_gui/Project/resource.qrc @@ -17,5 +17,6 @@ images/processor-cpu.png images/ui-combo-box-edit.png images/scylla.png + images/compile-error.png