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

📄 exeload.cpp

📁 十分经典的开源反编译工具
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/************************************************************************
*                  exeload.cpp                                          *
* Contains the executable file load routines and setting up of the      *
* disassembly for the files..                                           *
************************************************************************/

#include <windows.h>
#include <stdio.h>

#include "dasm.h"
#include "exeload.h"
#include "data.h"
#include "disio.h"
#include "disasm.h"
#include "schedule.h"
#include "relocs.h"
#include "gname.h"
#include "debug.h"

/************************************************************************
* constructor function                                                  *
* - resets file details.                                                *
************************************************************************/
fileloader::fileloader(void)
{ efile=INVALID_HANDLE_VALUE;
  exetype=0;
  fbuff=NULL;
}

/************************************************************************
* destructor function                                                   *
* - closes and file that is open.                                       *
************************************************************************/
fileloader::~fileloader(void)
{ if(fbuff!=NULL)
    delete fbuff;
  CloseHandle(efile);
}

/************************************************************************
* fileoffset                                                            *
* - function which returns the offset in a file of a given location,    *
*   this is to enable file patching given a location to patch           *
* - added in Borg v2.19                                                 *
************************************************************************/
dword fileloader::fileoffset(lptr loc)
{ dsegitem *ds;
  ds=dta.findseg(loc);
  if(ds==NULL)
    return 0;
  return (loc-ds->addr)+(ds->data-fbuff);
}

/************************************************************************
* patchfile                                                             *
* - writes to the currently open file (does not check it is opened with *
*   write access), given the number of bytes, data, and file offset to  *
*   write to.                                                           *
* - added in Borg v2.19                                                 *
************************************************************************/
void fileloader::patchfile(dword file_offs,dword num,byte *dat)
{ dword written;
  if(efile==INVALID_HANDLE_VALUE)
  { MessageBox(mainwindow,"File I/O Error - Invalid Handle for writing","Borg Message",MB_OK);
    return;
  }
  SetFilePointer(efile,file_offs,NULL,FILE_BEGIN);
  WriteFile(efile,dat,num,&written,NULL);
}

/************************************************************************
* patchoep                                                              *
* - writes to the currently open file (does not check it is opened with *
*   write access), given the new oep for the file is in options.oep     *
* - added in Borg v2.28                                                 *
************************************************************************/
void fileloader::patchoep(void)
{ if(exetype!=PE_EXE)
    return;
  peh->entrypoint_rva=options.oep.offs-peh->image_base;
  patchfile((byte *)&peh->entrypoint_rva-fbuff,4,(byte *)&peh->entrypoint_rva);
}

/************************************************************************
* reloadfile                                                            *
* - reads part of a file back in, given the file offset, number of      *
*   bytes and data buffer to read it in to. Used in the decryptor when  *
*   reloading a database file.                                          *
************************************************************************/
void fileloader::reloadfile(dword file_offs,dword num,byte *dat)
{ dword rd;
  if(efile==INVALID_HANDLE_VALUE)
  { MessageBox(mainwindow,"File I/O Error - Invalid Handle for reading","Borg Message",MB_OK);
    return;
  }
  SetFilePointer(efile,file_offs,NULL,FILE_BEGIN);
  ReadFile(efile,dat,num,&rd,NULL);
}

/************************************************************************
* readcomfile                                                           *
* - one of the simpler exe format loading routines, we just need to     *
*   load the file and disassemble from the start with an offset of      *
*   0x100                                                               *
************************************************************************/
void fileloader::readcomfile(dword fsize)
{ options.loadaddr.offs=0x100;
  options.dseg=options.loadaddr.segm;
  dta.addseg(options.loadaddr,fsize,fbuff,code16,NULL);
  dta.possibleentrycode(options.loadaddr);
  options.mode16=true;
  options.mode32=false;
  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);
}

/************************************************************************
* readsysfile                                                           *
* - very similar to the com file format, but the start offset is 0x00   *
* - detailed sys format below: (since so few documents seem to give the *
*   information correctly)                                              *
*                                                                       *
* Device Header                                                         *
*                                                                       *
* The device header is an extension to what is described in the MS-PRM. *
*                                                                       *
* DevHdr DD -1 ; Ptr to next driver in file or -1 if last driver        *
* DW ? ; Device attributes                                              *
* DW ? ; Device strategy entry point                                    *
* DW ? ; Device interrupt entry point                                   *
* DB 8 dup (?) ; Character device name field                            *
* DW 0 ; Reserved                                                       *
* DB 0 ; Drive letter                                                   *
* DB ? ; Number of units                                                *
*                                                                       *
* A device driver requires a device header at the beginning of the      *
* file.                                                                 *
*                                                                       *
* POINTER TO NEXT DEVICE HEADER FIELD                                   *
*                                                                       *
* The device header field is a pointer to the device header of the next *
* device driver. It is a doubleword field that is set by DOS at the     *
* time the device driver is loaded. The first word is an offset and the *
* second word is the segment. If you are loading only one device        *
* driver, set the device header field to -1 before loading the device.  *
* If you are loading more than one device driver, set the first word of *
* the device driver header to the offset of the next device driver's    *
* header. Set the device driver header field of the last device driver  *
* to -1.                                                                *
*                                                                       *
* ATTRIBUTE FIELD                                                       *
*                                                                       *
* The attribute field is a word field that describes the attributes of  *
* the device driver to the system. The attributes are:                  *
*                                                                       *
* word bits (decimal)                                                   *
*  15   1   character device                                            *
*       0   block device                                                *
*  14   1   supports IOCTL                                              *
*       0   doesn't support IOCTL                                       *
*  13   1   non-IBM format (block only)                                 *
*       0   IBM format                                                  *
*  12       not documented - unknown                                    *
*  11   1   supports removeable media                                   *
*       0   doesn't support removeable media                            *
*  10       reserved for DOS                                            *
*    through                                                            *
*   4       reserved for DOS                                            *
*   3   1   current block device                                        *
*       0   not current block device                                    *
*   2   1   current NUL device                                          *
*       0   not current NUL device                                      *
*   1   1   current standard output device                              *
*       0   not current standard output device                          *
*                                                                       *
* BIT 15 is the device type bit. Use it to tell the system the that     *
* driver is a block or character device.                                *
*                                                                       *
* BIT 14 is the IOCTL bit. It is used for both character and block      *
* devices. Use it to tell DOS whether the device driver can handle      *
* control strings through the IOCTL function call 44h.                  *
* If a device driver cannot process control strings, it should set bit  *
* 14 to 0. This way DOS can return an error is an attempt is made       *
* through the IOCTL function call to send or receive control strings to *
* the device. If a device can process control strings, it should set    *
* bit 14 to 1. This way, DOS makes calls to the IOCTL input and output  *
* device function to send and receive IOCTL strings.                    *
* The IOCTL functions allow data to be sent to and from the device      *
* without actually doing a normal read or write. In this way, the       *
* device driver can use the data for its own use, (for example, setting *
* a baud rate or stop bits, changing form lengths, etc.) It is up to    *
* the device to interpret the information that is passed to it, but the *
* information must not be treated as a normal I/O request.              *
*                                                                       *
* BIT 13 is the non-IBM format bit. It is used for block devices only.  *
* It affects the operation of the Get BPB (BIOS parameter block) device *
* call.                                                                 *
*                                                                       *
* BIT 11 is the open/close removeable media bit. Use it to tell DOS if  *
* the device driver can handle removeable media. (DOS 3.x only)         *
*                                                                       *
* BIT 3 is the clock device bit. It is used for character devices only. *
* Use it to tell DOS if your character device driver is the new CLOCK$  *
* device.                                                               *
*                                                                       *
* BIT 2 is the NUL attribute bit. It is used for character devices      *
* only. Use it to tell DOS if your character device driver is a NUL     *
* device. Although there is a NUL device attribute bit, you cannot      *
* reassign the NUL device. This is an attribute that exists for DOS so  *
* that DOS can tell if the NUL device is being used.                    *
*                                                                       *
* BIT 0 are the standard input and output bits. They are used for       *
* character & devices only. Use these bits to tell DOS if your          *
* character device                                                      *
*                                                                       *
* BIT 1 driver is the new standard input device or standard output      *
* device.                                                               *
*                                                                       *
* POINTER TO STRATEGY AND INTERRUPT ROUTINES                            *
*                                                                       *
* These two fields are pointers to the entry points of the strategy and *
* input routines. They are word values, so they must be in the same     *
* segment as the device header.                                         *
*                                                                       *
* NAME/UNIT FIELD                                                       *
*                                                                       *
* This is an 8-byte field that contains the name of a character device  *
* or the unit of a block device. For the character names, the name is   *
* left-justified and the space is filled to 8 bytes. For block devices, *
* the number of units can be placed in the first byte. This is optional *
* because DOS fills in this location with the value returned by the     *
* driver's INIT code.                                                   *
************************************************************************/
void fileloader::readsysfile(dword fsize)
{ lptr t;
  bool done;
  word devhdr,devlength;
  options.loadaddr.offs=0x00;
  options.dseg=options.loadaddr.segm;
  dta.addseg(options.loadaddr,fsize,fbuff,code16,NULL);
  dta.possibleentrycode(options.loadaddr);
  options.mode16=true;
  options.mode32=false;
  dio.setcuraddr(options.loadaddr);
  done=false;
  devhdr=0;
  while(!done)
  { t.assign(options.loadaddr.segm,devhdr);
    scheduler.addtask(dis_dataword,priority_data,t,NULL);
    scheduler.addtask(dis_dataword,priority_data,t+2,NULL);
    scheduler.addtask(dis_dataword,priority_data,t+4,NULL);
    scheduler.addtask(dis_dataword,priority_data,t+6,NULL);
    scheduler.addtask(dis_dataword,priority_data,t+8,NULL);
    scheduler.addtask(dis_dataword,priority_data,t+18,NULL);
    if((((word *)(fbuff+devhdr))[3])&&((((word *)(fbuff+devhdr))[3])<fsize))
    { t.assign(options.loadaddr.segm,((word *)(fbuff+devhdr))[3]+devhdr);
	   if(t.offs)
      { scheduler.addtask(dis_code,priority_definitecode,t,NULL);
	     scheduler.addtask(nameloc,priority_nameloc,t,"strategy");
      }
    }
    if((((word *)(fbuff+devhdr))[4])&&((((word *)(fbuff+devhdr))[4])<fsize))
    { t.assign(options.loadaddr.segm,((word *)(fbuff+devhdr))[4]);
	   if(t.offs)
      { scheduler.addtask(dis_code,priority_definitecode,t,NULL);
	     scheduler.addtask(nameloc,priority_nameloc,t,"interrupt");
      }
    }
    scheduler.addtask(windowupdate,priority_window,nlptr,NULL);
    devlength=((word *)(fbuff+devhdr))[0];
    if((devlength==0xffff)||(!devlength)||((unsigned)(devhdr+devlength)>(fsize-10)))
      done=true;
    devhdr+=devlength;
  }
}

/************************************************************************
* readpefile                                                            *
* - the main file loader in Borg is for PE files. The routines here are *
*   fairly complete, and lack only proper analysis of debug sections.   *
* - needs rewriting for clarity at some point in the future, as it has  *
*   sprawled out to 360 lines now.                                      *
* - some further resource tree analysis is done in other routines which *
*   follow                                                              *
************************************************************************/
void fileloader::readpefile(dword peoffs)
{ peobjdata *pdata;
  byte *pestart,*impname,*expname;
  unsigned char *chktable;
  lptr lef,leo,len,start_addr;
  dword *fnaddr,*nnaddr;
  word *onaddr,*rdata;
  dword numsymbols,numitems,numrelocs;
  char impbuff[100],inum[10],newimpname[GNAME_MAXLEN+1];
  lptr sseg,t;
  dword j;
  int i,k,k1,clen;
  peimportdirentry *impdir;
  byte *uinit;
  peexportdirentry *expdir;
  perelocheader *per;
  dword thunkrva,*imphint,impaddr,impaddr2,numtmp;
  bool peobjdone;
  perestable *resdir;
  perestableentry *rentry;
  start_addr=nlptr;
  options.dseg=options.loadaddr.segm;
  sseg.segm=options.loadaddr.segm;
  sseg.offs=0;
  pestart=&fbuff[peoffs];
  peh=(peheader *)pestart;
  options.loadaddr.offs=peh->image_base; // bugfix build 14
  // this is not right - ver 2.19 bugfix below
  //  pdata=(peobjdata *)(pestart+sizeof(peheader)+(peh->numintitems-0x0a)*8);
  // 24=standard header size and add nt_hdr_size to it.
  pdata=(peobjdata *)(pestart+24+peh->nt_hdr_size);
  for(i=0;i<peh->objects;i++)
  { peobjdone=false;
	 if((pdata[i].rva==peh->exporttable_rva)  // export info
		||((peh->exporttable_rva>pdata[i].rva)&&(peh->exporttable_rva<pdata[i].rva+pdata[i].phys_size)))
	 { expdir=(peexportdirentry *)&fbuff[pdata[i].phys_offset+peh->exporttable_rva-pdata[i].rva];
		t.assign(options.loadaddr.segm,peh->image_base+peh->exporttable_rva);
		scheduler.addtask(dis_datadword,priority_data,t,NULL);
		scheduler.addtask(dis_datadword,priority_data,t+4,NULL);
		scheduler.addtask(dis_dataword,priority_data,t+8,NULL);
		scheduler.addtask(dis_dataword,priority_data,t+10,NULL);
		scheduler.addtask(dis_datadword,priority_data,t+12,NULL);
		scheduler.addtask(dis_datadword,priority_data,t+16,NULL);
		scheduler.addtask(dis_datadword,priority_data,t+20,NULL);
		scheduler.addtask(dis_datadword,priority_data,t+24,NULL);
		scheduler.addtask(dis_datadword,priority_data,t+28,NULL);
		for(k1=0;k1<peh->objects;k1++)
		{ if((expdir->namerva>=pdata[k1].rva)&&(expdir->namerva<pdata[k1].rva+pdata[k1].phys_size))
		  { expname=&fbuff[expdir->namerva-pdata[k1].rva+pdata[k1].phys_offset];
			 break;
		  }
		}
		t.offs=expdir->namerva+peh->image_base;
		scheduler.addtask(dis_datastring,priority_data,t,NULL);
		numsymbols=expdir->numfunctions;
		chktable=new unsigned char [numsymbols];
		for(j=0;j<numsymbols;j++)
        chktable[j]=0;
		if(expdir->numnames<numsymbols)
        numsymbols=expdir->numnames;
		for(k=0;k<peh->objects;k++)
		{ if((expdir->nameaddrrva>=pdata[k].rva)&&(expdir->nameaddrrva<pdata[k].rva+pdata[k].phys_size))
		  { nnaddr=(dword *)&fbuff[expdir->nameaddrrva-pdata[k].rva+pdata[k].phys_offset];
			 break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -