📄 database.cpp
字号:
/************************************************************************
* database.cpp *
* - functions for loading and saving database files *
************************************************************************/
#include <windows.h>
#include "dasm.h"
#include "debug.h"
#include "disasm.h"
#include "gname.h"
#include "relocs.h"
#include "xref.h"
#include "data.h"
#include "exeload.h"
#include "schedule.h"
#include "resource.h"
#include "decrypt.h"
/************************************************************************
* forward declarations *
************************************************************************/
BOOL CALLBACK loadmessbox(HWND hdwnd,UINT message,WPARAM wParam,LPARAM lParam);
BOOL CALLBACK savemessbox(HWND hdwnd,UINT message,WPARAM wParam,LPARAM lParam);
/************************************************************************
* savedecryptitems *
* - this saves the list of decryptors to the database *
************************************************************************/
bool savedecryptitems(savefile *sf)
{ dword ndecs;
ndecs=decrypter.numlistitems();
decrypter.resetiterator();
if(!sf->swrite(&ndecs,sizeof(dword)))
return false;
while(ndecs)
{ if(!decrypter.write_item(sf))
return false;
ndecs--;
}
return true;
}
/************************************************************************
* loaddecryptitems *
* - here we reload the list of decryptors *
************************************************************************/
bool loaddecryptitems(savefile *sf)
{ dword ndecs,num;
if(!sf->sread(&ndecs,sizeof(dword),&num))
return false;
while(ndecs)
{ if(!decrypter.read_item(sf))
return false;
ndecs--;
}
return true;
}
/************************************************************************
* retstacksavedb *
* - Borg keeps track of the stack even through saves. It simply saves *
* the full stack *
************************************************************************/
bool retstacksavedb(savefile *sf)
{ if(!sf->swrite(&dio.retstack.stacktop,sizeof(int)))
return false;
if(!sf->swrite(dio.retstack.callstack,sizeof(lptr)*CALLSTACKSIZE))
return false;
return true;
}
/************************************************************************
* retstackloaddb *
* - reloads the stack from the saved database file *
************************************************************************/
bool retstackloaddb(savefile *sf)
{ dword num;
if(!sf->sread(&dio.retstack.stacktop,sizeof(int),&num))
return false;
if(!sf->sread(dio.retstack.callstack,sizeof(lptr)*CALLSTACKSIZE,&num))
return false;
return true;
}
/************************************************************************
* dissavedb *
* - this routine saves the entire disassembly database to the database *
* save file. It converts instruction pointers into instruction uids *
* and converts data pointers into offsets for saving *
************************************************************************/
bool dissavedb(savefile *sf,byte *filebuff)
{ dword ndsms;
dsmitemsave structsave;
dsmitem *currdsm;
ndsms=dsm.numlistitems();
dsm.resetiterator();
if(!sf->swrite(&ndsms,sizeof(dword)))
return false;
while(ndsms)
{ currdsm=dsm.nextiterator();
structsave.addr=currdsm->addr;
structsave.type=currdsm->type;
structsave.length=currdsm->length;
structsave.modrm=currdsm->modrm;
structsave.mode32=currdsm->mode32;
structsave.override=currdsm->override;
structsave.flags=currdsm->flags;
structsave.displayflags=currdsm->displayflags;
if(structsave.type==dsmxref)
{ structsave.fileoffset=0; // NULL ptrs
structsave.tptroffset=0;
}
else if(structsave.type==dsmcode)
{ structsave.fileoffset=currdsm->data-filebuff;
structsave.tptroffset=((asminstdata *)currdsm->tptr)->uniqueid;
}
else
{ structsave.fileoffset=strlen((char *)currdsm->data)+1; // strlen
structsave.tptroffset=0; // points to str as well
}
if(!sf->swrite(&structsave,sizeof(dsmitemsave)))
return false;
if((structsave.type!=dsmxref)&&(structsave.type!=dsmcode))
{ if(!sf->swrite(currdsm->tptr,structsave.fileoffset))
return false;
}
ndsms--;
}
// need to save callstack and some other stuff too.
if(!sf->swrite(&dio.curraddr,sizeof(lptr)))
return false;
if(!sf->swrite(&dio.subitem,sizeof(dsmitemtype)))
return false;
if(!sf->swrite(&dsm.itables,sizeof(int)))
return false;
if(!sf->swrite(&dsm.jtables,sizeof(int)))
return false;
if(!sf->swrite(&dsm.irefs,sizeof(int)))
return false;
return retstacksavedb(sf);
}
/************************************************************************
* disloaddb *
* - this routine loads the entire disassembly database from the save *
* file It converts instruction uids into the instruction pointers and *
* converts offsets back into pointers. We have to search the assembly *
* instructions for the uids in order to find the correct instruction. *
************************************************************************/
bool disloaddb(savefile *sf,byte *filebuff)
{ dword ndsms,num;
dsmitemsave structsave;
dsmitem *currdsm;
int asminstctr;
asminstdata *findasm;
if(!sf->sread(&ndsms,sizeof(dword),&num))
return false;
while(ndsms)
{ currdsm=new dsmitem;
if(!sf->sread(&structsave,sizeof(dsmitemsave),&num))
return false;
currdsm->addr=structsave.addr;
currdsm->type=structsave.type;
currdsm->length=structsave.length;
currdsm->modrm=structsave.modrm;
currdsm->mode32=structsave.mode32;
currdsm->override=structsave.override;
currdsm->flags=structsave.flags;
currdsm->displayflags=structsave.displayflags;
if(structsave.type==dsmxref)
{ currdsm->data=NULL;
currdsm->tptr=NULL;
}
else if(structsave.type==dsmcode)
{ currdsm->data=structsave.fileoffset+filebuff;
// now reset the tptr = asminstdata ptr (need to find it from the uniqueid)
asminstctr=0;
findasm=reconstruct[asminstctr];
while((dword)(findasm[0].uniqueid/1000)!=(dword)(structsave.tptroffset/1000))
{ asminstctr++;
findasm=reconstruct[asminstctr];
if(findasm==NULL)
{
#ifdef DEBUG
DebugMessage("File Loader:Failed to find instruction table for %lu",structsave.tptroffset);
#endif
return false;
}
}
asminstctr=0;
while(findasm[asminstctr].uniqueid!=structsave.tptroffset)
{ asminstctr++;
if((!findasm[asminstctr].instbyte)&&(!findasm[asminstctr].processor))
{
#ifdef DEBUG
DebugMessage("File Loader:Failed to find instruction %lu",structsave.tptroffset);
#endif
return false;
}
}
currdsm->tptr=(void *)&findasm[asminstctr];
}
else
{ currdsm->data=new byte[structsave.fileoffset];
currdsm->tptr=currdsm->data;
}
if((structsave.type!=dsmxref)&&(structsave.type!=dsmcode))
{ if(!sf->sread(currdsm->tptr,structsave.fileoffset,&num))
return false;
}
dsm.addto(currdsm);
ndsms--;
}
// need to save callstack and some other stuff too.
if(!sf->sread(&dio.curraddr,sizeof(lptr),&num))
return false;
if(!sf->sread(&dio.subitem,sizeof(dsmitemtype),&num))
return false;
if(!sf->sread(&dsm.itables,sizeof(int),&num))
return false;
if(!sf->sread(&dsm.jtables,sizeof(int),&num))
return false;
if(!sf->sread(&dsm.irefs,sizeof(int),&num))
return false;
dsm.dissettable();
dio.setcuraddr(dio.curraddr);
return retstackloaddb(sf);
}
/************************************************************************
* saverelocitems *
* - this saves the relocs list to the database file. *
* - we can simply save the number of items followed by each item *
************************************************************************/
bool saverelocitems(savefile *sf)
{ dword nrels;
nrels=reloc.numlistitems();
reloc.resetiterator();
// save number of reloc items
if(!sf->swrite(&nrels,sizeof(dword)))
return false;
while(nrels)
{ if(!reloc.write_item(sf))
return false;
nrels--;
}
return true;
}
/************************************************************************
* loadrelocitems *
* - this reloads the list of relocs from the database file and *
* constructs the list again *
************************************************************************/
bool loadrelocitems(savefile *sf)
{ dword nrels,num;
// get number of items
if(!sf->sread(&nrels,sizeof(dword),&num))
return false;
while(nrels)
{ if(!reloc.read_item(sf))
return false;
nrels--;
}
return true;
}
/************************************************************************
* gnamesavedb *
* - saves all the names in the list to the database file being saved. *
* this is in a one-pass compatible loading format. ie number of items *
* followed by each item, and for strings the length of the string *
* followed by the string. *
************************************************************************/
bool gnamesavedb(gname *gn,savefile *sf)
{ dword nexps,nlen;
gnameitem *currexp;
nexps=gn->numlistitems();
gn->resetiterator();
if(!sf->swrite(&nexps,sizeof(dword)))
return false;
while(nexps)
{ currexp=gn->nextiterator();
if(!sf->swrite(&(currexp->addr),sizeof(lptr)))
return false;
nlen=strlen(currexp->name)+1;
if(!sf->swrite(&nlen,sizeof(dword)))
return false;
if(!sf->swrite(currexp->name,nlen))
return false;
nexps--;
}
return true;
}
/************************************************************************
* gnameloaddb *
* - loads the names from the database file and reconstructs the names *
* list *
************************************************************************/
bool gnameloaddb(gname *gn,savefile *sf)
{ dword nexps,num,nlen;
gnameitem *currexp;
if(!sf->sread(&nexps,sizeof(dword),&num))
return false;
while(nexps)
{ currexp=new gnameitem;
if(!sf->sread(&(currexp->addr),sizeof(lptr),&num))
return false;
if(!sf->sread(&nlen,sizeof(dword),&num))
return false;
currexp->name=new char[nlen];
if(!sf->sread(currexp->name,nlen,&num))
return false;
gn->addto(currexp);
nexps--;
}
return true;
}
/************************************************************************
* savedatasegitems *
* - we save the data segment data structures to the database file. *
************************************************************************/
bool savedatasegitems(savefile *sf,byte *filebuff)
{ dword nsegs;
nsegs=dta.numlistitems();
dta.resetiterator();
if(!sf->swrite(&nsegs,sizeof(dword)))
return false;
while(nsegs)
{ if(!dta.write_item(sf,filebuff))
return false;
nsegs--;
}
return true;
}
/************************************************************************
* loaddatasegitems *
* - loads the data segment data structures in *
************************************************************************/
bool loaddatasegitems(savefile *sf,byte *filebuff)
{ dword nsegs,num;
if(!sf->sread(&nsegs,sizeof(dword),&num))
return false;
#ifdef DEBUG
DebugMessage("Loading %lu datasegs",nsegs);
#endif
while(nsegs)
{ if(!dta.read_item(sf,filebuff))
return false;
nsegs--;
}
return true;
}
/************************************************************************
* xrefsavedb *
* save xref list to database file, simply writes the list item out *
* consisting of loc and ref_by, ie two addresses *
************************************************************************/
bool xrefsavedb(savefile *sf)
{ dword nxrefs;
xrefitem *currxref;
nxrefs=xrefs.numlistitems();
xrefs.resetiterator();
if(!sf->swrite(&nxrefs,sizeof(dword)))
return false;
while(nxrefs)
{ currxref=xrefs.nextiterator();
if(!sf->swrite(currxref,sizeof(xrefitem)))
return false;
nxrefs--;
}
return true;
}
/************************************************************************
* xrefloaddb *
* load xref list to database file, simply reads the list item in *
* consisting of loc and ref_by, ie two addresses *
* and adds it to the new list *
************************************************************************/
bool xrefloaddb(savefile *sf)
{ dword nxrefs,num;
xrefitem *currxref;
if(!sf->sread(&nxrefs,sizeof(dword),&num))
return false;
while(nxrefs)
{ currxref=new xrefitem;
if(!sf->sread(currxref,sizeof(xrefitem),&num))
return false;
xrefs.addto(currxref);
nxrefs--;
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -