📄 exeload.cpp
字号:
}
}
for(k=0;k<peh->objects;k++)
{ if((expdir->funcaddrrva>=pdata[k].rva)&&(expdir->funcaddrrva<pdata[k].rva+pdata[k].phys_size))
{ fnaddr=(dword *)&fbuff[expdir->funcaddrrva-pdata[k].rva+pdata[k].phys_offset];
break;
}
}
for(k=0;k<peh->objects;k++)
{ if((expdir->ordsaddrrva>=pdata[k].rva)&&(expdir->ordsaddrrva<pdata[k].rva+pdata[k].phys_size))
{ onaddr=(word *)&fbuff[expdir->ordsaddrrva-pdata[k].rva+pdata[k].phys_offset];
break;
}
}
lef.assign(options.loadaddr.segm,expdir->funcaddrrva+peh->image_base);
leo.assign(options.loadaddr.segm,expdir->ordsaddrrva+peh->image_base);
len.assign(options.loadaddr.segm,expdir->nameaddrrva+peh->image_base);
while(numsymbols)
{ scheduler.addtask(dis_datadword,priority_data,lef,NULL);
scheduler.addtask(dis_dataword,priority_data,leo,NULL);
scheduler.addtask(dis_datadword,priority_data,len,NULL);
chktable[onaddr[0]]=1;
t.assign(options.loadaddr.segm,peh->image_base+fnaddr[onaddr[0]]);
scheduler.addtask(dis_export,priority_export,t,(char *)&fbuff[(*nnaddr)+pdata[k].phys_offset-pdata[k].rva]);
t.assign(options.loadaddr.segm,(*nnaddr)+peh->image_base);
scheduler.addtask(dis_datastring,priority_data,t,NULL);
// actually not definite code since data can be exported too, eg a debug hook address
// so uses dis_exportcode which will disassemble if its in a code segment only.
t.assign(options.loadaddr.segm,peh->image_base+fnaddr[onaddr[0]]);
scheduler.addtask(dis_exportcode,priority_definitecode,t,NULL);
numsymbols--;
onaddr++;
nnaddr++;
lef+=4;
leo+=2;
len+=4;
}
if(expdir->numfunctions>expdir->numnames)
{ for(j=0;j<expdir->numfunctions;j++)
{ if(!chktable[j])
{ numtmp=j+expdir->base;
wsprintf(inum,"%02d",numtmp);
lstrcpyn(impbuff,(char *)expname,GNAME_MAXLEN-8);
k=0;
while((impbuff[k])&&(k<GNAME_MAXLEN-8))
{ if(impbuff[k]=='.')
break;
k++;
}
strcpy(&impbuff[k],"::ord_");
strcat(impbuff,inum);
strcpy(newimpname,impbuff);
if(fnaddr[j])
{ t.assign(options.loadaddr.segm,fnaddr[j]+peh->image_base);
scheduler.addtask(dis_ordexport,priority_export,t,newimpname);
scheduler.addtask(dis_code,priority_definitecode,t,NULL);
}
}
}
}
delete chktable;
}
if((pdata[i].rva==peh->importtable_rva) // import info
||((peh->importtable_rva>pdata[i].rva)&&(peh->importtable_rva<pdata[i].rva+pdata[i].phys_size)))
{ impdir=(peimportdirentry *)&fbuff[pdata[i].phys_offset+peh->importtable_rva-pdata[i].rva];
j=0;
while(impdir[j].firstthunkrva)
{ t.assign(options.loadaddr.segm,
peh->image_base+peh->importtable_rva+j*sizeof(struct peimportdirentry));
scheduler.addtask(dis_datadword,priority_data,t,NULL);
scheduler.addtask(dis_datadword,priority_data,t+4,NULL);
scheduler.addtask(dis_datadword,priority_data,t+8,NULL);
scheduler.addtask(dis_datadword,priority_data,t+12,NULL);
scheduler.addtask(dis_datadword,priority_data,t+16,NULL);
for(k1=0;k1<peh->objects;k1++)
{ if((impdir[j].namerva>=pdata[k1].rva)&&(impdir[j].namerva<pdata[k1].rva+pdata[k1].phys_size))
{ impname=&fbuff[impdir[j].namerva-pdata[k1].rva+pdata[k1].phys_offset];
break;
}
}
t.assign(options.loadaddr.segm,impdir[j].namerva+peh->image_base);
scheduler.addtask(dis_datastring,priority_data,t,NULL);
if(!impdir[j].originalthunkrva)
thunkrva=impdir[j].firstthunkrva;
else
thunkrva=impdir[j].originalthunkrva;
for(k=0;k<peh->objects;k++)
{ if((thunkrva>=pdata[k].rva)&&(thunkrva<pdata[k].rva+pdata[k].phys_size))
{ imphint=(dword *)&fbuff[thunkrva-pdata[k].rva+pdata[k].phys_offset];
break;
}
}
impaddr=impdir[j].firstthunkrva+peh->image_base;
impaddr2=impdir[j].originalthunkrva+peh->image_base;
while(*imphint)
{ if((*imphint)&0x80000000)
{ numtmp=(*imphint)&0x7fffffff;
wsprintf(inum,"%02d",numtmp);
strcpy(impbuff,(char *)impname);
k=0;
while(impbuff[k])
{ if(impbuff[k]=='.')
break;
k++;
}
strcpy(&impbuff[k],"::ord_");
strcat(impbuff,inum);
strcpy(newimpname,impbuff);
t.assign(options.loadaddr.segm,impaddr);
scheduler.addtask(dis_ordimport,priority_import,t,newimpname);
}
else
{ t.assign(options.loadaddr.segm,impaddr);
scheduler.addtask(dis_import,priority_import,t,(char *)&fbuff[(*imphint)+2+pdata[k1].phys_offset-pdata[k1].rva]);
}
t.assign(options.loadaddr.segm,peh->image_base+(*imphint));
scheduler.addtask(dis_dataword,priority_data,t,NULL);
scheduler.addtask(dis_datastring,priority_data,t+2,NULL);
t.assign(options.loadaddr.segm,impaddr);
scheduler.addtask(dis_datadword,priority_data,t,NULL);
t.assign(options.loadaddr.segm,impaddr2);
scheduler.addtask(dis_datadword,priority_data,t,NULL);
imphint++;
impaddr+=4;
impaddr2+=4;
}
t.assign(options.loadaddr.segm,impaddr);
scheduler.addtask(dis_datadword,priority_data,t,NULL);
t.assign(options.loadaddr.segm,impaddr2);
scheduler.addtask(dis_datadword,priority_data,t,NULL);
j++;
}
t.assign(options.loadaddr.segm,
peh->image_base+peh->importtable_rva+j*sizeof(struct peimportdirentry));
scheduler.addtask(dis_datadword,priority_data,t,NULL);
scheduler.addtask(dis_datadword,priority_data,t+4,NULL);
scheduler.addtask(dis_datadword,priority_data,t+8,NULL);
scheduler.addtask(dis_datadword,priority_data,t+12,NULL);
scheduler.addtask(dis_datadword,priority_data,t+16,NULL);
}
if(pdata[i].rva==peh->tls_rva)
peobjdone=true; // tls info
if((pdata[i].rva==peh->resourcetable_rva) // resource info
||((peh->resourcetable_rva>pdata[i].rva)&&(peh->resourcetable_rva<pdata[i].rva+pdata[i].phys_size)))
{ // RESOURCE_DATA;
if((pdata[i].phys_size)&&(options.loadresources))
{ resdir=(perestable *)&fbuff[pdata[i].phys_offset+peh->resourcetable_rva-pdata[i].rva];
pdatarva=peh->resourcetable_rva; // bugfix build 14
rawdata=(byte *)resdir;
numitems=resdir->numnames+resdir->numids;
rentry=(struct perestableentry *)(resdir+1);
while(numitems)
{ if((rentry->id)&0x80000000)
{ impname=rawdata+((rentry->id)&0x7fffffff);
clen=((word *)impname)[0];
WideCharToMultiByte(CP_ACP,0,(const wchar_t *)(impname+2),clen,impbuff,100,NULL,NULL);
impbuff[clen]=0;
}
else
{ switch(rentry->id)
{ case 1:
strcpy(impbuff,"Cursor");
break;
case 2:
strcpy(impbuff,"Bitmap");
break;
case 3:
strcpy(impbuff,"Icon");
break;
case 4:
strcpy(impbuff,"Menu");
break;
case 5:
strcpy(impbuff,"Dialog");
break;
case 6:
strcpy(impbuff,"String Table");
break;
case 7:
strcpy(impbuff,"Font Directory");
break;
case 8:
strcpy(impbuff,"Font");
break;
case 9:
strcpy(impbuff,"Accelerators");
break;
case 10:
strcpy(impbuff,"Unformatted Resource Data");
break;
case 11:
strcpy(impbuff,"Message Table");
break;
case 12:
strcpy(impbuff,"Group Cursor");
break;
case 14:
strcpy(impbuff,"Group Icon");
break;
case 16:
strcpy(impbuff,"Version Information");
break;
case 0x2002:
strcpy(impbuff,"New Bitmap");
break;
case 0x2004:
strcpy(impbuff,"New Menu");
break;
case 0x2005:
strcpy(impbuff,"New Dialog");
break;
default:
strcpy(impbuff,"User Defined Id:");
numtmp=rentry->id&0x7fffffff;
wsprintf(inum,"%02lx",numtmp);
strcat(impbuff,inum);
break;
}
}
if(rentry->offset&0x80000000)
{ subdirsummary(rawdata+((rentry->offset)&0x7fffffff),impbuff,peh->image_base,rentry->id);
}
else
{ leafnodesummary(rawdata+((rentry->offset)&0x7fffffff),impbuff,peh->image_base,0);
}
rentry++;
numitems--;
}
}
if(pdata[i].rva==peh->resourcetable_rva)
peobjdone=true;
}
if(pdata[i].rva==peh->fixuptable_rva) // fixup info
{ per=(perelocheader *)&fbuff[pdata[i].phys_offset];
while(per->rva)
{ rdata=(word *)per+sizeof(perelocheader)/2;
numrelocs=(per->len-sizeof(perelocheader))/2;
while((numrelocs)&&(rdata[0]))
{ t.assign(options.loadaddr.segm,((dword)(rdata[0])&0x0fff)+per->rva+peh->image_base);
reloc.addreloc(t,RELOC_NONE);
rdata++;
numrelocs--;
}
per=(perelocheader *)((byte *)(per)+per->len);
}
peobjdone=true;
}
if(pdata[i].rva==peh->debugtable_rva) // debug info
{ // DEBUG_DATA;
if((pdata[i].phys_size)&&(options.loaddebug))
{ sseg.offs=pdata[i].rva+peh->image_base;
dta.addseg(sseg,pdata[i].phys_size,&fbuff[pdata[i].phys_offset],debugdata,NULL);
}
peobjdone=true;
}
if((pdata[i].obj_flags&0x40)&&(!(pdata[i].obj_flags&0x20))&&(!peobjdone))
{ // INIT_DATA;
if((pdata[i].phys_size)&&(options.loaddata))
{ sseg.offs=pdata[i].rva+peh->image_base;
dta.addseg(sseg,pdata[i].phys_size,&fbuff[pdata[i].phys_offset],data32,NULL);
}
if((pdata[i].virt_size>pdata[i].phys_size)&&(options.loaddata))
{ sseg.offs=pdata[i].rva+peh->image_base+pdata[i].phys_size;
uinit=new byte[pdata[i].virt_size-pdata[i].phys_size];
for(j=0;j<pdata[i].virt_size-pdata[i].phys_size;j++)
uinit[j]=0;
dta.addseg(sseg,pdata[i].virt_size-pdata[i].phys_size,uinit,uninitdata,NULL);
}
}
else if((pdata[i].obj_flags&0x80)&&(!peobjdone))
{ // UNINIT_DATA;
if(options.loaddata)
{ sseg.offs=pdata[i].rva+peh->image_base;
uinit=new byte[pdata[i].virt_size];
for(j=0;j<pdata[i].virt_size;j++)
uinit[j]=0;
dta.addseg(sseg,pdata[i].virt_size,uinit,uninitdata,NULL);
}
}
else if(!peobjdone)
{ // CODE_DATA;
if(pdata[i].phys_size)
{ sseg.offs=pdata[i].rva+peh->image_base;
dta.addseg(sseg,pdata[i].phys_size,&fbuff[pdata[i].phys_offset],code32,NULL);
dta.possibleentrycode(sseg);
}
}
// default start addr=first seg, in the case of no entry point
// (eg some dll files). added version 2.20
if(!start_addr.segm)
{ start_addr.assign(options.loadaddr.segm,pdata[i].rva+peh->image_base);
dio.setcuraddr(start_addr);
}
}
start_addr.assign(options.loadaddr.segm,peh->entrypoint_rva+peh->image_base);
options.oep=start_addr;
dio.setcuraddr(start_addr);
scheduler.addtask(dis_code,priority_definitecode,start_addr,NULL);
scheduler.addtask(nameloc,priority_nameloc,start_addr,"start");
scheduler.addtask(windowupdate,priority_window,nlptr,NULL);
}
/************************************************************************
* mzcmp *
* - short comparison routine used in a qsort of relocations in dos mz *
* executable files *
************************************************************************/
int mzcmp(const void *a1,const void *a2)
{ if(((word *)a1)[0]<((word *)a2)[0])
return -1;
if(((word *)a1)[0]>((word *)a2)[0])
return 1;
return 0;
}
/************************************************************************
* readmzfile *
* - standard dos mz-executable file reader. *
* - fairly basic at the moment, as it is simply a load, and a better *
* analysis of d_seg is required (in fact Borg needs more work on *
* segmentation all round. *
************************************************************************/
void fileloader::readmzfile(dword fsize)
{ mzheader *mzh;
dword fs;
byte *roffs;
byte *poffs;
word nrelocs,nr;
word *ritem;
word *rchange;
word *rtable;
lptr sseg,tseg; // current segment limits
lptr ip;
dword saddr,taddr,ipaddr;
options.loadaddr.offs=0;
mzh=(mzheader *)fbuff;
fs=(mzh->numpages-1)*512L+mzh->numbytes;
if(fs>fsize)
fs=fsize;
fs-=mzh->headersize*16L;
roffs=fbuff+mzh->relocoffs;
poffs=fbuff+mzh->headersize*16L;
nrelocs=mzh->numrelocs;
if(nrelocs)
rtable=new word[nrelocs];
if(!nrelocs)
{ MessageBox(mainwindow,"Relocation table is empty\nThis file is probably packed"
"\nBorg will not be able to create the segments properly","Borg Warning",MB_OK|MB_ICONEXCLAMATION);
}
while(nrelocs)
{ ritem=(word *)(&roffs[(mzh->numrelocs-nrelocs)*4L]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -