⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exeload.cpp

📁 十分经典的开源反编译工具
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	 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 + -