DBG: save functions & loops to database
This commit is contained in:
parent
974be7ee3e
commit
d0160f2f0a
|
|
@ -25,6 +25,8 @@ void dbsave()
|
|||
commentcachesave(root);
|
||||
labelcachesave(root);
|
||||
bookmarkcachesave(root);
|
||||
functioncachesave(root);
|
||||
loopcachesave(root);
|
||||
if(json_object_size(root))
|
||||
json_dump_file(root, dbpath, JSON_INDENT(4));
|
||||
json_decref(root); //free root
|
||||
|
|
@ -44,6 +46,8 @@ void dbload()
|
|||
commentcacheload(root);
|
||||
labelcacheload(root);
|
||||
bookmarkcacheload(root);
|
||||
functioncacheload(root);
|
||||
loopcacheload(root);
|
||||
json_decref(root); //free root
|
||||
dprintf("%ums\n", GetTickCount()-ticks);
|
||||
}
|
||||
|
|
@ -52,6 +56,10 @@ void dbclose()
|
|||
{
|
||||
dbsave();
|
||||
CommentsInfo().swap(comments);
|
||||
LabelsInfo().swap(labels);
|
||||
BookmarksInfo().swap(bookmarks);
|
||||
FunctionsInfo().swap(functions);
|
||||
LoopsInfo().swap(loops);
|
||||
}
|
||||
|
||||
///module functions
|
||||
|
|
@ -388,7 +396,7 @@ bool labelget(uint addr, char* text)
|
|||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
LabelsInfo::iterator found=labels.find(modhashfromva(addr));
|
||||
const LabelsInfo::iterator found=labels.find(modhashfromva(addr));
|
||||
if(found==labels.end()) //not found
|
||||
return false;
|
||||
if(text)
|
||||
|
|
@ -585,17 +593,20 @@ void bookmarkcacheload(JSON root)
|
|||
///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
|
||||
if(!DbgIsDebugging() or end<start)
|
||||
return false;
|
||||
uint page=memfindbaseaddr(fdProcessInfo->hProcess, start, 0);
|
||||
if(!page or page!=memfindbaseaddr(fdProcessInfo->hProcess, end, 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;
|
||||
uint modbase=modbasefromaddr(start);
|
||||
function.start=start-modbase;
|
||||
function.end=end-modbase;
|
||||
function.manual=manual;
|
||||
functions.push_back(function);
|
||||
functions.insert(std::make_pair(ModuleRange(modhashfromva(modbase), Range(function.start, function.end)), function));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -603,90 +614,148 @@ bool functionget(uint addr, uint* start, uint* end)
|
|||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
for(FunctionsInfo::iterator i=functions.begin(); i!=functions.end(); ++i)
|
||||
{
|
||||
uint curAddr=addr-i->modbase;
|
||||
if(i->start<=curAddr and i->end>=curAddr)
|
||||
{
|
||||
if(start)
|
||||
*start=i->start+i->modbase;
|
||||
if(end)
|
||||
*end=i->end+i->modbase;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
uint modbase=modbasefromaddr(addr);
|
||||
const FunctionsInfo::iterator found=functions.find(ModuleRange(modhashfromva(modbase), Range(addr-modbase, addr-modbase)));
|
||||
if(found==functions.end()) //not found
|
||||
return false;
|
||||
if(start)
|
||||
*start=found->second.start+modbase;
|
||||
if(end)
|
||||
*end=found->second.end+modbase;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool functionoverlaps(uint start, uint end)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
if(!DbgIsDebugging() or end<start)
|
||||
return false;
|
||||
for(FunctionsInfo::iterator i=functions.begin(); i!=functions.end(); ++i)
|
||||
{
|
||||
uint curStart=start-i->modbase;
|
||||
uint curEnd=end-i->modbase;
|
||||
if(i->start<=curEnd and i->end>=curStart)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
const uint modbase=modbasefromaddr(start);
|
||||
return (functions.count(ModuleRange(modhashfromva(modbase), Range(start-modbase, end-modbase)))>0);
|
||||
}
|
||||
|
||||
bool functiondel(uint addr)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
const uint modbase=modbasefromaddr(addr);
|
||||
return (functions.erase(ModuleRange(modhashfromva(modbase), Range(addr-modbase, addr-modbase)))>0);
|
||||
}
|
||||
|
||||
void functioncachesave(JSON root)
|
||||
{
|
||||
const JSON jsonfunctions=json_array();
|
||||
const JSON jsonautofunctions=json_array();
|
||||
for(FunctionsInfo::iterator i=functions.begin(); i!=functions.end(); ++i)
|
||||
{
|
||||
uint curAddr=addr-i->modbase;
|
||||
if(i->start<=curAddr and i->end>=curAddr)
|
||||
const FUNCTIONSINFO curFunction=i->second;
|
||||
JSON curjsonfunction=json_object();
|
||||
if(*curFunction.mod)
|
||||
json_object_set_new(curjsonfunction, "module", json_string(curFunction.mod));
|
||||
else
|
||||
json_object_set_new(curjsonfunction, "module", json_null());
|
||||
json_object_set_new(curjsonfunction, "start", json_hex(curFunction.start));
|
||||
json_object_set_new(curjsonfunction, "end", json_hex(curFunction.end));
|
||||
if(curFunction.manual)
|
||||
json_array_append_new(jsonfunctions, curjsonfunction);
|
||||
else
|
||||
json_array_append_new(jsonautofunctions, curjsonfunction);
|
||||
}
|
||||
if(json_array_size(jsonfunctions))
|
||||
json_object_set(root, "functions", jsonfunctions);
|
||||
json_decref(jsonfunctions);
|
||||
if(json_array_size(jsonautofunctions))
|
||||
json_object_set(root, "autofunctions", jsonautofunctions);
|
||||
json_decref(jsonautofunctions);
|
||||
}
|
||||
|
||||
void functioncacheload(JSON root)
|
||||
{
|
||||
functions.clear();
|
||||
const JSON jsonfunctions=json_object_get(root, "functions");
|
||||
if(jsonfunctions)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsonfunctions, i, value)
|
||||
{
|
||||
functions.erase(i);
|
||||
return true;
|
||||
FUNCTIONSINFO curFunction;
|
||||
const char* mod=json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod)<MAX_MODULE_SIZE)
|
||||
strcpy(curFunction.mod, mod);
|
||||
else
|
||||
*curFunction.mod='\0';
|
||||
curFunction.start=json_hex_value(json_object_get(value, "start"));
|
||||
curFunction.end=json_hex_value(json_object_get(value, "end"));
|
||||
if(curFunction.end < curFunction.start)
|
||||
continue; //invalid function
|
||||
curFunction.manual=true;
|
||||
const uint key=modhashfromname(curFunction.mod);
|
||||
functions.insert(std::make_pair(ModuleRange(modhashfromname(curFunction.mod), Range(curFunction.start, curFunction.end)), curFunction));
|
||||
}
|
||||
}
|
||||
JSON jsonautofunctions=json_object_get(root, "autofunctions");
|
||||
if(jsonautofunctions)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsonautofunctions, i, value)
|
||||
{
|
||||
FUNCTIONSINFO curFunction;
|
||||
const char* mod=json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod)<MAX_MODULE_SIZE)
|
||||
strcpy(curFunction.mod, mod);
|
||||
else
|
||||
*curFunction.mod='\0';
|
||||
curFunction.start=json_hex_value(json_object_get(value, "start"));
|
||||
curFunction.end=json_hex_value(json_object_get(value, "end"));
|
||||
if(curFunction.end < curFunction.start)
|
||||
continue; //invalid function
|
||||
curFunction.manual=true;
|
||||
const uint key=modhashfromname(curFunction.mod);
|
||||
functions.insert(std::make_pair(ModuleRange(modhashfromname(curFunction.mod), Range(curFunction.start, curFunction.end)), curFunction));
|
||||
}
|
||||
}
|
||||
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
|
||||
if(!DbgIsDebugging() or end<start)
|
||||
return false;
|
||||
uint page=memfindbaseaddr(fdProcessInfo->hProcess, start, 0);
|
||||
if(!page or page!=memfindbaseaddr(fdProcessInfo->hProcess, end, 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;
|
||||
const uint modbase=modbasefromaddr(start);
|
||||
loop.start=start-modbase;
|
||||
loop.end=end-modbase;
|
||||
loop.depth=finaldepth;
|
||||
if(finaldepth)
|
||||
loop.parent=finaldepth-1;
|
||||
loopget(finaldepth-1, start, &loop.parent, 0);
|
||||
else
|
||||
loop.parent=0;
|
||||
loop.manual=manual;
|
||||
return false;
|
||||
loops.insert(std::make_pair(DepthModuleRange(finaldepth, ModuleRange(modhashfromva(modbase), Range(loop.start, loop.end))), loop));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool loopget(int depth, uint addr, uint* start, uint* end)
|
||||
{
|
||||
if(!DbgIsDebugging() or !memisvalidreadptr(fdProcessInfo->hProcess, addr))
|
||||
return false;
|
||||
for(LoopsInfo::iterator i=loops.begin(); i!=loops.end(); ++i)
|
||||
{
|
||||
uint curAddr=addr-i->modbase;
|
||||
if(i->start<=curAddr and i->end>=curAddr and i->depth==depth)
|
||||
{
|
||||
if(start)
|
||||
*start=i->start+i->modbase;
|
||||
if(end)
|
||||
*end=i->end+i->modbase;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
const uint modbase=modbasefromaddr(addr);
|
||||
LoopsInfo::iterator found=loops.find(DepthModuleRange(depth, ModuleRange(modhashfromva(modbase), Range(addr-modbase, addr-modbase))));
|
||||
if(found==loops.end()) //not found
|
||||
return false;
|
||||
if(start)
|
||||
*start=found->second.start+modbase;
|
||||
if(end)
|
||||
*end=found->second.end+modbase;
|
||||
return true;
|
||||
}
|
||||
|
||||
//check if a loop overlaps a range, inside is not overlapping
|
||||
|
|
@ -694,13 +763,20 @@ bool loopoverlaps(int depth, uint start, uint end, int* finaldepth)
|
|||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
const uint modbase=modbasefromaddr(start);
|
||||
uint curStart=start-modbase;
|
||||
uint curEnd=end-modbase;
|
||||
const uint key=modhashfromva(modbase);
|
||||
|
||||
//check if the new loop fits in the old loop
|
||||
for(LoopsInfo::iterator i=loops.begin(); i!=loops.end(); ++i)
|
||||
{
|
||||
uint curStart=start-i->modbase;
|
||||
uint curEnd=end-i->modbase;
|
||||
if(i->start<curStart and i->end>curEnd and i->depth==depth)
|
||||
return loopoverlaps(depth+1, start, end, finaldepth);
|
||||
if(i->first.second.first!=key) //only look in the current module
|
||||
continue;
|
||||
LOOPSINFO* curLoop=&i->second;
|
||||
if(curLoop->start<curStart and curLoop->end>curEnd and curLoop->depth==depth)
|
||||
return loopoverlaps(depth+1, curStart, curEnd, finaldepth);
|
||||
}
|
||||
|
||||
if(finaldepth)
|
||||
|
|
@ -709,9 +785,10 @@ bool loopoverlaps(int depth, uint start, uint end, int* finaldepth)
|
|||
//check for loop overlaps
|
||||
for(LoopsInfo::iterator i=loops.begin(); i!=loops.end(); ++i)
|
||||
{
|
||||
uint curStart=start-i->modbase;
|
||||
uint curEnd=end-i->modbase;
|
||||
if(i->start<=curEnd and i->end>=curStart and i->depth==depth)
|
||||
if(i->first.second.first!=key) //only look in the current module
|
||||
continue;
|
||||
LOOPSINFO* curLoop=&i->second;
|
||||
if(curLoop->start<=curEnd and curLoop->end>=curStart and curLoop->depth==depth)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -721,3 +798,83 @@ bool loopdel(int depth, uint addr)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void loopcachesave(JSON root)
|
||||
{
|
||||
const JSON jsonloops=json_array();
|
||||
const JSON jsonautoloops=json_array();
|
||||
for(LoopsInfo::iterator i=loops.begin(); i!=loops.end(); ++i)
|
||||
{
|
||||
const LOOPSINFO curLoop=i->second;
|
||||
JSON curjsonloop=json_object();
|
||||
if(*curLoop.mod)
|
||||
json_object_set_new(curjsonloop, "module", json_string(curLoop.mod));
|
||||
else
|
||||
json_object_set_new(curjsonloop, "module", json_null());
|
||||
json_object_set_new(curjsonloop, "start", json_hex(curLoop.start));
|
||||
json_object_set_new(curjsonloop, "end", json_hex(curLoop.end));
|
||||
json_object_set_new(curjsonloop, "depth", json_integer(curLoop.depth));
|
||||
json_object_set_new(curjsonloop, "parent", json_hex(curLoop.parent));
|
||||
if(curLoop.manual)
|
||||
json_array_append_new(jsonloops, curjsonloop);
|
||||
else
|
||||
json_array_append_new(jsonautoloops, curjsonloop);
|
||||
}
|
||||
if(json_array_size(jsonloops))
|
||||
json_object_set(root, "loops", jsonloops);
|
||||
json_decref(jsonloops);
|
||||
if(json_array_size(jsonautoloops))
|
||||
json_object_set(root, "autoloops", jsonautoloops);
|
||||
json_decref(jsonautoloops);
|
||||
}
|
||||
|
||||
void loopcacheload(JSON root)
|
||||
{
|
||||
loops.clear();
|
||||
const JSON jsonloops=json_object_get(root, "loops");
|
||||
if(jsonloops)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsonloops, i, value)
|
||||
{
|
||||
LOOPSINFO curLoop;
|
||||
const char* mod=json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod)<MAX_MODULE_SIZE)
|
||||
strcpy(curLoop.mod, mod);
|
||||
else
|
||||
*curLoop.mod='\0';
|
||||
curLoop.start=json_hex_value(json_object_get(value, "start"));
|
||||
curLoop.end=json_hex_value(json_object_get(value, "end"));
|
||||
curLoop.depth=json_integer_value(json_object_get(value, "depth"));
|
||||
curLoop.parent=json_hex_value(json_object_get(value, "parent"));
|
||||
if(curLoop.end < curLoop.start)
|
||||
continue; //invalid loop
|
||||
curLoop.manual=true;
|
||||
loops.insert(std::make_pair(DepthModuleRange(curLoop.depth, ModuleRange(modhashfromname(curLoop.mod), Range(curLoop.start, curLoop.end))), curLoop));
|
||||
}
|
||||
}
|
||||
JSON jsonautoloops=json_object_get(root, "autoloops");
|
||||
if(jsonautoloops)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsonautoloops, i, value)
|
||||
{
|
||||
LOOPSINFO curLoop;
|
||||
const char* mod=json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod)<MAX_MODULE_SIZE)
|
||||
strcpy(curLoop.mod, mod);
|
||||
else
|
||||
*curLoop.mod='\0';
|
||||
curLoop.start=json_hex_value(json_object_get(value, "start"));
|
||||
curLoop.end=json_hex_value(json_object_get(value, "end"));
|
||||
curLoop.depth=json_integer_value(json_object_get(value, "depth"));
|
||||
curLoop.parent=json_hex_value(json_object_get(value, "parent"));
|
||||
if(curLoop.end < curLoop.start)
|
||||
continue; //invalid loop
|
||||
curLoop.manual=false;
|
||||
loops.insert(std::make_pair(DepthModuleRange(curLoop.depth, ModuleRange(modhashfromname(curLoop.mod), Range(curLoop.start, curLoop.end))), curLoop));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,10 +5,12 @@
|
|||
|
||||
//ranges
|
||||
typedef std::pair<uint, uint> Range;
|
||||
typedef std::pair<uint, Range> ModuleRange; //modhash + RVA range
|
||||
typedef std::pair<int, ModuleRange> DepthModuleRange; //depth + modulerange
|
||||
|
||||
struct RangeCompare
|
||||
{
|
||||
bool operator()(const Range& a, const Range& b) //a before b?
|
||||
bool operator()(const Range& a, const Range& b) const //a before b?
|
||||
{
|
||||
return a.second < b.first;
|
||||
}
|
||||
|
|
@ -16,12 +18,40 @@ struct RangeCompare
|
|||
|
||||
struct OverlappingRangeCompare
|
||||
{
|
||||
bool operator()(const Range& a, const Range& b) //a before b?
|
||||
bool operator()(const Range& a, const Range& b) const //a before b?
|
||||
{
|
||||
return a.second < b.first || a.second < b.second;
|
||||
}
|
||||
};
|
||||
|
||||
struct ModuleRangeCompare
|
||||
{
|
||||
bool operator()(const ModuleRange& a, const ModuleRange& b) const
|
||||
{
|
||||
if(a.first < b.first) //module hash is smaller
|
||||
return true;
|
||||
if(a.first != b.first) //module hashes are not equal
|
||||
return false;
|
||||
return a.second.second < b.second.first; //a.second is before b.second
|
||||
}
|
||||
};
|
||||
|
||||
struct DepthModuleRangeCompare
|
||||
{
|
||||
bool operator()(const DepthModuleRange& a, const DepthModuleRange& b) const
|
||||
{
|
||||
if(a.first < b.first) //module depth is smaller
|
||||
return true;
|
||||
if(a.first != b.first) //module depths are not equal
|
||||
return false;
|
||||
if(a.second.first < b.second.first) //module hash is smaller
|
||||
return true;
|
||||
if(a.second.first != b.second.first) //module hashes are not equal
|
||||
return false;
|
||||
return a.second.second.second < b.second.second.first; //a.second.second is before b.second.second
|
||||
}
|
||||
};
|
||||
|
||||
//structures
|
||||
struct MODINFO
|
||||
{
|
||||
|
|
@ -62,29 +92,26 @@ typedef std::map<uint, BOOKMARKSINFO> BookmarksInfo;
|
|||
struct FUNCTIONSINFO
|
||||
{
|
||||
char mod[MAX_MODULE_SIZE];
|
||||
uint modbase;
|
||||
uint start;
|
||||
uint end;
|
||||
bool manual;
|
||||
};
|
||||
typedef std::map<ModuleRange, FUNCTIONSINFO, ModuleRangeCompare> FunctionsInfo;
|
||||
|
||||
struct LOOPSINFO
|
||||
{
|
||||
char mod[MAX_MODULE_SIZE];
|
||||
uint modbase;
|
||||
uint start;
|
||||
uint end;
|
||||
int parent;
|
||||
uint parent;
|
||||
int depth;
|
||||
bool manual;
|
||||
};
|
||||
typedef std::map<DepthModuleRange, LOOPSINFO, DepthModuleRangeCompare> LoopsInfo;
|
||||
|
||||
//typedefs
|
||||
typedef void (*EXPORTENUMCALLBACK)(uint base, const char* mod, const char* name, uint addr);
|
||||
|
||||
typedef std::vector<FUNCTIONSINFO> FunctionsInfo;
|
||||
typedef std::vector<LOOPSINFO> LoopsInfo;
|
||||
|
||||
void dbsave();
|
||||
void dbload();
|
||||
void dbclose();
|
||||
|
|
@ -119,15 +146,18 @@ bool bookmarkdel(uint addr);
|
|||
void bookmarkcachesave(JSON root);
|
||||
void bookmarkcacheload(JSON root);
|
||||
|
||||
|
||||
bool functionadd(uint start, uint end, bool manual);
|
||||
bool functionget(uint addr, uint* start, uint* end);
|
||||
bool functionoverlaps(uint start, uint end);
|
||||
bool functiondel(uint addr);
|
||||
void functioncachesave(JSON root);
|
||||
void functioncacheload(JSON root);
|
||||
|
||||
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 loopdel(int depth, uint addr);
|
||||
void loopcachesave(JSON root);
|
||||
void loopcacheload(JSON root);
|
||||
|
||||
#endif // _ADDRINFO_H
|
||||
|
|
|
|||
Loading…
Reference in New Issue