1
0
Fork 0

DBG: comment database working again (using JSON)

This commit is contained in:
Mr. eXoDia 2014-06-19 00:44:43 +02:00
parent 289f11db05
commit 8ba093b0ba
6 changed files with 186 additions and 98 deletions

View File

@ -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);
}

View File

@ -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)
{

View File

@ -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

View File

@ -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!");

View File

@ -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;
}

View File

@ -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!";