📄 exeload.cpp
字号:
if((ritem[0])||(ritem[1]))
{ rchange=(word *)(&poffs[ritem[0]+ritem[1]*16L]);
rchange[0]+=(word)options.loadaddr.segm;
rtable[mzh->numrelocs-nrelocs]=rchange[0];
}
else
rtable[mzh->numrelocs-nrelocs]=options.loadaddr.segm;
nrelocs--;
}
qsort(rtable,mzh->numrelocs,2,mzcmp);
sseg=options.loadaddr;
options.dseg=options.loadaddr.segm; // need to look for better value for dseg later
ip=options.loadaddr;
ipaddr=(((word)mzh->csip)+((word)(mzh->csip/0x10000L)+options.loadaddr.segm)*16L+options.loadaddr.offs)&0xfffff;
for(nrelocs=0;nrelocs<mzh->numrelocs;nrelocs++)
{ if(rtable[nrelocs]!=sseg.segm)
{ tseg.assign(rtable[nrelocs],0);
saddr=sseg.segm*16L+sseg.offs;
taddr=tseg.segm*16L+tseg.offs;
if((ipaddr>=saddr)&&(ipaddr<taddr))
{ ip.assign(sseg.segm,ipaddr-ip.segm*16L);
}
if((saddr<taddr)&&(sseg.segm>=options.loadaddr.segm))
{ dta.addseg(sseg,taddr-saddr,fbuff+mzh->headersize*16
+(sseg.segm-options.loadaddr.segm)*16L,code16,NULL);
dta.possibleentrycode(sseg);
// go through the reloc items, check if any lie in the seg
// if they do - add to reloc entries.
for(nr=0;nr<mzh->numrelocs;nr++)
{ ritem=(word *)(&roffs[(mzh->numrelocs-nr)*4L]);
if((ritem[0])||(ritem[1]))
{ rchange=(word *)(&poffs[ritem[0]+ritem[1]*16L]);
if(((byte *)rchange>=fbuff+mzh->headersize*16+(sseg.segm-options.loadaddr.segm)*16L)
&&((byte *)rchange<fbuff+mzh->headersize*16+(sseg.segm-options.loadaddr.segm)*16L+taddr-saddr))
reloc.addreloc(sseg+(dword)((byte *)rchange-
(fbuff+mzh->headersize*16+(sseg.segm-options.loadaddr.segm)*16L)),RELOC_SEG);
}
}
sseg.segm=tseg.segm;
}
}
}
if((sseg.segm-options.loadaddr.segm)*16UL<fs)
{ saddr=sseg.segm*16L+sseg.offs;
if(ipaddr>=saddr)
{ ip.assign(sseg.segm,ipaddr-ip.segm*16L);
}
dta.addseg(sseg,fs-(sseg.segm-options.loadaddr.segm)*16L,
fbuff+mzh->headersize*16+(sseg.segm-options.loadaddr.segm)*16L,code16,NULL);
for(nr=0;nr<mzh->numrelocs;nr++)
{ ritem=(word *)(&roffs[(mzh->numrelocs-nr)*4L]);
if((ritem[0])||(ritem[1]))
{ rchange=(word *)(&poffs[ritem[0]+ritem[1]*16L]);
if(((byte *)rchange>=fbuff+mzh->headersize*16+(sseg.segm-options.loadaddr.segm)*16L)
&&((byte *)rchange<fbuff+mzh->headersize*16+fs))
reloc.addreloc(sseg+(dword)((byte *)rchange-
(fbuff+mzh->headersize*16+(sseg.segm-options.loadaddr.segm)*16L)),RELOC_SEG);
}
}
dta.possibleentrycode(sseg);
}
// need to search for dseg better value.
options.mode16=true;
options.mode32=false;
dio.setcuraddr(ip);
scheduler.addtask(dis_code,priority_definitecode,ip,NULL);
scheduler.addtask(nameloc,priority_nameloc,ip,"start");
scheduler.addtask(windowupdate,priority_window,nlptr,NULL);
if(mzh->numrelocs)
delete rtable;
}
/************************************************************************
* readlefile *
* - to be written yet *
************************************************************************/
void fileloader::readlefile(void)
{
}
/************************************************************************
* readnefile *
* - NE = new executable = old windows 16-bit format. *
* - this is partially written but needs much more work on imports, *
* exports, etc *
************************************************************************/
void fileloader::readnefile(dword neoffs)
{ neheader *neh;
byte *nestart,*importnames,*modoffsets;
word nsegs;
nesegtable *nesegt;
int i,j,k;
lptr sseg,iaddr,inum;
dword slen,soffs;
word numrelocs;
word *stable;
nesegtablereloc *reloctable;
char iname[80];
options.dseg=options.loadaddr.segm;
sseg.assign(options.loadaddr.segm,0);
nestart=&fbuff[neoffs];
neh=(neheader *)nestart;
if(!neh->csip)
{ MessageBox(mainwindow,"No entry point to executable - assume that Executable"
"is a resource only\nUse a resource viewer","Borg Warning",MB_OK|MB_ICONEXCLAMATION);
CloseHandle(efile);
efile=INVALID_HANDLE_VALUE;
exetype=0;
return;
}
nsegs=neh->numsegs;
stable=new word[nsegs];
nesegt=(nesegtable *)(nestart+neh->offs_segments);
importnames=(byte *)(nestart+neh->offs_imports);
modoffsets=(byte *)(nestart+neh->offs_module);
// add segments
for(i=0;i<nsegs;i++)
{ slen=nesegt[i].seglength;
if(!slen)
slen=0x10000;
soffs=nesegt[i].sectoroffs;
// added uninit data borg 2.20
if(soffs)
{ if(nesegt[i].segflags&1)
{ dta.addseg(sseg,slen,&fbuff[soffs<<(dword)neh->shiftcount],data16,NULL);
options.dseg=sseg.segm;
}
else
{ dta.addseg(sseg,slen,&fbuff[soffs<<(dword)neh->shiftcount],code16,NULL);
dta.possibleentrycode(sseg);
}
}
else
dta.addseg(sseg,slen,NULL,uninitdata,NULL); // uninit data
stable[i]=sseg.segm;
sseg.segm+=(word)((slen+15)/16L);
}
// relocate data
// approach to imports:
// - start with a new segment 0xffff, to be created later, size 0.
// - for each import, if its an ordinal add it at the current addr in the import segment,
// - and increase the size of the segment, name it = name+ordinal num
// - otherwise name=importnames table name, check for if it is already an import
// - and only add if necessary.
// - finally create the segment at the end.
iaddr.segm=0xffff;
inum.segm=0xffff;
iaddr.offs=0;
for(i=0;i<nsegs;i++)
{ slen=nesegt[i].seglength;
if(!slen)
slen=0x10000;
soffs=nesegt[i].sectoroffs;
if((nesegt[i].segflags&100)&&(soffs))
{ // reloc data present
numrelocs=((word *)&fbuff[(soffs<<(dword)neh->shiftcount)+slen])[0];
reloctable=(nesegtablereloc *)&fbuff[(soffs<<(dword)neh->shiftcount)+slen+2];
for(j=0;j<numrelocs;j++)
{ switch(reloctable[j].reloctype)
{ case 0: //low byte
break;
case 2: //16bit selector
if((!reloctable[j].relocsort)&&(reloctable[j].index<0xff))
{ ((word *)&fbuff[(soffs<<(dword)neh->shiftcount)+reloctable[j].segm_offs])[0]=stable[reloctable[j].index-1];
}
break;
case 3: //32bit pointer
if((!reloctable[j].relocsort)&&(reloctable[j].index<0xff))
{ ((word *)&fbuff[(soffs<<(dword)neh->shiftcount)+reloctable[j].segm_offs+2])[0]=stable[reloctable[j].index-1];
((word *)&fbuff[(soffs<<(dword)neh->shiftcount)+reloctable[j].segm_offs])[0]=reloctable[j].indexoffs;
}
else if(reloctable[j].relocsort==2) // import by name
{ for(k=0;(k<importnames[reloctable[j].indexoffs])&&(k<79);k++)
{ iname[k]=importnames[reloctable[j].indexoffs+1+k];
iname[k+1]=0;
}
inum.offs=import.getoffsfromname(iname);
if(!inum.offs)
{ iaddr++;
import.addname(iaddr,iname);
inum.offs=iaddr.offs;
}
((word *)&fbuff[(soffs<<(dword)neh->shiftcount)+reloctable[j].segm_offs+2])[0]=inum.segm;
((word *)&fbuff[(soffs<<(dword)neh->shiftcount)+reloctable[j].segm_offs])[0]=(word)inum.offs;
}
break;
case 5: //16bit offset
if((!reloctable[j].relocsort)&&(reloctable[j].index<0xff))
{ ((word *)&fbuff[(soffs<<(dword)neh->shiftcount)+reloctable[j].segm_offs])[0]=reloctable[j].indexoffs;
}
break;
case 11: //48bit pointer
if((!reloctable[j].relocsort)&&(reloctable[j].index<0xff))
{ ((word *)&fbuff[(soffs<<(dword)neh->shiftcount)+reloctable[j].segm_offs+4])[0]=stable[reloctable[j].index-1];
((dword *)&fbuff[(soffs<<(dword)neh->shiftcount)+reloctable[j].segm_offs])[0]=reloctable[j].indexoffs;
}
break;
case 13: //32bit offset
if((!reloctable[j].relocsort)&&(reloctable[j].index<0xff))
{ ((dword *)&fbuff[(soffs<<(dword)neh->shiftcount)+reloctable[j].segm_offs])[0]=reloctable[j].indexoffs;
}
break;
default:
break;
}
}
}
}
inum.offs=0;
if(iaddr.offs)
dta.addseg(inum,iaddr.offs+1,NULL,uninitdata,"Import Segment <Borg>");
// set up disassembly
options.loadaddr.assign(stable[(neh->csip>>16)-1],neh->csip&0xffff);
dio.setcuraddr(options.loadaddr);
scheduler.addtask(dis_code,priority_definitecode,options.loadaddr,NULL);
scheduler.addtask(nameloc,priority_nameloc,options.loadaddr,"start");
scheduler.addtask(windowupdate,priority_window,nlptr,NULL);
delete stable;
}
/************************************************************************
* reados2file *
* - not written yet
************************************************************************/
void fileloader::reados2file(void)
{
}
/************************************************************************
* readbinfile *
* - reads a file as a flat binary file, so in effect we can load more *
* or less anything and do some analysis *
************************************************************************/
void fileloader::readbinfile(dword fsize)
{ options.mode32=!options.mode16;
options.dseg=options.loadaddr.segm;
dta.addseg(options.loadaddr,fsize,fbuff,options.mode32 ? code32:code16,NULL);
dta.possibleentrycode(options.loadaddr);
dio.setcuraddr(options.loadaddr);
scheduler.addtask(dis_code,priority_definitecode,options.loadaddr,NULL);
scheduler.addtask(nameloc,priority_nameloc,options.loadaddr,"start");
scheduler.addtask(windowupdate,priority_window,nlptr,NULL);
}
/************************************************************************
* getexetype *
* - returns the exe type, external class interface function *
************************************************************************/
int fileloader::getexetype(void)
{ return exetype;
}
/************************************************************************
* setexetype *
* - sets the exe type, external class interface function *
************************************************************************/
void fileloader::setexetype(int etype)
{ exetype=etype;
}
/************************************************************************
* subdirsummary *
* - this is part of the resource analysis for PE files. Resources are *
* held in a tree type format consisting of subdirs and leafnodes. *
************************************************************************/
void fileloader::subdirsummary(byte *data,char *impname,dword image_base,dword rtype)
{ struct perestable *resdir;
struct perestableentry *rentry;
unsigned char *name;
char nbuff[100],nbuff2[100],inum[10];
int clen;
dword numtmp;
unsigned long numitems;
resdir=(struct perestable *)data;
numitems=resdir->numnames+resdir->numids;
rentry=(struct perestableentry *)(resdir+1);
while(numitems)
{ if(rentry->id&0x80000000)
{ name=rawdata+((rentry->id)&0x7fffffff);
clen=((short int *)name)[0];
WideCharToMultiByte(CP_ACP,0,(const wchar_t *)(name+2),clen,nbuff,100,NULL,NULL);
nbuff[clen]=0;
if(impname!=NULL)
{ strcpy(nbuff2,nbuff);
strcpy(nbuff,impname);
strcat(nbuff," ");
strcat(nbuff,nbuff2);
}
}
else
{ numtmp=rentry->id&0x7fffffff;
wsprintf(inum,"%02lx",numtmp);
strcpy(nbuff,impname);
strcat(nbuff," Id:");
strcat(nbuff,inum);
}
if(rentry->offset&0x80000000)
leaf2summary(rawdata+((rentry->offset)&0x7fffffff),nbuff,image_base,rtype);
else
leafnodesummary(rawdata+((rentry->offset)&0x7fffffff),nbuff,image_base,rtype);
rentry++;
numitems--;
}
}
/************************************************************************
* leaf2summary *
* - PE resource analysis of leaf nodes *
************************************************************************/
void fileloader::leaf2summary(byte *data,char *name,dword image_base,dword rtype)
{ struct perestable *resdir;
struct perestableentry *rentry;
unsigned long numitems;
resdir=(struct perestable *)data;
numitems=resdir->numnames+resdir->numids;
rentry=(struct perestableentry *)(resdir+1);
while(numitems)
{ leafnodesummary(rawdata+((rentry->offset)&0x7fffffff),name,image_base,rtype);
rentry++;
numitems--;
}
}
/************************************************************************
* leafnodesummary *
* - analysis of a leaf node in a PE resource table *
* - detailed analysis of dialogs and string tables is done at the *
* moment *
************************************************************************/
void fileloader::leafnodesummary(byte *data,char *resname,dword image_base,dword rtype)
{ struct peleafnode *leaf;
lptr t;
leaf=(struct peleafnode *)data;
t.assign(options.loadaddr.segm,leaf->datarva+image_base);
// bugfix to third arg - build 14
dta.addseg(t,leaf->size,&rawdata[leaf->datarva-pdatarva],resourcedata,resname);
switch(rtype)
{ case 5: // dialog
scheduler.addtask(dis_dialog,priority_data,t,resname);
break;
case 6: // stringtable
scheduler.addtask(dis_stringtable,priority_data,t,resname);
break;
default:
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -