forked from KolibriOS/kolibrios
6bd5a354f5
git-svn-id: svn://kolibrios.org@6446 a494cfbc-eb01-0410-851d-a64ba20cac60
1106 lines
36 KiB
C++
1106 lines
36 KiB
C++
#include "tok.h"
|
|
|
|
#include "coff.h"
|
|
|
|
|
|
|
|
#define _OUTPE_
|
|
|
|
|
|
|
|
/* -----------------------------------------------------------------------
|
|
|
|
‘®§¤ ¨¥ PE ä®à¬ â
|
|
|
|
------------------------------------------------------------------------ */
|
|
|
|
#define SIZESTUB 96
|
|
|
|
#define STRVERS 0x20 //ᬥ饨¥ ⥪áâ á ®¬¥à®¬ ¢¥àᨨ
|
|
|
|
|
|
|
|
char stub[]={0x4D,0x5A,0x50,0x00,0x02,0x00,0x00,0x00,
|
|
|
|
0x04,0x00,0x0F,0x00,0xFF,0xFF,0x00,0x00,
|
|
|
|
0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
|
0x40,0x00,0x1A,0x00,0x00,0x00,0x00,0x00,
|
|
|
|
|
|
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
|
0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,
|
|
|
|
|
|
|
|
0xBA,0x0E,0x00,0x0E,0x1F,0xB4,0x09,0xCD,
|
|
|
|
0x21,0xB8,0x01,0x4C,0xCD,0x21,0x46,0x6F,
|
|
|
|
0x72,0x20,0x57,0x69,0x6E,0x33,0x32,0x20,
|
|
|
|
0x6F,0x6E,0x6C,0x79,0x21,0x0D,0x0A,0x24};
|
|
|
|
|
|
|
|
#define SIZESTUB2 12
|
|
|
|
char stub2[]={0x4D,0x5A,0x53,0x50,0x48,0x49,0x4E,0x58,
|
|
|
|
0x20,0x43,0x2D,0x2D};
|
|
|
|
unsigned int numdll,numapi;
|
|
|
|
unsigned char FixUpTable=FALSE; //§ ¯à¥â¨âì ᮧ¤ ¨¥ â ¡«¨æ¨ Fix UP for Windows
|
|
|
|
unsigned char WinMonoBlock=TRUE;
|
|
|
|
int numexport=0;
|
|
|
|
unsigned long ImageBase=0x400000;
|
|
|
|
unsigned long vsizeheader=0x1000; //¢¨àâã «ìë© à §¬¥à § £®«®¢ª .
|
|
|
|
unsigned long FILEALIGN=0;//512; // ¢ëà ¢¨¢ ¨¥ ᥪ権 ¢ ä ©«¥
|
|
|
|
int filingzerope;
|
|
|
|
|
|
|
|
struct listexport *lexport=NULL;
|
|
|
|
static unsigned long sizestub;
|
|
|
|
static unsigned long numrs=1;
|
|
|
|
|
|
|
|
unsigned long Align(unsigned long size,unsigned long val)
|
|
|
|
{
|
|
|
|
if(val<2)return size;
|
|
|
|
val--;
|
|
|
|
return (size+val)&(~val);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
#include <conio.h>
|
|
|
|
|
|
|
|
void PrintMem(void *mem)
|
|
|
|
{
|
|
|
|
unsigned char *m,*n;
|
|
|
|
int i,j;
|
|
|
|
m=(unsigned char *)mem;
|
|
|
|
for(i=0;i<192;){
|
|
|
|
n=m;
|
|
|
|
for(j=0;j<16;j++,i++){
|
|
|
|
printf("%02X ",*m);
|
|
|
|
m++;
|
|
|
|
}
|
|
|
|
for(j=0;j<16;j++){
|
|
|
|
char c=*n;
|
|
|
|
n++;
|
|
|
|
if(c<0x20||c>0x7e)c='.';
|
|
|
|
putch(c);
|
|
|
|
}
|
|
|
|
puts("");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CheckMem()
|
|
|
|
{
|
|
|
|
if(listdll!=NULL){ //¥áâì api-¯à®æ
|
|
|
|
DLLLIST *newdll=listdll; // ç «® ᯨ᪠DLL
|
|
|
|
APIPROC *listapi=newdll->list;
|
|
|
|
idrec *rec=listapi->recapi;
|
|
|
|
PrintMem(rec);
|
|
|
|
}
|
|
|
|
} */
|
|
|
|
|
|
|
|
void AddJmpApi()
|
|
|
|
{
|
|
|
|
//¯®¨áª api ¯à®æ¥¤ãà
|
|
|
|
//᪮à४â¨à®¢ âì ¤à¥á ¨§ â ¡«¨æë ¯¥à¥¬¥é¥¨©
|
|
|
|
alignersize+=AlignCD(CS,4);
|
|
|
|
if(listdll!=NULL){ //¥áâì api-¯à®æ
|
|
|
|
DLLLIST *newdll=listdll; // ç «® ᯨ᪠DLL
|
|
|
|
numdll=numapi=0;
|
|
|
|
for(APIPROC *listapi=newdll->list;;){
|
|
|
|
unsigned short numapiprocdll=0; //ç¨á«® ¨á¯®«ì§ã¥¬ëå ¢ ¡¨¡«¨®â¥ª¥ ¯à®æ¥¤ãà
|
|
|
|
for(short i=0;i<newdll->num;i++){ //¯à®¢¥à¨âì ¢á¥ ¯à®æ¥¤ãàë
|
|
|
|
idrec *rec=(listapi+i)->recapi;
|
|
|
|
unsigned int idnum=rec->recnumber; //¨¤¥â¨ä¨ª â®à ᯨáª
|
|
|
|
char useapi=FALSE; //ä« £ ¨á¯®«ì§®¢ ¨ï
|
|
|
|
for(unsigned int j=0;j<posts;j++){ //¯®¨áª ¨á¯®«ì§®¢ ¨ï ¯à®æ¥¤ãàë
|
|
|
|
if((postbuf+j)->num==idnum){
|
|
|
|
if((postbuf+j)->type==CALL_32){ // 諨
|
|
|
|
useapi=API_JMP; //ä« £ ¢§¢¥¤¥¬
|
|
|
|
unsigned long hold=outptr-((postbuf+j)->loc+4); //à áâ®ï¨¥ ¤® ¢ë§®¢
|
|
|
|
*(long *)&output[(postbuf+j)->loc]=hold; //¨á¯à ¢¨âì
|
|
|
|
}
|
|
|
|
else if((postbuf+j)->type==CALL_32I){
|
|
|
|
useapi=API_FAST; //ä« £ ¢§¢¥¤¥¬
|
|
|
|
numrel++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(useapi==API_JMP){ // ¯à®æ¥¤ãà ¢ë§ë¢ « áì
|
|
|
|
*(short *)&output[outptr]=0x25ff; //£¥¥à æ¨ï JMP
|
|
|
|
outptr+=2;
|
|
|
|
rec->recnumber=outptr; //⥯¥àì ¢¬¥áâ® ¨¤¥â. â®çª ¢å®¤
|
|
|
|
AddReloc(CS); //¤®¡ ¢¨âì ¥¥ ¢ â ¡« ¯¥à¥¬¥é¥¨©
|
|
|
|
*(long *)&output[outptr]=0; // ¤à¥á ¢ë§®¢
|
|
|
|
outptr+=4;
|
|
|
|
numapi++; //®¡é¥¥ ç¨á«® ¨á¯®«ì§®¢ ëå api-¯à®æ¥¤ãà
|
|
|
|
numapiprocdll++; //ç¨á«® ¨á¯®«ì§®¢ ëå ¯à®æ¥¤ãà ¢ í⮩ DLL
|
|
|
|
}
|
|
|
|
else if(useapi==API_FAST){
|
|
|
|
numapi++; //®¡é¥¥ ç¨á«® ¨á¯®«ì§®¢ ëå api-¯à®æ¥¤ãà
|
|
|
|
numapiprocdll++; //ç¨á«® ¨á¯®«ì§®¢ ëå ¯à®æ¥¤ãà ¢ í⮩ DLL
|
|
|
|
}
|
|
|
|
rec->recrm=useapi; //⨯ ¢ë§®¢ api; 0 - not used
|
|
|
|
if(rec->newid!=NULL){
|
|
|
|
free(rec->newid); //ᯨ᮪ ¯ à ¬¥â஢ ¡®«ìè¥ ¥ 㦥
|
|
|
|
rec->newid=NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
newdll->num=numapiprocdll; //¨á¯à ¢¨âì ç¨á«® ॠ«ì® ¨á¯®«ì§ ¯à®æ¥¤ãà
|
|
|
|
if(numapiprocdll==0){ //¢ í⮩ ¡¨¡«¨®â¥ª¥ ¥ ¨á¯®«ì§ ¨ ®¤¨ ¢ë§®¢
|
|
|
|
free(newdll->list); //㤠«¨âì ᯨ᮪ ¯à®æ¥¤ãà.
|
|
|
|
}
|
|
|
|
else numdll++;
|
|
|
|
if(newdll->next==NULL)break; //ª®¥æ ᯨáª
|
|
|
|
newdll=newdll->next;
|
|
|
|
listapi=newdll->list;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
outptrdata=outptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
int MakePE()
|
|
|
|
{
|
|
|
|
unsigned short numobj=1;
|
|
|
|
char *importblock=NULL;
|
|
|
|
char *relocblock=NULL;
|
|
|
|
char *exportblock=NULL;
|
|
|
|
unsigned long psize,vsize=0,sizereloc=0,sizeReloc=0,sizeImport=0,sizeExport=0,
|
|
|
|
sizebss=0,sizeRes=0;
|
|
|
|
unsigned long startsec=0,startsecr=0,startsece=0,startsecres=0;
|
|
|
|
unsigned int posrel=0,sizeimport=0,startimportname=0,sizeexport=0,sizeres=0,
|
|
|
|
startexportname=0;
|
|
|
|
unsigned int sizehead; //à §¬¥à § £®«®¢ª
|
|
|
|
unsigned int exportnum=0; //®¬¥à ᥪ樨 íªá¯®àâ
|
|
|
|
unsigned int relocnum=0; //®¬¥à ᥪ樨 ¯¥à¥¬¥é¥¨©
|
|
|
|
unsigned int importnum=0; //®¬¥à ᥪ樨 ¨¬¯®àâ
|
|
|
|
unsigned int codenum=0; //®¬¥à ᥪ樨 ª®¤
|
|
|
|
unsigned int resnum=0; //®¬¥à ᥪ樨 à¥áãàᮢ
|
|
|
|
if(hout==NULL)return -1;
|
|
|
|
if(WinMonoBlock==FALSE){
|
|
|
|
vsize=Align(outptr+(wbss==FALSE?postsize:0),OBJECTALIGN);//¢¨àâã «ìë© à §¬¥à ᥪ樨 ª®¤
|
|
|
|
psize=Align(outptr,FILEALIGN); //䨧¨ç¥áª¨© à §¬¥à ᥪ樨 ª®¤
|
|
|
|
}
|
|
|
|
else vsize=outptr;
|
|
|
|
// sizehead=((postsize&&wbss)?2:1)*sizeof(OBJECT_ENTRY);
|
|
|
|
sizehead=numrs*sizeof(OBJECT_ENTRY);
|
|
|
|
OBJECT_ENTRY *objentry=(OBJECT_ENTRY *)MALLOC(sizehead);//â ¢«¨æ ®¡ê¥ªâ®¢
|
|
|
|
memset(objentry,0,sizehead);//®ç¨áâ¨âì â ¡«¨æã ®¡ê¥ªâ®¢
|
|
|
|
//ᥪæ¨ï .bss
|
|
|
|
if(wbss){ //¥áâì post ¯¥à¥¬¥ë¥
|
|
|
|
numobj++; //㢥«¨ç¨¢ ¥¬ ç¨á«® ®¡ê¥ªâ®¢
|
|
|
|
codenum=1; //®¬¥à ᥪ樨 ª®¤
|
|
|
|
strcpy(objentry->name,".bss"); //¨¬ï ᥪ樨
|
|
|
|
objentry->vsize=sizebss=Align(postsize,OBJECTALIGN);
|
|
|
|
objentry->pOffset=objentry->psize=0;
|
|
|
|
objentry->flags=0xC0000080;
|
|
|
|
objentry->sectionRVA=vsizeheader;
|
|
|
|
}
|
|
|
|
strcpy((objentry+codenum)->name,"CODE"); //¥¥ ¨¬ï
|
|
|
|
(objentry+codenum)->vsize=vsize; //à §¬¥à ᥪ樨 ¢ ¯ ¬ïâ¨
|
|
|
|
(objentry+codenum)->psize=psize; //à §¬¥à ᥪ樨 ¢ ä ©«¥
|
|
|
|
(objentry+codenum)->flags=0xe0000060; //ä« £ ᥪ樨
|
|
|
|
(objentry+codenum)->sectionRVA=vsizeheader+sizebss;//¢¨àâã «ìë© ¤à¥á ᥪ樨 ¢ ¯ ¬ïâ¨
|
|
|
|
//ᥪæ¨ï ¨¬¯®àâ
|
|
|
|
if(numapi!=0){ //¥áâì ¢ë§®¢ë api-¯à®æ¥¤ãà ᮧ¤ ᥪæ¨î ¨¬¯®àâ
|
|
|
|
if(!WinMonoBlock){ //¥á«¨ ¥ ¥¤¨ë© ¡«®ª
|
|
|
|
importnum=numobj;
|
|
|
|
numobj++; //㢥«¨ç¨¢ ¥¬ ç¨á«® ®¡ê¥ªâ®¢
|
|
|
|
}
|
|
|
|
startsec=vsizeheader+vsize+sizebss; // ç «® ᥪ樨 ¢ ¯ ¬ïâ¨
|
|
|
|
//ॠ«ìë© à §¬¥à ᥪ樨
|
|
|
|
startimportname=(numdll+1)*20+(numapi+numdll)*(shortimport==0?8:4);
|
|
|
|
sizeimport=Align(startimportname,FILEALIGN); //à §¬¥à ᥪ樨 ¢ ¯ ¬ïâ¨
|
|
|
|
importblock=(char *)MALLOC(sizeimport); //¯ ¬ïâì ¯®¤ ¥¥
|
|
|
|
memset(importblock,0,sizeimport); //®ç¨áâ¨âì ¥¥
|
|
|
|
DLLLIST *newdll=listdll; //â ¡«¨çª dll á ¨¬¯®àâ¨à㥬묨 ¯à®æ¥¤ãà ¬¨
|
|
|
|
unsigned long sn,sn1;
|
|
|
|
sn1=sn=(numdll+1)*20;
|
|
|
|
for(int i=0;;i++){
|
|
|
|
while(newdll->num==0)if((newdll=newdll->next)==NULL)break;//¯à®¯ã᪠¥¨á¯®«ì§ã¥¬ëå
|
|
|
|
if(newdll==NULL)break; //§ ¢¥àè¨âì 横« ¥á«¨ ᯨ᮪ dll ¯ãáâ
|
|
|
|
APIPROC *listapi=newdll->list; //â ¡«¨çª ¯à®æ¥¤ãà ¨§ ⥪ã饩 dll
|
|
|
|
*(long *)&importblock[i*20+12]=startsec+startimportname;
|
|
|
|
*(long *)&importblock[i*20]=(shortimport==0?startsec+sn:0);
|
|
|
|
*(long *)&importblock[i*20+16]=startsec+sn+(shortimport==0?(numdll+numapi)*4:0);
|
|
|
|
sn+=(newdll->num+1)*4;
|
|
|
|
unsigned int lenn=strlen(newdll->name)+1;
|
|
|
|
if((lenn+startimportname+1)>=sizeimport){
|
|
|
|
sizeimport+=FILEALIGN; //㢥«¨ç¨âì à §¬¥à ᥪ樨
|
|
|
|
importblock=(char *)REALLOC(importblock,sizeimport);
|
|
|
|
memset(importblock+sizeimport-FILEALIGN,0,FILEALIGN);
|
|
|
|
}
|
|
|
|
strcpy(&importblock[startimportname],newdll->name);
|
|
|
|
startimportname+=lenn;
|
|
|
|
for(int n=0,t=0;n<newdll->num;n++,t++){
|
|
|
|
while((listapi+t)->recapi->recrm==0)t++;
|
|
|
|
idrec *rec=(listapi+t)->recapi;
|
|
|
|
unsigned long newadr;
|
|
|
|
newadr=ImageBase+startsec+sn1+(shortimport==0?(numdll+numapi)*4:0);
|
|
|
|
if(rec->recrm==API_JMP)*(long *)&output[rec->recnumber]=newadr;
|
|
|
|
else{
|
|
|
|
for(unsigned int j=0;j<posts;j++){ //¯®¨áª ¨á¯®«ì§®¢ ¨ï ¯à®æ¥¤ãàë
|
|
|
|
if((postbuf+j)->num==(unsigned long)rec->recnumber&&(postbuf+j)->type==CALL_32I){
|
|
|
|
*(long *)&output[(postbuf+j)->loc]=newadr; //¨á¯à ¢¨âì
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(useordinal&&rec->recsib!=-1){
|
|
|
|
*(long *)&importblock[sn1]=rec->recsib|0x80000000;
|
|
|
|
if(shortimport==0)*(long *)&importblock[sn1+(numdll+numapi)*4]=rec->recsib|0x80000000;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
if((startimportname%2)==1)importblock[startimportname++]=0;
|
|
|
|
*(long *)&importblock[sn1]=startsec+startimportname;
|
|
|
|
if(shortimport==0)*(long *)&importblock[sn1+(numdll+numapi)*4]=startsec+startimportname;
|
|
|
|
if(rec->recsize!=-1)sprintf((char *)string2,"%s@%u",rec->recid,rec->recsize);
|
|
|
|
else strcpy((char *)string2,rec->recid);
|
|
|
|
lenn=strlen((char *)string2)+1;
|
|
|
|
if((lenn+startimportname+4)>=sizeimport){
|
|
|
|
sizeimport+=FILEALIGN;
|
|
|
|
importblock=(char *)REALLOC(importblock,sizeimport);
|
|
|
|
memset(importblock+sizeimport-FILEALIGN,0,FILEALIGN);
|
|
|
|
}
|
|
|
|
*(short *)&importblock[startimportname]=0;
|
|
|
|
startimportname+=2;
|
|
|
|
strcpy(&importblock[startimportname],(char *)string2);
|
|
|
|
startimportname+=lenn;
|
|
|
|
}
|
|
|
|
sn1+=4;
|
|
|
|
}
|
|
|
|
if(newdll->next==NULL)break;
|
|
|
|
newdll=newdll->next;
|
|
|
|
sn1+=4;
|
|
|
|
}
|
|
|
|
importblock[startimportname++]=0;
|
|
|
|
|
|
|
|
if(!WinMonoBlock){ //¥á«¨ ¥ ¥¤¨ë© ¡«®ª
|
|
|
|
strcpy((objentry+importnum)->name,".idata"); //¨¬ï ᥪ樨
|
|
|
|
(objentry+importnum)->vsize=sizeImport=Align(sizeimport,OBJECTALIGN);
|
|
|
|
(objentry+importnum)->psize=sizeimport;
|
|
|
|
(objentry+importnum)->flags=0xC0000040;
|
|
|
|
(objentry+importnum)->sectionRVA=startsec;
|
|
|
|
}
|
|
|
|
else sizeImport=sizeimport=Align(startimportname,4);
|
|
|
|
}
|
|
|
|
//ᥪæ¨ï íªá¯®àâ
|
|
|
|
if(numexport!=0){
|
|
|
|
if(!WinMonoBlock){ //¥á«¨ ¥ ¥¤¨ë© ¡«®ª
|
|
|
|
exportnum=numobj;
|
|
|
|
numobj++; //㢥«¨ç¨¢ ¥¬ ç¨á«® ®¡ê¥ªâ®¢
|
|
|
|
}
|
|
|
|
startsece=vsizeheader+vsize+sizeImport+sizebss;// ç «® ᥪ樨 ¢ ¯ ¬ïâ¨
|
|
|
|
startexportname=sizeof(EXPORT_TABLE)+numexport*10;//ॠ«ìë© à §¬¥à ᥪ樨
|
|
|
|
sizeexport=Align(startexportname,FILEALIGN); //à §¬¥à ᥪ樨 ¢ ¯ ¬ïâ¨
|
|
|
|
exportblock=(char *)MALLOC(sizeexport); //¯ ¬ïâì ¯®¤ ¥¥
|
|
|
|
memset(exportblock,0,sizeexport); //®ç¨áâ¨âì ¥¥
|
|
|
|
*(long *)&exportblock[12]=startsece+startexportname;// ¤à¥á ¨¬¥¨ ä ©«
|
|
|
|
*(long *)&exportblock[16]=1; //Ordinal Base
|
|
|
|
*(long *)&exportblock[20]=numexport; //Num of Functions
|
|
|
|
*(long *)&exportblock[24]=numexport; //Num of Name Pointer
|
|
|
|
*(long *)&exportblock[28]=startsece+sizeof(EXPORT_TABLE);//Address Table RVA
|
|
|
|
*(long *)&exportblock[32]=startsece+sizeof(EXPORT_TABLE)+numexport*4;//Name Pointers RVA
|
|
|
|
*(long *)&exportblock[36]=startsece+sizeof(EXPORT_TABLE)+numexport*8;//Ordinal Table RVA
|
|
|
|
char *oname;
|
|
|
|
strcpy((char *)string2,(char *)rawfilename);
|
|
|
|
oname=strrchr((char *)string2,'\\');
|
|
|
|
if(oname==NULL)oname=(char *)string2;
|
|
|
|
else oname=oname+1;
|
|
|
|
sprintf((char *)string,"%s.%s",oname,outext);
|
|
|
|
unsigned int lenn=strlen((char *)string)+1;
|
|
|
|
if((lenn+startexportname+1)>=sizeexport){
|
|
|
|
sizeexport+=FILEALIGN; //㢥«¨ç¨âì à §¬¥à ᥪ樨
|
|
|
|
exportblock=(char *)REALLOC(exportblock,sizeexport);
|
|
|
|
memset(exportblock+sizeexport-FILEALIGN,0,FILEALIGN);
|
|
|
|
}
|
|
|
|
strcpy(&exportblock[startexportname],(char *)string);
|
|
|
|
startexportname+=lenn;
|
|
|
|
for(int i=0;i<numexport;i++){
|
|
|
|
*(long *)&exportblock[sizeof(EXPORT_TABLE)+i*4]=(lexport+i)->address+vsizeheader+sizebss; // ¤à¥á äãªæ¨©
|
|
|
|
*(long *)&exportblock[sizeof(EXPORT_TABLE)+(numexport+i)*4]=startsece+startexportname; // ¤à¥á ¨¬¥
|
|
|
|
*(short *)&exportblock[sizeof(EXPORT_TABLE)+numexport*8+i*2]=(short)i; //®à¤¨ «ë ¨¬¥
|
|
|
|
lenn=strlen((lexport+i)->name)+1;
|
|
|
|
if((lenn+startexportname+1)>=sizeexport){
|
|
|
|
sizeexport+=FILEALIGN; //㢥«¨ç¨âì à §¬¥à ᥪ樨
|
|
|
|
exportblock=(char *)REALLOC(exportblock,sizeexport);
|
|
|
|
memset(exportblock+sizeexport-FILEALIGN,0,FILEALIGN);
|
|
|
|
}
|
|
|
|
strcpy(&exportblock[startexportname],(lexport+i)->name);
|
|
|
|
startexportname+=lenn;
|
|
|
|
}
|
|
|
|
free(lexport);//®á¢®¡®¤¨¬ 㦥 ¥ ã¦ë© ¡«®ª
|
|
|
|
if(!WinMonoBlock){ //¥á«¨ ¥ ¥¤¨ë© ¡«®ª
|
|
|
|
strcpy((objentry+exportnum)->name,".edata"); //¨¬ï ᥪ樨
|
|
|
|
(objentry+exportnum)->vsize=sizeExport=Align(sizeexport,OBJECTALIGN);
|
|
|
|
(objentry+exportnum)->psize=sizeexport;
|
|
|
|
(objentry+exportnum)->flags=0x40000040;
|
|
|
|
(objentry+exportnum)->sectionRVA=startsece;
|
|
|
|
}
|
|
|
|
else sizeexport=sizeExport=Align(startexportname,4);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(numres){ //ᥪæ¨ï à¥áãàᮢ
|
|
|
|
if(WinMonoBlock==FALSE){ //¥á«¨ ¥ ¥¤¨ë© ¡«®ª
|
|
|
|
resnum=numobj;
|
|
|
|
numobj++; //㢥«¨ç¨âì ç¨á«® ®¡ê¥ªâ®¢
|
|
|
|
}
|
|
|
|
startsecres=vsizeheader+vsize+sizeImport+sizebss+sizeExport;// ç «® ᥪ樨 ¢ ¯ ¬ïâ¨
|
|
|
|
LISTRELOC *resrel;
|
|
|
|
if(MakeRes(startsecres,&resrel))free(resrel);
|
|
|
|
if(!WinMonoBlock){ //¥á«¨ ¥ ¥¤¨ë© ¡«®ª
|
|
|
|
strcpy((objentry+resnum)->name,".rsrc"); //¨¬ï ᥪ樨
|
|
|
|
(objentry+resnum)->vsize=sizeRes=Align(curposbuf,OBJECTALIGN);
|
|
|
|
(objentry+resnum)->psize=sizeres=Align(curposbuf,FILEALIGN);
|
|
|
|
(objentry+resnum)->flags=0x40000040;
|
|
|
|
(objentry+resnum)->sectionRVA=startsecres;
|
|
|
|
}
|
|
|
|
else sizeres=Align(curposbuf,4);
|
|
|
|
}
|
|
|
|
|
|
|
|
//ᥪæ¨ï â ¡«¨æ ¯¥à¥¬¥é¥¨ï
|
|
|
|
if((FixUpTable==TRUE&&numrel!=0)/*||numexport!=0*/){//ᮧ¤ âì ᥪæ¨î ¯¥à¥¬¥é¥¨ï
|
|
|
|
if(WinMonoBlock==FALSE||dllflag==TRUE){ //¥á«¨ ¥ ¥¤¨ë© ¡«®ª ¨ íâ® DLL
|
|
|
|
relocnum=numobj;
|
|
|
|
numobj++; //㢥«¨ç¨âì ç¨á«® ®¡ê¥ªâ®¢
|
|
|
|
}
|
|
|
|
if(WinMonoBlock&&dllflag)startsecr=vsizeheader+
|
|
|
|
Align(sizeimport+sizeexport+outptr+(wbss==FALSE?postsize:0)+sizebss+sizeres,OBJECTALIGN);
|
|
|
|
else startsecr=vsizeheader+vsize+sizeImport+sizeExport+sizebss+sizeres; //¢¨àâã «ìë© ¤à¥á ᥪ樨 ¢ ¯ ¬ïâ¨
|
|
|
|
//䨧¨ç¥áª¨© à §¬¥à ᥪ樨 â ¡«¨æë ¯¥à¥¬¥é¥¨©
|
|
|
|
sizereloc=Align(numrel*2+(outptr/4096+1)*10,FILEALIGN);
|
|
|
|
sizeReloc=Align(sizereloc,OBJECTALIGN);//¢¨àâã «ìë© à §¬¥à í⮩ ᥪ樨
|
|
|
|
relocblock=(char *)MALLOC(sizereloc); //¯ ¬ïâì ¯®¤ íâã ᥪæ¨î
|
|
|
|
memset(relocblock,0,sizereloc); //®ç¨áâ¨âì ¥¥
|
|
|
|
//§ ¯®«ï¥¬ ᥪæ¨î ¯¥à¥¬¥é¥¨ï
|
|
|
|
unsigned int startrsec=0; // ¤à¥á ç « ¡«®ª ¢ ᥪ樨 ¯¥à¥¬¥é¥¨ï
|
|
|
|
unsigned int startblc=0; // ¤à¥á ¯¥à¢®£® ¡«®ª
|
|
|
|
posrel=8;
|
|
|
|
do{
|
|
|
|
unsigned char fr=FALSE; //ä« £ í«¥¬¥â
|
|
|
|
for(unsigned int i=0;i<posts;i++){ //®¡å®¤¨¬ ¢áî â ¡«¨æã post
|
|
|
|
if(
|
|
|
|
(
|
|
|
|
(postbuf+i)->type==CALL_32I||
|
|
|
|
((postbuf+i)->type>=POST_VAR32&&(postbuf+i)->type<=FIX_CODE32))
|
|
|
|
&&
|
|
|
|
(postbuf+i)->loc>=startblc&&(postbuf+i)->loc<(startblc+4096)){
|
|
|
|
*(short *)&relocblock[posrel]=(short)((postbuf+i)->loc%4096|0x3000);
|
|
|
|
posrel+=2;
|
|
|
|
fr=TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(fr!=FALSE){ //¥á«¨ ¡ë«¨ ¯¥à¥¬¥é ¥¬ë¥ ¤à¥á
|
|
|
|
posrel+=posrel%4; //¢ëà ¢¨¢ ¥¬
|
|
|
|
*(long *)&relocblock[startrsec]=vsizeheader+sizebss+startblc;
|
|
|
|
*(long *)&relocblock[startrsec+4]=posrel-startrsec; //à §¬¥à ªãáª
|
|
|
|
startrsec=posrel;
|
|
|
|
posrel+=8;
|
|
|
|
}
|
|
|
|
startblc+=4096;
|
|
|
|
}while(startblc<vsize);
|
|
|
|
posrel-=8;
|
|
|
|
if(WinMonoBlock==FALSE||dllflag==TRUE){ //¥á«¨ ¥ ¥¤¨ë© ¡«®ª
|
|
|
|
strcpy((objentry+relocnum)->name,".reloc"); //¨¬ï ᥪ樨
|
|
|
|
(objentry+relocnum)->vsize=sizeReloc; //à §¬¥à ᥪ樨 ¢ ¯ ¬ïâ¨
|
|
|
|
(objentry+relocnum)->psize=sizereloc; //à §¬¥à ᥪ樨 ¢ ä ©«¥
|
|
|
|
(objentry+relocnum)->flags=0x52000040; //ä« £ ᥪ樨
|
|
|
|
(objentry+relocnum)->sectionRVA=startsecr; //¢¨àâã «ìë© ¤à¥á ᥪ樨 ¢ ¯ ¬ïâ¨
|
|
|
|
}
|
|
|
|
else sizereloc=Align(posrel,4);
|
|
|
|
}
|
|
|
|
if(WinMonoBlock){
|
|
|
|
psize=sizeimport+sizeexport+(dllflag==FALSE?sizereloc:0)+sizeres; //à §¬¥à ¤®¯®«¨â¥«ìëå ¤ ëå
|
|
|
|
if(wbss==0){
|
|
|
|
for(unsigned int i=0;i<posts;i++){
|
|
|
|
if((postbuf+i)->type==POST_VAR32)
|
|
|
|
*(long *)&output[(postbuf+i)->loc]+=psize;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
psize+=outptr;
|
|
|
|
(objentry+codenum)->vsize=vsize=Align(psize+(wbss==FALSE?postsize:0),OBJECTALIGN);//¢¨àâã «ìë© à §¬¥à ᥪ樨 ª®¤
|
|
|
|
filingzerope=(objentry+codenum)->psize=Align(psize,FILEALIGN); //䨧¨ç¥áª¨© à §¬¥à ᥪ樨 ª®¤
|
|
|
|
filingzerope-=psize;
|
|
|
|
psize=(objentry+codenum)->psize;
|
|
|
|
sizeImport=sizeExport=0;
|
|
|
|
if(dllflag==FALSE)sizeReloc=0;
|
|
|
|
}
|
|
|
|
PE_HEADER *peheader=(PE_HEADER *)MALLOC(sizeof(PE_HEADER));
|
|
|
|
memset(peheader,0,sizeof(PE_HEADER));
|
|
|
|
sizehead=Align(sizeof(PE_HEADER)+sizestub+(numobj+(numres!=0?0:1))*sizeof(OBJECT_ENTRY),FILEALIGN);
|
|
|
|
#ifdef _WC_
|
|
|
|
peheader->sign='EP';
|
|
|
|
#else
|
|
|
|
peheader->sign='PE';
|
|
|
|
#endif
|
|
|
|
peheader->cpu=0x14c;//(chip>=4?(chip>=5?0x14e:0x14D):0x14c);
|
|
|
|
// peheader->date_time=0;
|
|
|
|
peheader->DLLflag=dllflag;
|
|
|
|
peheader->numobj=numobj;
|
|
|
|
peheader->NTheadsize=0xe0;
|
|
|
|
peheader->flags=(short)(0x818e|(dllflag==0?0:0x2000));
|
|
|
|
peheader->Magic=0x10b;
|
|
|
|
peheader->LinkVer=(short)((short)ver2*256+ver1);
|
|
|
|
peheader->sizecode=psize;
|
|
|
|
peheader->sizeuninitdata=postsize;
|
|
|
|
{
|
|
|
|
unsigned int temp;
|
|
|
|
temp=EntryPoint();
|
|
|
|
if(temp==0xffffffff)peheader->EntryRVA=0;
|
|
|
|
else peheader->EntryRVA=vsizeheader+sizebss+temp;
|
|
|
|
}
|
|
|
|
peheader->basecode=vsizeheader+sizebss;
|
|
|
|
peheader->objAlig=OBJECTALIGN;
|
|
|
|
peheader->fileAlig=FILEALIGN;
|
|
|
|
peheader->OSver=1;
|
|
|
|
peheader->SubSysVer=4;
|
|
|
|
peheader->ImageBase=ImageBase;
|
|
|
|
peheader->headsize=sizehead;
|
|
|
|
peheader->imagesize=vsizeheader+ //à §¬¥à § £®«®¢ª
|
|
|
|
vsize+ //à §¬¥à ª®¤
|
|
|
|
sizebss+ //à §¬¥à post ¡«®ª
|
|
|
|
sizeReloc+ //à §¬¥à â ¡«¨æë ¯¥à¥¬¥é¥¨ï
|
|
|
|
sizeImport+//à §¬¥à â ¡«¨æë ¨¬¯®àâ
|
|
|
|
sizeRes+ //à §¬¥à â ¡«¨æë à¥áãàᮢ
|
|
|
|
sizeExport;//à §¬¥à â ¡«¨æë íªá¯®àâ
|
|
|
|
peheader->SubSys=(short)(2+wconsole); //GUIWIN
|
|
|
|
peheader->stackRezSize=stacksize*0x10;
|
|
|
|
peheader->stackComSize=stacksize;
|
|
|
|
peheader->heapRezSize=0x10000;
|
|
|
|
peheader->heapComSize=0x1000;//postsize; //????
|
|
|
|
peheader->numRVA=0x10;
|
|
|
|
if(!usestub){
|
|
|
|
peheader->basedata=12;
|
|
|
|
peheader->pCOFF=0x40;
|
|
|
|
}
|
|
|
|
(objentry+codenum)->pOffset=sizehead;
|
|
|
|
if(numapi){
|
|
|
|
if(!WinMonoBlock)(objentry+importnum)->pOffset=sizehead+psize;
|
|
|
|
peheader->importRVA=startsec;
|
|
|
|
peheader->importSize=startimportname;
|
|
|
|
}
|
|
|
|
if(numexport){
|
|
|
|
if(!WinMonoBlock)(objentry+exportnum)->pOffset=sizehead+psize+sizeimport;
|
|
|
|
peheader->exportRVA=startsece;
|
|
|
|
peheader->exportSize=startexportname;
|
|
|
|
}
|
|
|
|
if(numres){
|
|
|
|
if(!WinMonoBlock)(objentry+resnum)->pOffset=sizehead+psize+sizeimport+sizeexport;
|
|
|
|
peheader->resourRVA=startsecres;
|
|
|
|
peheader->resourSize=curposbuf;
|
|
|
|
}
|
|
|
|
if(posrel){
|
|
|
|
if(!WinMonoBlock)(objentry+relocnum)->pOffset=sizehead+psize+sizeimport+sizeexport+sizeres;
|
|
|
|
else if(dllflag)(objentry+relocnum)->pOffset=sizehead+psize;
|
|
|
|
peheader->fixupRVA=startsecr;
|
|
|
|
peheader->fixupSize=posrel;
|
|
|
|
}
|
|
|
|
if(fwrite(peheader,sizeof(PE_HEADER),1,hout)!=1){
|
|
|
|
errwrite:
|
|
|
|
ErrWrite();
|
|
|
|
fclose(hout);
|
|
|
|
hout=NULL;
|
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
if(fwrite(objentry,sizeof(OBJECT_ENTRY)*numobj,1,hout)!=1)goto errwrite;
|
|
|
|
ChSize(sizehead);
|
|
|
|
runfilesize=sizehead+psize;
|
|
|
|
outputcodestart=ftell(hout);
|
|
|
|
if(fwrite(output,outptr,1,hout)!=1)goto errwrite; //¡«®ª ª®¤
|
|
|
|
if(!WinMonoBlock){
|
|
|
|
filingzerope=psize-outptr;
|
|
|
|
ChSize(runfilesize);
|
|
|
|
}
|
|
|
|
if(numapi){
|
|
|
|
if(fwrite(importblock,sizeimport,1,hout)!=1)goto errwrite;
|
|
|
|
free(importblock);
|
|
|
|
}
|
|
|
|
if(numexport){
|
|
|
|
if(fwrite(exportblock,sizeexport,1,hout)!=1)goto errwrite;
|
|
|
|
free(exportblock);
|
|
|
|
}
|
|
|
|
if(numres){
|
|
|
|
if(fwrite(resbuf,sizeres,1,hout)!=1)goto errwrite;
|
|
|
|
free(resbuf);
|
|
|
|
}
|
|
|
|
if(posrel){
|
|
|
|
if(WinMonoBlock&&dllflag)ChSize(runfilesize);
|
|
|
|
if(fwrite(relocblock,sizereloc,1,hout)!=1)goto errwrite;
|
|
|
|
free(relocblock);
|
|
|
|
}
|
|
|
|
if(WinMonoBlock){
|
|
|
|
if(dllflag)runfilesize+=sizereloc;
|
|
|
|
}
|
|
|
|
else runfilesize+=sizereloc+sizeimport+sizeexport+sizeres;
|
|
|
|
ChSize(runfilesize);
|
|
|
|
free(peheader);
|
|
|
|
free(objentry);
|
|
|
|
fclose(hout);
|
|
|
|
hout=NULL;
|
|
|
|
ImageBase+=vsizeheader+sizebss; //¨§¬ à §¬¥à ¤«ï «¨á⨣
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ChSize(long size)
|
|
|
|
{
|
|
|
|
char buf[256];
|
|
|
|
long delta,ssave;
|
|
|
|
memset(buf,0,256);
|
|
|
|
delta=size-ftell(hout);
|
|
|
|
while(delta>0){
|
|
|
|
ssave=256;
|
|
|
|
if(delta<256)ssave=delta;
|
|
|
|
fwrite(buf,ssave,1,hout);
|
|
|
|
delta-=ssave;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int AlignCD(char segm,int val) //¢ëà ¢ïâì ¤ ë¥ ¨«¨ ª®¤
|
|
|
|
{
|
|
|
|
unsigned int a;
|
|
|
|
a=(segm==DS?outptrdata:outptr)%val;
|
|
|
|
if(a==0)val=0;
|
|
|
|
else val-=a;
|
|
|
|
a=0;
|
|
|
|
while(val!=0){
|
|
|
|
segm==DS?opd(aligner):op(0x90);
|
|
|
|
val--;
|
|
|
|
a++;
|
|
|
|
}
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CreatWinStub()
|
|
|
|
{
|
|
|
|
if(!usestub){
|
|
|
|
sizestub=SIZESTUB2;
|
|
|
|
hout=CreateOutPut(outext,"wb");
|
|
|
|
if(fwrite(stub2,SIZESTUB2,1,hout)!=1){
|
|
|
|
ErrWrite();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else CreatStub(winstub);
|
|
|
|
//¯®¤áç¨â âì ç¨á«® ᥪ権
|
|
|
|
if(wbss){
|
|
|
|
if(postsize)numrs++;
|
|
|
|
else wbss=FALSE;
|
|
|
|
}
|
|
|
|
if(WinMonoBlock==FALSE){ //¥á«¨ ¥ ¥¤¨ë© ¡«®ª
|
|
|
|
if(numapi)numrs++; //¥áâì ¢ë§®¢ë api-¯à®æ¥¤ãà
|
|
|
|
if(numexport)numrs++; //ᮧ¤ âì ᥪæ¨î ¨¬¯®àâ
|
|
|
|
if((FixUpTable==TRUE&&posts)/*||numexport!=0*/)numrs++; //ᮧ¤ âì ᥪæ¨î ¯¥à¥¬¥é¥¨ï
|
|
|
|
if(numres)numrs++; //à¥áãàáë
|
|
|
|
}
|
|
|
|
else if(dllflag&&FixUpTable==TRUE&&posts!=0)numrs++; //ᮧ¤ âì ᥪæ¨î ¯¥à¥¬¥é¥¨ï
|
|
|
|
//à §¬¥à § £à㧮箣® ®¡à §
|
|
|
|
vsizeheader=Align(numrs*sizeof(OBJECT_ENTRY)+sizeof(PE_HEADER)+sizestub,0x1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ImportName(char *name)
|
|
|
|
{
|
|
|
|
FILE *infile;
|
|
|
|
union{
|
|
|
|
PE_HEADER pe;
|
|
|
|
OBJECT_ENTRY obj;
|
|
|
|
};
|
|
|
|
unsigned long temp;
|
|
|
|
unsigned long ulexport; //ᥪæ¨ï á ¥ªá¯®à⮬
|
|
|
|
unsigned long numobj; //ç¨á«® ®¡ê¥ªâ®¢
|
|
|
|
unsigned long posdll; //¯®§¨æ¨ï ᥪ樨 ¢ ä ©«¥
|
|
|
|
unsigned long nameadr; //â ¡«¨æ ¤à¥á®¢ ¨¬¥
|
|
|
|
unsigned long startname; // ç «® ¨¬¥¨
|
|
|
|
unsigned long ordinallist,ordinalbase;
|
|
|
|
unsigned int i,j;
|
|
|
|
DLLLIST *newdll;
|
|
|
|
APIPROC *listapi;
|
|
|
|
if((infile=fopen(name,"rb"))==NULL){
|
|
|
|
ErrOpenFile(name);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
fseek(infile,0x3C,SEEK_SET);
|
|
|
|
if(fread(&temp,4,1,infile)!=1){
|
|
|
|
errread:
|
|
|
|
//fprintf(stderr,"Unable to read from file %s.\n",name);
|
|
printf("Unable to read from file %s.\n",name);
|
|
fclose(infile);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
fseek(infile,0,SEEK_END);
|
|
|
|
if((unsigned long)ftell(infile)<=temp){
|
|
|
|
//fprintf(stderr,"Bad file %s.\n",name);
|
|
printf("Bad file %s.\n",name);
|
|
fclose(infile);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
fseek(infile,temp,SEEK_SET);
|
|
|
|
if(fread(&pe,sizeof(PE_HEADER),1,infile)!=1)goto errread;
|
|
|
|
if(pe.sign!=
|
|
|
|
#ifdef _WC_
|
|
|
|
'EP'
|
|
|
|
#else
|
|
|
|
'PE'
|
|
|
|
#endif
|
|
|
|
){
|
|
|
|
//fprintf(stderr,"For DLL support only format PE.\n");
|
|
printf("For DLL support only format PE.\n");
|
|
|
|
fclose(infile);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if((ulexport=pe.exportRVA)==0){
|
|
|
|
//fprintf(stderr,"No export directory on %s.\n",name);
|
|
printf("No export directory on %s.\n",name);
|
|
fclose(infile);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
numobj=pe.numobj;
|
|
|
|
temp=pe.objAlig;
|
|
|
|
while(numobj!=0){
|
|
|
|
if(fread(&obj,sizeof(OBJECT_ENTRY),1,infile)!=1)goto errread;
|
|
|
|
if((obj.sectionRVA+Align(obj.psize,temp))>ulexport)break;
|
|
|
|
numobj--;
|
|
|
|
}
|
|
|
|
if(numobj==0){
|
|
|
|
//fprintf(stderr,"Bad object table in %s.\n",name);
|
|
printf("Bad object table in %s.\n",name);
|
|
fclose(infile);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
posdll=obj.pOffset+ulexport-obj.sectionRVA;
|
|
|
|
fseek(infile,posdll+24,SEEK_SET);
|
|
|
|
if(fread(&numobj,4,1,infile)!=1)goto errread;
|
|
|
|
fseek(infile,posdll+32,SEEK_SET);
|
|
|
|
if(fread(&nameadr,4,1,infile)!=1)goto errread;
|
|
|
|
if(fread(&ordinallist,4,1,infile)!=1)goto errread;
|
|
|
|
nameadr-=ulexport;
|
|
|
|
ordinallist-=ulexport;
|
|
|
|
fseek(infile,posdll+12,SEEK_SET);
|
|
|
|
if(fread(&startname,4,1,infile)!=1)goto errread;
|
|
|
|
if(fread(&ordinalbase,4,1,infile)!=1)goto errread;
|
|
|
|
fseek(infile,posdll+startname-ulexport,SEEK_SET);
|
|
|
|
j=0;
|
|
|
|
do{
|
|
|
|
if(fread(&string[j],1,1,infile)!=1)goto errread;
|
|
|
|
}while(string[j++]!=0); //¨¬ï ¡¨¡«¨®â¥ª¨
|
|
|
|
newdll=FindDLL();
|
|
|
|
listapi=newdll->list;
|
|
|
|
|
|
|
|
for(i=0;i<numobj;i++){
|
|
|
|
fseek(infile,posdll+nameadr,SEEK_SET);
|
|
|
|
if(fread(&startname,4,1,infile)!=1)goto errread;
|
|
|
|
fseek(infile,posdll+startname-ulexport,SEEK_SET);
|
|
|
|
itok.size=-1;
|
|
|
|
j=0;
|
|
|
|
unsigned char c;
|
|
|
|
do{
|
|
|
|
if(fread(&c,1,1,infile)!=1)goto errread;
|
|
|
|
if(c=='@'){
|
|
|
|
itok.name[j]=0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
itok.name[j]=c;
|
|
|
|
j++;
|
|
|
|
}while(j<=IDLENGTH&&c!=0);
|
|
|
|
if(c=='@'){
|
|
|
|
j=0;
|
|
|
|
do{
|
|
|
|
if(fread(&c,1,1,infile)!=1)goto errread;
|
|
|
|
string[j++]=c;
|
|
|
|
}while(isdigit(c));
|
|
|
|
itok.size=getnumber(string);
|
|
|
|
}
|
|
|
|
tok=tk_id;
|
|
|
|
searchvar(itok.name);
|
|
|
|
if(tok==tk_id){
|
|
|
|
fseek(infile,posdll+ordinallist,SEEK_SET);
|
|
|
|
itok.sib=0;
|
|
|
|
if(fread(&itok.sib,2,1,infile)!=1)goto errread;
|
|
|
|
itok.sib+=ordinalbase;
|
|
|
|
tok=tk_apiproc;
|
|
|
|
itok.number=secondcallnum++;
|
|
|
|
itok.segm=NOT_DYNAMIC;
|
|
|
|
string[0]=0;
|
|
|
|
if(newdll->num==0)listapi=(APIPROC *)MALLOC(sizeof(APIPROC)); //¯¥à¢ ï ¢ ᯨ᪥
|
|
|
|
else listapi=(APIPROC *)REALLOC(listapi,sizeof(APIPROC)*(newdll->num+1));
|
|
|
|
(listapi+newdll->num)->recapi=addtotree(itok.name);
|
|
|
|
newdll->num++;
|
|
|
|
}
|
|
|
|
nameadr+=4;
|
|
|
|
ordinallist+=2;
|
|
|
|
}
|
|
|
|
newdll->list=listapi;
|
|
|
|
fclose(infile);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CreatStub(char *name)
|
|
|
|
{
|
|
|
|
sizestub=SIZESTUB;
|
|
|
|
hout=CreateOutPut(outext,"wb");
|
|
|
|
sprintf(&stub[STRVERS],"%s%s",compilerstr,__DATE__);
|
|
|
|
if(name==NULL){
|
|
|
|
stdstub:
|
|
|
|
if(fwrite(stub,SIZESTUB,1,hout)!=1){
|
|
|
|
errwrite:
|
|
|
|
ErrWrite();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
EXE_DOS_HEADER exeheader; // header for EXE format
|
|
|
|
FILE *stubin;
|
|
|
|
if((stubin=fopen(name,"rb"))==NULL){
|
|
|
|
ErrOpenFile(name);
|
|
|
|
goto stdstub;
|
|
|
|
}
|
|
|
|
if(fread(&exeheader,sizeof(EXE_DOS_HEADER),1,stubin)!=1){
|
|
|
|
errread:
|
|
|
|
ErrReadStub();
|
|
|
|
fclose(stubin);
|
|
|
|
goto stdstub;
|
|
|
|
}
|
|
|
|
if(exeheader.sign!=0x5A4D){
|
|
|
|
errstub:
|
|
|
|
//fprintf(stderr,"File %s can not be stub file.\n",name);
|
|
printf("File %s can not be stub file.\n",name);
|
|
fclose(stubin);
|
|
|
|
goto stdstub;
|
|
|
|
}
|
|
|
|
fseek(stubin,0,SEEK_END);
|
|
|
|
sizestub=ftell(stubin);
|
|
|
|
unsigned long temp;
|
|
|
|
if(exeheader.ofsreloc>=0x40){ //¯à®¢¥àª çâ® íâ® ¥ 32-¡¨âë© ä ©«
|
|
|
|
fseek(stubin,0x3c,SEEK_SET);
|
|
|
|
if(fread(&temp,4,1,stubin)!=1)goto errread;
|
|
|
|
if(temp<sizestub){
|
|
|
|
fseek(stubin,temp,SEEK_SET);
|
|
|
|
if(fread(&temp,4,1,stubin)!=1)goto errread;
|
|
|
|
switch(temp){
|
|
|
|
#ifdef _WC_
|
|
|
|
case 'EP':
|
|
|
|
case 'EN':
|
|
|
|
case 'EL':
|
|
|
|
case 'XL':
|
|
|
|
#else
|
|
|
|
case 'PE':
|
|
|
|
case 'NE':
|
|
|
|
case 'LE':
|
|
|
|
case 'LX':
|
|
|
|
#endif
|
|
|
|
goto errstub;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
exeheader.ofsreloc+=(unsigned short)0x20;
|
|
|
|
}
|
|
|
|
else exeheader.ofsreloc=0x40;
|
|
|
|
//à §¬¥à ä ©«
|
|
|
|
sizestub=Align(sizestub+32,8);
|
|
|
|
fseek(stubin,0x20,SEEK_SET);
|
|
|
|
exeheader.headsize+=(unsigned short)2;
|
|
|
|
if(fwrite(&exeheader,sizeof(EXE_DOS_HEADER),1,hout)!=1)goto errwrite;
|
|
|
|
*(unsigned long *)&stub[STRVERS+28]=sizestub;
|
|
|
|
if(fwrite(&stub[STRVERS],32,1,hout)!=1)goto errwrite;
|
|
|
|
CopyFile(stubin,hout);
|
|
|
|
ChSize(sizestub);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#define MAXLISTNAME 1024
|
|
|
|
#define MAXNUMSYMBOL 128
|
|
|
|
#define MAXSIZESYMBOL MAXNUMSYMBOL*sizeof(IMAGE_SYMBOL)
|
|
|
|
#define MAXNUMRELOC 256
|
|
|
|
|
|
|
|
char *ListName;
|
|
|
|
unsigned long sizelistName,maxsizelistname,textnum,bssnum;
|
|
|
|
IMAGE_SYMBOL *isymbol;
|
|
|
|
unsigned long numsymbol,maxnumsymbol,maxnumnameid,maxnumreloc,numreloc;
|
|
|
|
int segtext,segbss;
|
|
|
|
extern int numextern;
|
|
|
|
IMAGE_RELOCATION *treloc;
|
|
|
|
|
|
|
|
struct NAMEID{
|
|
|
|
int num;
|
|
|
|
int id;
|
|
|
|
}*NameId;
|
|
|
|
|
|
|
|
#define MAXSIZENAMEID MAXNUMSYMBOL*sizeof(NAMEID)
|
|
|
|
|
|
|
|
void AddName(char *name,unsigned long size)
|
|
|
|
{
|
|
|
|
if(sizelistName+size+1>=maxsizelistname){
|
|
|
|
maxsizelistname+=MAXLISTNAME;
|
|
|
|
ListName=(char *)REALLOC(ListName,maxsizelistname);
|
|
|
|
}
|
|
|
|
strcpy(ListName+sizelistName,name);
|
|
|
|
sizelistName+=size+1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CreatSymbolTable(idrec *ptr)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
if(ptr!=NULL){
|
|
|
|
CreatSymbolTable(ptr->right);
|
|
|
|
if(ptr->rectok==tk_apiproc){
|
|
|
|
for(unsigned int j=0;j<posts;j++){ //¯®¨áª ¨á¯®«ì§®¢ ¨ï ¯à®æ¥¤ãàë
|
|
|
|
if((postbuf+j)->num==(unsigned long)ptr->recnumber&&((postbuf+j)->type==CALL_32I||(postbuf+j)->type==CALL_32)){
|
|
|
|
goto nameext;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if((externnum!=0&&ptr->rectok==tk_undefproc&&(ptr->flag&f_extern)!=0)||
|
|
|
|
((ptr->rectok==tk_proc||ptr->rectok==tk_interruptproc)&&ptr->recsegm>=NOT_DYNAMIC)||
|
|
|
|
((ptr->rectok>=tk_bits&&ptr->rectok<=tk_doublevar)||ptr->rectok==tk_structvar)){
|
|
|
|
nameext:
|
|
|
|
if(numsymbol+1>=maxnumsymbol){
|
|
|
|
maxnumsymbol+=MAXNUMSYMBOL;
|
|
|
|
isymbol=(IMAGE_SYMBOL *)REALLOC(isymbol,maxnumsymbol*sizeof(IMAGE_SYMBOL));
|
|
|
|
memset(isymbol+maxnumsymbol*sizeof(IMAGE_SYMBOL)-MAXSIZESYMBOL,0,MAXSIZESYMBOL); //®ç¨áâ¨âì ¥¥
|
|
|
|
}
|
|
|
|
if(ptr->rectok==tk_apiproc||ptr->rectok==tk_undefproc||
|
|
|
|
ptr->rectok==tk_proc||ptr->rectok==tk_interruptproc)(isymbol+numsymbol)->Type=32;
|
|
|
|
i=strlen(ptr->recid);
|
|
|
|
if(i>8){
|
|
|
|
(isymbol+numsymbol)->N.Name.Short=0;
|
|
|
|
(isymbol+numsymbol)->N.Name.Long=sizelistName+4;
|
|
|
|
AddName(ptr->recid,i);
|
|
|
|
}
|
|
|
|
else strncpy((isymbol+numsymbol)->N.sname,ptr->recid,i);
|
|
|
|
if(ptr->rectok!=tk_apiproc&&ptr->rectok!=tk_undefproc&&(ptr->flag&f_extern)==0){
|
|
|
|
(isymbol+numsymbol)->Value=ptr->recnumber;
|
|
|
|
if(ptr->rectok==tk_proc||ptr->rectok==tk_interruptproc)(isymbol+numsymbol)->SectionNumber=(short)(textnum+1);
|
|
|
|
else (isymbol+numsymbol)->SectionNumber=(short)((ptr->recpost==0?textnum:bssnum)+1);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
(NameId+numextern)->num=ptr->recnumber;
|
|
|
|
(NameId+numextern)->id=numsymbol;
|
|
|
|
numextern++;
|
|
|
|
if(numextern>=maxnumnameid){
|
|
|
|
maxnumnameid+=MAXNUMSYMBOL;
|
|
|
|
NameId=(NAMEID *)REALLOC(NameId,maxnumnameid*sizeof(NAMEID));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
(isymbol+numsymbol)->StorageClass=2;
|
|
|
|
numsymbol++;
|
|
|
|
}
|
|
|
|
CreatSymbolTable(ptr->left);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void FreeCoffBuf()
|
|
|
|
{
|
|
|
|
free(ListName);
|
|
|
|
free(isymbol);
|
|
|
|
free(NameId);
|
|
|
|
free(treloc);
|
|
|
|
fclose(hout);
|
|
|
|
hout=NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IncReloc()
|
|
|
|
{
|
|
|
|
numreloc++;
|
|
|
|
if(numreloc>=maxnumreloc){
|
|
|
|
maxnumreloc+=MAXNUMRELOC;
|
|
|
|
treloc=(IMAGE_RELOCATION *)REALLOC(treloc,maxnumreloc*sizeof(IMAGE_RELOCATION));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CreatRelocTable()
|
|
|
|
{
|
|
|
|
for(int j=0;j<posts;j++){
|
|
|
|
(treloc+numreloc)->VirtualAddress=(postbuf+j)->loc-startptr;
|
|
|
|
if((postbuf+j)->type>=CALL_32I&&(postbuf+j)->type<=FIX_CODE32){
|
|
|
|
switch((postbuf+j)->type){
|
|
|
|
case POST_VAR:
|
|
|
|
case POST_VAR32:
|
|
|
|
(treloc+numreloc)->Type=IMAGE_REL_I386_DIR32;
|
|
|
|
(treloc+numreloc)->SymbolTableIndex=segbss;
|
|
|
|
break;
|
|
|
|
case FIX_VAR:
|
|
|
|
case FIX_VAR32:
|
|
|
|
case FIX_CODE:
|
|
|
|
case FIX_CODE32:
|
|
|
|
(treloc+numreloc)->Type=IMAGE_REL_I386_DIR32;
|
|
|
|
(treloc+numreloc)->SymbolTableIndex=segtext;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
IncReloc();
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
for(int i=0;i<numextern;i++){
|
|
|
|
if((NameId+i)->num==(postbuf+j)->num){
|
|
|
|
if((postbuf+j)->type==EXT_VAR)(treloc+numreloc)->Type=IMAGE_REL_I386_DIR32;
|
|
|
|
else (treloc+numreloc)->Type=IMAGE_REL_I386_REL32;
|
|
|
|
(treloc+numreloc)->SymbolTableIndex=(NameId+i)->id;
|
|
|
|
IncReloc();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int MakeCoff()
|
|
|
|
{
|
|
|
|
COFF_HEADER chead;
|
|
|
|
unsigned long sizehead,curobj,resnum,numresrel,segres,lastoffset,headernum;
|
|
|
|
OBJECT_ENTRY *objentry;
|
|
|
|
int i;
|
|
|
|
LISTRELOC *resrel=NULL;
|
|
|
|
char *codesecname;
|
|
|
|
hout=CreateOutPut("obj","wb");
|
|
|
|
chead.cpu=0x14c;
|
|
|
|
chead.SizeOfOptionalHeader=0;
|
|
|
|
chead.date_time=0;
|
|
|
|
chead.Characteristics=0x100;
|
|
|
|
/*if(header)*/numrs=2;
|
|
|
|
//¯®¤áç¨â âì ç¨á«® ᥪ権
|
|
|
|
if(wbss){
|
|
|
|
if(postsize)numrs++;
|
|
|
|
else wbss=FALSE;
|
|
|
|
}
|
|
|
|
if(numres)numrs++; //à¥áãàáë
|
|
|
|
chead.numobj=numrs;
|
|
|
|
sizehead=numrs*sizeof(OBJECT_ENTRY);
|
|
|
|
objentry=(OBJECT_ENTRY *)MALLOC(sizehead);//â ¢«¨æ ®¡ê¥ªâ®¢
|
|
|
|
memset(objentry,0,sizehead);//®ç¨áâ¨âì â ¡«¨æã ®¡ê¥ªâ®¢
|
|
|
|
curobj=0;
|
|
|
|
lastoffset=sizehead+sizeof(COFF_HEADER);
|
|
|
|
// if(header){
|
|
|
|
strcpy((objentry+curobj)->name,".version");
|
|
|
|
sprintf(&stub[STRVERS],"%s%s",compilerstr,__DATE__);
|
|
|
|
(objentry+curobj)->psize=strlen(&stub[STRVERS])+1;
|
|
|
|
(objentry+curobj)->pOffset=lastoffset;
|
|
|
|
(objentry+curobj)->flags=0x100A00;
|
|
|
|
headernum=curobj;
|
|
|
|
lastoffset+=(objentry+curobj)->psize;
|
|
|
|
curobj++;
|
|
|
|
// }
|
|
|
|
codesecname=".text";
|
|
|
|
if(splitdata==FALSE)codesecname=".codedat";
|
|
|
|
strcpy((objentry+curobj)->name,codesecname);
|
|
|
|
(objentry+curobj)->psize=outptr;
|
|
|
|
(objentry+curobj)->pOffset=lastoffset;
|
|
|
|
(objentry+curobj)->flags=0xE0300060;
|
|
|
|
lastoffset+=outptr;
|
|
|
|
textnum=curobj;
|
|
|
|
curobj++;
|
|
|
|
if(wbss){
|
|
|
|
strcpy((objentry+curobj)->name,".bss");
|
|
|
|
(objentry+curobj)->psize=postsize;
|
|
|
|
(objentry+curobj)->flags=0xC0300080;
|
|
|
|
bssnum=curobj;
|
|
|
|
curobj++;
|
|
|
|
}
|
|
|
|
if(numres){
|
|
|
|
strcpy((objentry+curobj)->name,".rsrc$01");
|
|
|
|
numresrel=(objentry+curobj)->NumberOfRelocations=MakeRes(0,&resrel);
|
|
|
|
(objentry+curobj)->psize=curposbuf;
|
|
|
|
(objentry+curobj)->flags=0x40000040;
|
|
|
|
resnum=curobj;
|
|
|
|
}
|
|
|
|
sizelistName=0;numsymbol=0;
|
|
|
|
ListName=(char *)MALLOC(MAXLISTNAME);
|
|
|
|
isymbol=(IMAGE_SYMBOL *)MALLOC(MAXSIZESYMBOL);
|
|
|
|
memset(isymbol,0,MAXSIZESYMBOL); //®ç¨áâ¨âì ¥¥
|
|
|
|
maxsizelistname=MAXLISTNAME;
|
|
|
|
maxnumnameid=maxnumsymbol=MAXNUMSYMBOL;
|
|
|
|
NameId=(NAMEID *)MALLOC(MAXSIZENAMEID);
|
|
|
|
treloc=(IMAGE_RELOCATION *)MALLOC(sizeof(IMAGE_RELOCATION)*MAXNUMRELOC);
|
|
|
|
maxnumreloc=MAXNUMRELOC;
|
|
|
|
numreloc=0;
|
|
|
|
strcpy(isymbol->N.sname,"@comp.id");
|
|
|
|
isymbol->Value=0x141F8E;
|
|
|
|
isymbol->SectionNumber=-1;
|
|
|
|
isymbol->StorageClass=3;
|
|
|
|
strcpy((isymbol+1)->N.sname,".file");
|
|
|
|
(isymbol+1)->Value=1;
|
|
|
|
(isymbol+1)->SectionNumber=-2;
|
|
|
|
(isymbol+1)->StorageClass=0x67;
|
|
|
|
i=(strlen(startfileinfo->filename)-1)/sizeof(IMAGE_SYMBOL)+1;
|
|
|
|
(isymbol+1)->NumberOfAuxSymbols=i;
|
|
|
|
strcpy((isymbol+2)->N.sname,startfileinfo->filename);
|
|
|
|
numsymbol=i+2;
|
|
|
|
segtext=numsymbol;
|
|
|
|
strcpy((isymbol+numsymbol)->N.sname,codesecname);
|
|
|
|
(isymbol+numsymbol)->SectionNumber=textnum+1;
|
|
|
|
(isymbol+numsymbol)->StorageClass=3;
|
|
|
|
(isymbol+numsymbol)->NumberOfAuxSymbols=1;
|
|
|
|
numsymbol++;
|
|
|
|
(isymbol+numsymbol)->N.Name.Short=outptr;
|
|
|
|
numsymbol++;
|
|
|
|
if(wbss){
|
|
|
|
segbss=numsymbol;
|
|
|
|
strcpy((isymbol+numsymbol)->N.sname,".bss");
|
|
|
|
(isymbol+numsymbol)->SectionNumber=bssnum+1;
|
|
|
|
(isymbol+numsymbol)->StorageClass=3;
|
|
|
|
(isymbol+numsymbol)->NumberOfAuxSymbols=1;
|
|
|
|
numsymbol++;
|
|
|
|
(isymbol+numsymbol)->N.Name.Short=postsize;
|
|
|
|
numsymbol++;
|
|
|
|
strcpy((isymbol+numsymbol)->N.sname,"DGROUP");
|
|
|
|
(isymbol+numsymbol)->SectionNumber=bssnum+1;
|
|
|
|
(isymbol+numsymbol)->StorageClass=3;
|
|
|
|
}
|
|
|
|
strcpy((isymbol+numsymbol)->N.sname,"FLAT");
|
|
|
|
(isymbol+numsymbol)->SectionNumber=-1;
|
|
|
|
(isymbol+numsymbol)->StorageClass=3;
|
|
|
|
numsymbol++;
|
|
|
|
if(numres){
|
|
|
|
segres=numsymbol;
|
|
|
|
strcpy((isymbol+numsymbol)->N.sname,".rsrc$01");
|
|
|
|
(isymbol+numsymbol)->StorageClass=3;
|
|
|
|
(isymbol+numsymbol)->SectionNumber=resnum+1;
|
|
|
|
numsymbol++;
|
|
|
|
}
|
|
|
|
// if(header){
|
|
|
|
strcpy((isymbol+numsymbol)->N.sname,".version");
|
|
|
|
(isymbol+numsymbol)->SectionNumber=headernum+1;
|
|
|
|
(isymbol+numsymbol)->StorageClass=3;
|
|
|
|
numsymbol++;
|
|
|
|
// }
|
|
|
|
CreatSymbolTable(treestart);
|
|
|
|
CreatRelocTable();
|
|
|
|
(isymbol+segtext+1)->N.Name.Long=numreloc;
|
|
|
|
(objentry+textnum)->NumberOfRelocations=numreloc;
|
|
|
|
if(numreloc){
|
|
|
|
(objentry+textnum)->PointerToRelocations=lastoffset;
|
|
|
|
lastoffset+=sizeof(IMAGE_RELOCATION)*numreloc;
|
|
|
|
}
|
|
|
|
if(numres){
|
|
|
|
(objentry+resnum)->pOffset=lastoffset;
|
|
|
|
lastoffset+=curposbuf;
|
|
|
|
if(numresrel){
|
|
|
|
(objentry+resnum)->PointerToRelocations=lastoffset;
|
|
|
|
lastoffset+=sizeof(IMAGE_RELOCATION)*numresrel;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
chead.COFFsize=numsymbol;
|
|
|
|
if(numsymbol){
|
|
|
|
chead.pCOFF=lastoffset;
|
|
|
|
}
|
|
|
|
if(fwrite(&chead,sizeof(COFF_HEADER),1,hout)!=1){
|
|
|
|
errwrite:
|
|
|
|
ErrWrite();
|
|
|
|
free(objentry);
|
|
|
|
if(resrel)free(resrel);
|
|
|
|
FreeCoffBuf();
|
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
if(fwrite(objentry,sizehead,1,hout)!=1)goto errwrite;
|
|
|
|
// if(header){
|
|
|
|
if(fwrite(&stub[STRVERS],(objentry+headernum)->psize,1,hout)!=1)goto errwrite;
|
|
|
|
// }
|
|
|
|
if(fwrite(output,outptr,1,hout)!=1)goto errwrite; //¡«®ª ª®¤
|
|
|
|
if(numreloc){
|
|
|
|
if(fwrite(treloc,numreloc*sizeof(IMAGE_RELOCATION),1,hout)!=1)goto errwrite;
|
|
|
|
}
|
|
|
|
if(numres){
|
|
|
|
if(fwrite(resbuf,curposbuf,1,hout)!=1)goto errwrite;
|
|
|
|
free(resbuf);
|
|
|
|
if(numresrel){
|
|
|
|
IMAGE_RELOCATION *rrel;
|
|
|
|
rrel=(IMAGE_RELOCATION *)MALLOC(sizeof(IMAGE_RELOCATION)*numresrel);
|
|
|
|
for(i=0;i<numresrel;i++){
|
|
|
|
(rrel+i)->VirtualAddress=(resrel+i)->val;
|
|
|
|
(rrel+i)->Type=IMAGE_REL_I386_DIR32NB;
|
|
|
|
(rrel+i)->SymbolTableIndex=segres;
|
|
|
|
}
|
|
|
|
if(fwrite(rrel,sizeof(IMAGE_RELOCATION)*numresrel,1,hout)!=1)goto errwrite;
|
|
|
|
free(rrel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(numsymbol){
|
|
|
|
if(fwrite(isymbol,numsymbol*sizeof(IMAGE_SYMBOL),1,hout)!=1)goto errwrite;
|
|
|
|
if(sizelistName){
|
|
|
|
sizelistName+=4;
|
|
|
|
if(fwrite(&sizelistName,4,1,hout)!=1)goto errwrite;
|
|
|
|
if(fwrite(ListName,sizelistName-4,1,hout)!=1)goto errwrite;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
if(fwrite(&sizelistName,4,1,hout)!=1)goto errwrite;
|
|
|
|
sizelistName+=4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
runfilesize=lastoffset+sizelistName;
|
|
|
|
free(objentry);
|
|
|
|
if(resrel)free(resrel);
|
|
|
|
FreeCoffBuf();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|