📄 data.cpp
字号:
/************************************************************************
* data.cpp *
* - this is the set of functions which looks after segments/sections *
* blocks of code or data can be added to the database, where they are *
* kept and ordered and can be interrogated. functions should be segment *
* level functions in here. the possibleentrycode function was put here *
* on this basis rather than being a disasm function as it simply *
* looks for likely entry code and adds scheduler items *
* *
* NB segment address with segment=0 is treated as a special return *
* value, and segments should not be created with this value *
************************************************************************/
#include <windows.h>
#include "data.h"
#include "proctab.h"
#include "schedule.h"
#include "dasm.h"
#include "disasm.h"
#include "debug.h"
// save structure used in databases
struct dsegitemsave
{ lptr addr;
dword size;
dword fileoffset;
segtype typ;
bool name;
};
/************************************************************************
* global variables *
* - total_data_size and current_data_pos are basically used to control *
* the vertical scroll bar. They are set up in here where the values *
* are first initialised as segments are added *
************************************************************************/
unsigned long total_data_size;
unsigned long current_data_pos;
/************************************************************************
* constructor function *
* - we reset the global variables used to track data size and position *
************************************************************************/
dataseg::dataseg()
{ total_data_size=0;
current_data_pos=0;
}
/************************************************************************
* destructor *
* - null at present. the list destructor should handle all segment *
* destruction *
************************************************************************/
dataseg::~dataseg()
{
}
/************************************************************************
* compare function *
* this is the compare function for the inherited list class *
* it determines how segments are ordered - by start address *
************************************************************************/
int dataseg::compare(dsegitem *i,dsegitem *j)
{ if(i->addr==j->addr)
return 0;
if(i->addr>j->addr)
return 1;
return -1;
}
/************************************************************************
* deletion function *
* this function is called for each list item (segment) and is used to *
* delete the list items (dsegitem) *
* - we delete any name which was created for the segment, and also any *
* data which was created for uninitdata types (we generate a memory *
* space for uninitdata for simplicity of analysis later) *
* - overrides the standard listitem deletion function *
************************************************************************/
void dataseg::delfunc(dsegitem *i)
{ if(i->name!=NULL)
delete i->name;
if(i->typ==uninitdata)
delete i->data;
delete i;
}
/************************************************************************
* insegloc *
* returns true if loc is in the segment/section ds, otherwise false *
************************************************************************/
bool dataseg::insegloc(dsegitem *ds,lptr loc)
{ if(ds==NULL)
return false;
if(loc.between(ds->addr,ds->addr+ds->size-1))
return true;
return false;
}
/************************************************************************
* addseg *
* this adds a segment to the list of segments. It is called on loading *
* the file, and segments should be setup before any analysis - here a *
* segment is just a block of data of a single attribute, which will be *
* referenced later. It could be a true segment, or just a PE section, *
* or even just a single resource. Segments should not overlap *
* the function checks for any overlaps, adds a task to the scheduler *
* for a segment header comment block, keeps track of total data size *
************************************************************************/
void dataseg::addseg(lptr loc,dword size,byte *dataptr,segtype t,char *name)
{ dsegitem *addit,*chker;
char warning[100];
dword tmpnum,tsize;
#ifdef DEBUG
DebugMessage("Addseg %04lx:%04lx Size %04lx",loc.segm,loc.offs,size);
#endif
addit=new dsegitem;
addit->addr=loc;
addit->size=size;
addit->data=dataptr;
addit->typ=t;
if(name!=NULL)
{ addit->name=new char [strlen(name)+1];
strcpy(addit->name,name);
}
else
addit->name=NULL;
resetiterator();
chker=nextiterator();
while(chker!=NULL)
{ if(insegloc(addit,chker->addr))
{ //need to cut addit short.
addit->size=chker->addr-addit->addr;
if(!addit->size)
{ tmpnum=loc.segm;
wsprintf(warning,"Warning : Unable to create segment %04lx",tmpnum);
wsprintf(warning+strlen(warning),":%04lx",loc.offs);
wsprintf(warning+strlen(warning)," size :%04lx",size);
MessageBox(mainwindow,warning,"Borg Warning",MB_ICONEXCLAMATION|MB_OK);
return;
}
else
{ tmpnum=loc.segm;
wsprintf(warning,"Warning : Segment overlap %04lx",tmpnum);
wsprintf(warning+strlen(warning),":%04lx",loc.offs);
wsprintf(warning+strlen(warning)," size :%04lx",size);
wsprintf(warning+strlen(warning)," reduced to size :%04lx",addit->size);
MessageBox(mainwindow,warning,"Borg Warning",MB_ICONEXCLAMATION|MB_OK);
}
}
if(insegloc(chker,addit->addr))
{ //need to cut chkit short.
tsize=chker->size;
chker->size=addit->addr-chker->addr;
if(!chker->size)
{ tmpnum=chker->addr.segm;
wsprintf(warning,"Warning : Unable to create segment %04lx",tmpnum);
wsprintf(warning+strlen(warning),":%04lx",chker->addr.offs);
wsprintf(warning+strlen(warning)," size :%04lx",tsize);
MessageBox(mainwindow,warning,"Borg Warning",MB_ICONEXCLAMATION|MB_OK);
delfrom(chker);
resetiterator();
}
else
{ tmpnum=chker->addr.segm;
wsprintf(warning,"Warning : Segment overlap %04lx",tmpnum);
wsprintf(warning+strlen(warning),":%04lx",chker->addr.offs);
wsprintf(warning+strlen(warning)," size :%04lx",tsize);
wsprintf(warning+strlen(warning)," reduced to size :%04lx",chker->size);
MessageBox(mainwindow,warning,"Borg Warning",MB_ICONEXCLAMATION|MB_OK);
}
}
chker=nextiterator();
}
addto(addit);
#ifdef DEBUG
DebugMessage("Adding Seg %04lx:%04lx Size %04lx",loc.segm,loc.offs,size);
if(name!=NULL)
DebugMessage("Name:%s",name);
#endif
scheduler.addtask(dis_segheader,priority_segheader,loc,NULL);
total_data_size+=size;
}
/************************************************************************
* findseg *
* - the segment locator takes a loc and searches for the segment *
* containing the loc. If its found then it returns a pointer to the *
* dsegitem. Note the iterator is changed, and will be left pointing *
* to the next segment. *
************************************************************************/
dsegitem *dataseg::findseg(lptr loc)
{ dsegitem t1,*findd;
t1.addr.assign(loc.segm,0);
findnext(&t1);
findd=nextiterator();
while(findd!=NULL)
{ if(insegloc(findd,loc))
return findd;
findd=nextiterator();
}
return NULL;
}
/************************************************************************
* datagetpos *
* - this simply calculates how far along the total data a loc is, which *
* is used for the vertical scroll bar to determine how far down it *
* should be. *
************************************************************************/
unsigned long dataseg::datagetpos(lptr loc)
{ dsegitem *findd;
unsigned long ctr;
resetiterator();
findd=nextiterator();
ctr=0;
while(findd!=NULL)
{ if(insegloc(findd,loc))
{ ctr+=(loc-findd->addr);
break;
}
ctr+=findd->size;
findd=nextiterator();
}
return ctr;
}
/************************************************************************
* getlocpos *
* - for a data position this returns the loc, treating all segments as *
* continous. It is the opposite function to datagetpos. It is used *
* when the vertical scroll bar is dragged to a position and stopped, *
* in order to calculate the new loc. *
************************************************************************/
lptr dataseg::getlocpos(unsigned long pos)
{ dsegitem *findd;
lptr ctr;
resetiterator();
findd=nextiterator();
ctr=findd->addr;
while(findd!=NULL)
{ if(pos<findd->size)
{ ctr=findd->addr+pos;
break;
}
pos-=findd->size;
ctr=findd->addr;
if(findd->size)
ctr+=(findd->size-1); // last byte in seg in case we dont find the addr
findd=nextiterator();
}
return ctr;
}
/************************************************************************
* beyondseg *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -