DBG: comment database working again (using JSON)
This commit is contained in:
parent
289f11db05
commit
8ba093b0ba
|
@ -410,18 +410,18 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoset(duint addr, ADDRINFO* addrinfo)
|
|||
bool retval=false;
|
||||
if(addrinfo->flags&flaglabel) //set label
|
||||
{
|
||||
if(labelset(addr, addrinfo->label))
|
||||
if(labelset(addr, addrinfo->label, true))
|
||||
retval=true;
|
||||
}
|
||||
if(addrinfo->flags&flagcomment) //set comment
|
||||
{
|
||||
if(commentset(addr, addrinfo->comment))
|
||||
if(commentset(addr, addrinfo->comment, true))
|
||||
retval=true;
|
||||
}
|
||||
if(addrinfo->flags&flagbookmark) //set bookmark
|
||||
{
|
||||
if(addrinfo->isbookmark)
|
||||
retval=bookmarkset(addr);
|
||||
retval=bookmarkset(addr, true);
|
||||
else
|
||||
retval=bookmarkdel(addr);
|
||||
}
|
||||
|
|
|
@ -13,35 +13,28 @@ static BookmarksInfo bookmarks;
|
|||
static FunctionsInfo functions;
|
||||
static LoopsInfo loops;
|
||||
|
||||
///basic database functions
|
||||
void dbinit()
|
||||
//database functions
|
||||
void dbsave()
|
||||
{
|
||||
dbreadcache();
|
||||
JSON root=json_object();
|
||||
commentcachesave(root);
|
||||
json_dump_file(root, dbpath, JSON_INDENT(4)|JSON_SORT_KEYS);
|
||||
json_decref(root); //free root
|
||||
}
|
||||
|
||||
bool dbload()
|
||||
void dbload()
|
||||
{
|
||||
return true;
|
||||
JSON root=json_load_file(dbpath, 0, 0);
|
||||
if(!root)
|
||||
return;
|
||||
commentcacheload(root);
|
||||
json_decref(root); //free root
|
||||
}
|
||||
|
||||
bool dbsave()
|
||||
void dbupdate()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void dbreadcache()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void dbwritecache()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void dbclose()
|
||||
{
|
||||
dbwritecache();
|
||||
dbsave(); //flush cache to disk
|
||||
dbload(); //load database to cache (and update the module bases + VAs)
|
||||
}
|
||||
|
||||
///module functions
|
||||
|
@ -74,11 +67,13 @@ bool modload(uint base, uint size, const char* fullpath)
|
|||
_strlwr(info.name);
|
||||
modinfo.push_back(info);
|
||||
symupdatemodulelist();
|
||||
dbupdate();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool modunload(uint base)
|
||||
{
|
||||
dbupdate();
|
||||
int total=modinfo.size();
|
||||
for(int i=0; i<total; i++)
|
||||
{
|
||||
|
@ -229,20 +224,21 @@ bool apienumexports(uint base, EXPORTENUMCALLBACK cbEnum)
|
|||
}
|
||||
|
||||
///comment functions
|
||||
bool commentset(uint addr, const char* text)
|
||||
bool commentset(uint addr, const char* text, bool manual)
|
||||
{
|
||||
if(!DbgIsDebugging() or !memisvalidreadptr(fdProcessInfo->hProcess, addr) or !text or strlen(text)>=MAX_COMMENT_SIZE-1)
|
||||
return false;
|
||||
if(!*text) //NOTE: delete when there is no text
|
||||
return commentdel(addr);
|
||||
COMMENTSINFO info;
|
||||
strcpy(info.text, text);
|
||||
modnamefromaddr(addr, info.mod, true);
|
||||
info.addr=addr-modbasefromaddr(addr);
|
||||
COMMENTSINFO comment;
|
||||
comment.manual=manual;
|
||||
strcpy(comment.text, text);
|
||||
modnamefromaddr(addr, comment.mod, true);
|
||||
comment.addr=addr-modbasefromaddr(addr);
|
||||
if(comments.count(addr)) //contains addr
|
||||
comments[addr]=info;
|
||||
comments[addr]=comment;
|
||||
else
|
||||
comments.insert(std::make_pair(addr, info));
|
||||
comments.insert(std::make_pair(addr, comment));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -270,14 +266,99 @@ bool commentdel(uint addr)
|
|||
return false;
|
||||
}
|
||||
|
||||
void commentcachesave(JSON root)
|
||||
{
|
||||
JSON jsoncomments=json_array();
|
||||
JSON jsonautocomments=json_array();
|
||||
for(CommentsInfo::iterator i=comments.begin(); i!=comments.end(); ++i)
|
||||
{
|
||||
COMMENTSINFO curComment=i->second;
|
||||
JSON curjsoncomment=json_object();
|
||||
if(*curComment.mod)
|
||||
json_object_set_new(curjsoncomment, "module", json_string(curComment.mod));
|
||||
else
|
||||
json_object_set_new(curjsoncomment, "module", json_null());
|
||||
json_object_set_new(curjsoncomment, "address", json_hex(curComment.addr));
|
||||
json_object_set_new(curjsoncomment, "text", json_string(curComment.text));
|
||||
if(curComment.manual)
|
||||
json_array_append_new(jsoncomments, curjsoncomment);
|
||||
else
|
||||
json_array_append_new(jsonautocomments, curjsoncomment);
|
||||
}
|
||||
if(json_array_size(jsoncomments))
|
||||
json_object_set(root, "comments", jsoncomments);
|
||||
json_decref(jsoncomments);
|
||||
if(json_array_size(jsonautocomments))
|
||||
json_object_set(root, "autocomments", jsonautocomments);
|
||||
json_decref(jsonautocomments);
|
||||
}
|
||||
|
||||
void commentcacheload(JSON root)
|
||||
{
|
||||
comments.clear();
|
||||
JSON jsoncomments=json_object_get(root, "comments");
|
||||
if(jsoncomments)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsoncomments, i, value)
|
||||
{
|
||||
COMMENTSINFO curComment;
|
||||
const char* mod=json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod)<MAX_MODULE_SIZE)
|
||||
strcpy(curComment.mod, mod);
|
||||
else
|
||||
*curComment.mod='\0';
|
||||
curComment.addr=json_hex_value(json_object_get(value, "address"));
|
||||
if(!curComment.addr)
|
||||
continue; //skip
|
||||
curComment.manual=true;
|
||||
const char* text=json_string_value(json_object_get(value, "text"));
|
||||
if(text)
|
||||
strcpy(curComment.text, text);
|
||||
else
|
||||
continue; //skip
|
||||
uint modbase=modbasefromname(curComment.mod);
|
||||
comments.insert(std::make_pair(curComment.addr+modbase, curComment));
|
||||
}
|
||||
}
|
||||
JSON jsonautocomments=json_object_get(root, "autocomments");
|
||||
if(jsonautocomments)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsonautocomments, i, value)
|
||||
{
|
||||
COMMENTSINFO curComment;
|
||||
const char* mod=json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod)<MAX_MODULE_SIZE)
|
||||
strcpy(curComment.mod, mod);
|
||||
else
|
||||
*curComment.mod='\0';
|
||||
curComment.addr=json_hex_value(json_object_get(value, "address"));
|
||||
if(!curComment.addr)
|
||||
continue; //skip
|
||||
curComment.manual=false;
|
||||
const char* text=json_string_value(json_object_get(value, "text"));
|
||||
if(text)
|
||||
strcpy(curComment.text, text);
|
||||
else
|
||||
continue; //skip
|
||||
uint modbase=modbasefromname(curComment.mod);
|
||||
comments.insert(std::make_pair(curComment.addr+modbase, curComment));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///label functions
|
||||
bool labelset(uint addr, const char* text)
|
||||
bool labelset(uint addr, const char* text, bool manual)
|
||||
{
|
||||
if(!DbgIsDebugging() or !memisvalidreadptr(fdProcessInfo->hProcess, addr) or !text or strlen(text)>=MAX_LABEL_SIZE-1)
|
||||
return false;
|
||||
if(!*text) //NOTE: delete when there is no text
|
||||
return labeldel(addr);
|
||||
LABELSINFO label;
|
||||
label.manual=manual;
|
||||
strcpy(label.text, text);
|
||||
modnamefromaddr(addr, label.mod, true);
|
||||
label.addr=addr-modbasefromaddr(addr);
|
||||
|
@ -329,13 +410,14 @@ bool labeldel(uint addr)
|
|||
}
|
||||
|
||||
///bookmark functions
|
||||
bool bookmarkset(uint addr)
|
||||
bool bookmarkset(uint addr, bool manual)
|
||||
{
|
||||
if(!DbgIsDebugging() or !memisvalidreadptr(fdProcessInfo->hProcess, addr))
|
||||
return false;
|
||||
BOOKMARKSINFO bookmark;
|
||||
modnamefromaddr(addr, bookmark.mod, true);
|
||||
bookmark.addr=addr-modbasefromaddr(addr);
|
||||
bookmark.manual=manual;
|
||||
bookmarks.insert(std::make_pair(addr, bookmark));
|
||||
return true;
|
||||
}
|
||||
|
@ -362,6 +444,22 @@ bool bookmarkdel(uint addr)
|
|||
}
|
||||
|
||||
///function database
|
||||
bool functionadd(uint start, uint end, bool manual)
|
||||
{
|
||||
if(!DbgIsDebugging() or end<start or memfindbaseaddr(fdProcessInfo->hProcess, start, 0)!=memfindbaseaddr(fdProcessInfo->hProcess, end, 0)!=0) //the function boundaries are not in the same mem page
|
||||
return false;
|
||||
if(functionoverlaps(start, end))
|
||||
return false;
|
||||
FUNCTIONSINFO function;
|
||||
modnamefromaddr(start, function.mod, true);
|
||||
function.modbase=modbasefromaddr(start);
|
||||
function.start=start-function.modbase;
|
||||
function.end=end-function.modbase;
|
||||
function.manual=manual;
|
||||
functions.push_back(function);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool functionget(uint addr, uint* start, uint* end)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
|
@ -395,22 +493,6 @@ bool functionoverlaps(uint start, uint end)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool functionadd(uint start, uint end, bool manual)
|
||||
{
|
||||
if(!DbgIsDebugging() or end<start or memfindbaseaddr(fdProcessInfo->hProcess, start, 0)!=memfindbaseaddr(fdProcessInfo->hProcess, end, 0)!=0) //the function boundaries are not in the same mem page
|
||||
return false;
|
||||
if(functionoverlaps(start, end))
|
||||
return false;
|
||||
FUNCTIONSINFO function;
|
||||
modnamefromaddr(start, function.mod, true);
|
||||
function.modbase=modbasefromaddr(start);
|
||||
function.start=start-function.modbase;
|
||||
function.end=end-function.modbase;
|
||||
function.manual=manual;
|
||||
functions.push_back(function);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool functiondel(uint addr)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
|
@ -427,6 +509,28 @@ bool functiondel(uint addr)
|
|||
return false;
|
||||
}
|
||||
|
||||
//loop database
|
||||
bool loopadd(uint start, uint end, bool manual)
|
||||
{
|
||||
if(!DbgIsDebugging() or end<start or memfindbaseaddr(fdProcessInfo->hProcess, start, 0)!=memfindbaseaddr(fdProcessInfo->hProcess, end, 0)!=0) //the function boundaries are not in the same mem page
|
||||
return false;
|
||||
int finaldepth;
|
||||
if(loopoverlaps(0, start, end, &finaldepth)) //loop cannot overlap another loop
|
||||
return false;
|
||||
LOOPSINFO loop;
|
||||
modnamefromaddr(start, loop.mod, true);
|
||||
loop.modbase=modbasefromaddr(start);
|
||||
loop.start=start-loop.modbase;
|
||||
loop.end=end-loop.modbase;
|
||||
loop.depth=finaldepth;
|
||||
if(finaldepth)
|
||||
loop.parent=finaldepth-1;
|
||||
else
|
||||
loop.parent=0;
|
||||
loop.manual=manual;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool loopget(int depth, uint addr, uint* start, uint* end)
|
||||
{
|
||||
if(!DbgIsDebugging() or !memisvalidreadptr(fdProcessInfo->hProcess, addr))
|
||||
|
@ -446,27 +550,6 @@ bool loopget(int depth, uint addr, uint* start, uint* end)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool loopadd(uint start, uint end, bool manual)
|
||||
{
|
||||
if(!DbgIsDebugging() or end<start or memfindbaseaddr(fdProcessInfo->hProcess, start, 0)!=memfindbaseaddr(fdProcessInfo->hProcess, end, 0)!=0) //the function boundaries are not in the same mem page
|
||||
return false;
|
||||
int finaldepth;
|
||||
if(loopoverlaps(0, start, end, &finaldepth)) //loop cannot overlap another loop
|
||||
return false;
|
||||
LOOPSINFO loop;
|
||||
modnamefromaddr(start, loop.mod, true);
|
||||
loop.modbase=modbasefromaddr(start);
|
||||
loop.start=start-loop.modbase;
|
||||
loop.end=end-loop.modbase;
|
||||
loop.depth=finaldepth;
|
||||
if(finaldepth)
|
||||
loop.parent=finaldepth-1;
|
||||
else
|
||||
loop.parent=0;
|
||||
loop.manual=manual;
|
||||
return false;
|
||||
}
|
||||
|
||||
//check if a loop overlaps a range, inside is not overlapping
|
||||
bool loopoverlaps(int depth, uint start, uint end, int* finaldepth)
|
||||
{
|
||||
|
|
|
@ -17,6 +17,7 @@ struct COMMENTSINFO
|
|||
char mod[MAX_MODULE_SIZE];
|
||||
uint addr;
|
||||
char text[MAX_COMMENT_SIZE];
|
||||
bool manual;
|
||||
};
|
||||
|
||||
struct LABELSINFO
|
||||
|
@ -24,12 +25,14 @@ struct LABELSINFO
|
|||
char mod[MAX_MODULE_SIZE];
|
||||
uint addr;
|
||||
char text[MAX_LABEL_SIZE];
|
||||
bool manual;
|
||||
};
|
||||
|
||||
struct BOOKMARKSINFO
|
||||
{
|
||||
char mod[MAX_MODULE_SIZE];
|
||||
uint addr;
|
||||
bool manual;
|
||||
};
|
||||
|
||||
struct FUNCTIONSINFO
|
||||
|
@ -62,12 +65,9 @@ typedef std::map<uint, BOOKMARKSINFO> BookmarksInfo;
|
|||
typedef std::vector<FUNCTIONSINFO> FunctionsInfo;
|
||||
typedef std::vector<LOOPSINFO> LoopsInfo;
|
||||
|
||||
void dbinit();
|
||||
bool dbsave();
|
||||
bool dbload();
|
||||
void dbreadcache();
|
||||
void dbwritecache();
|
||||
void dbclose();
|
||||
void dbsave();
|
||||
void dbload();
|
||||
void dbupdate();
|
||||
|
||||
bool modload(uint base, uint size, const char* fullpath);
|
||||
bool modunload(uint base);
|
||||
|
@ -78,27 +78,29 @@ uint modbasefromname(const char* modname);
|
|||
|
||||
bool apienumexports(uint base, EXPORTENUMCALLBACK cbEnum);
|
||||
|
||||
bool commentset(uint addr, const char* text);
|
||||
bool commentset(uint addr, const char* text, bool manual);
|
||||
bool commentget(uint addr, char* text);
|
||||
bool commentdel(uint addr);
|
||||
void commentcachesave(JSON root);
|
||||
void commentcacheload(JSON root);
|
||||
|
||||
bool labelset(uint addr, const char* text);
|
||||
bool labelset(uint addr, const char* text, bool manual);
|
||||
bool labelfromstring(const char* text, uint* addr);
|
||||
bool labelget(uint addr, char* text);
|
||||
bool labeldel(uint addr);
|
||||
|
||||
bool bookmarkset(uint addr);
|
||||
bool bookmarkset(uint addr, bool manual);
|
||||
bool bookmarkget(uint addr);
|
||||
bool bookmarkdel(uint addr);
|
||||
|
||||
bool functionadd(uint start, uint end, bool manual);
|
||||
bool functionget(uint addr, uint* start, uint* end);
|
||||
bool functionoverlaps(uint start, uint end);
|
||||
bool functionadd(uint start, uint end, bool manual);
|
||||
bool functiondel(uint addr);
|
||||
|
||||
bool loopadd(uint start, uint end, bool manual);
|
||||
bool loopget(int depth, uint addr, uint* start, uint* end);
|
||||
bool loopoverlaps(int depth, uint start, uint end, int* finaldepth);
|
||||
bool loopadd(uint start, uint end, bool manual);
|
||||
bool loopdel(int depth, uint addr);
|
||||
|
||||
#endif // _ADDRINFO_H
|
||||
|
|
|
@ -518,7 +518,7 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
|
|||
#endif // _WIN64
|
||||
sprintf(dbpath, "%s\\%s", dbbasepath, sqlitedb);
|
||||
dprintf("Database file: %s\n", dbpath);
|
||||
dbinit();
|
||||
dbload();
|
||||
SymSetOptions(SYMOPT_DEBUG|SYMOPT_LOAD_LINES);
|
||||
GuiSymbolLogClear();
|
||||
SymInitialize(fdProcessInfo->hProcess, 0, false); //initialize symbols
|
||||
|
@ -1007,7 +1007,7 @@ static DWORD WINAPI threadDebugLoop(void* lpParameter)
|
|||
//message the user/do final stuff
|
||||
RemoveAllBreakPoints(UE_OPTION_REMOVEALL); //remove all breakpoints
|
||||
//cleanup
|
||||
dbclose();
|
||||
dbsave();
|
||||
modclear();
|
||||
threadclear();
|
||||
GuiSetDebugState(stopped);
|
||||
|
@ -1955,7 +1955,7 @@ static DWORD WINAPI threadAttachLoop(void* lpParameter)
|
|||
plugincbcall(CB_STOPDEBUG, &stopInfo);
|
||||
//message the user/do final stuff
|
||||
RemoveAllBreakPoints(UE_OPTION_REMOVEALL); //remove all breakpoints
|
||||
dbclose();
|
||||
dbsave();
|
||||
modclear();
|
||||
GuiSetDebugState(stopped);
|
||||
dputs("debugging stopped!");
|
||||
|
|
|
@ -236,7 +236,7 @@ CMDRESULT cbInstrCmt(int argc, char* argv[])
|
|||
uint addr=0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
if(!commentset(addr, argv[2]))
|
||||
if(!commentset(addr, argv[2], true))
|
||||
{
|
||||
dputs("error setting comment");
|
||||
return STATUS_ERROR;
|
||||
|
@ -273,7 +273,7 @@ CMDRESULT cbInstrLbl(int argc, char* argv[])
|
|||
uint addr=0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
if(!labelset(addr, argv[2]))
|
||||
if(!labelset(addr, argv[2], true))
|
||||
{
|
||||
dputs("error setting label");
|
||||
return STATUS_ERROR;
|
||||
|
@ -310,7 +310,7 @@ CMDRESULT cbInstrBookmarkSet(int argc, char* argv[])
|
|||
uint addr=0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
if(!bookmarkset(addr))
|
||||
if(!bookmarkset(addr, true))
|
||||
{
|
||||
dputs("failed to set bookmark!");
|
||||
return STATUS_ERROR;
|
||||
|
@ -340,22 +340,14 @@ CMDRESULT cbInstrBookmarkDel(int argc, char* argv[])
|
|||
|
||||
CMDRESULT cbLoaddb(int argc, char* argv[])
|
||||
{
|
||||
if(!dbload())
|
||||
{
|
||||
dputs("failed to load database from disk!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dbload();
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbSavedb(int argc, char* argv[])
|
||||
{
|
||||
if(!dbsave())
|
||||
{
|
||||
dputs("failed to save database to disk!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dbsave();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -209,8 +209,19 @@ static DWORD WINAPI DbgCommandLoopThread(void* a)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void* emalloc_json(size_t size)
|
||||
{
|
||||
return emalloc(size, "json:ptr");
|
||||
}
|
||||
|
||||
static void efree_json(void* ptr)
|
||||
{
|
||||
efree(ptr, "json:ptr");
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT const char* _dbg_dbginit()
|
||||
{
|
||||
json_set_alloc_funcs(emalloc_json, efree_json);
|
||||
char dir[deflen]="";
|
||||
if(!GetModuleFileNameA(hInst, dir, deflen))
|
||||
return "GetModuleFileNameA failed!";
|
||||
|
|
Loading…
Reference in New Issue