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 DoTDS() { int retcode; unsigned int i,j; //создать файл if(lstflag)GeneratLst(); if(dbg&1){ //убрать из списка файлов не используемые for(i=0;i<totalmodule;i++){ if((startfileinfo+i)->numdline==0){ totalmodule--; if(totalmodule!=i){ memcpy(&(startfileinfo+i)->filename, &(startfileinfo+totalmodule)->filename,sizeof(FILEINFO)); //корректировка таблиц строк for(j=0;j<pdbg;j++){ if(dbgmod[j]==(unsigned short)totalmodule)dbgmod[j]=(unsigned short)i; } i--; } } } //создать таблицу корреляций corinfo=(struct _COR_INFO_ *)MALLOC(sizeof(_COR_INFO_)); corinfo->ofs=dbgloc[0]; corinfo->startline=0; omodule=corinfo->file=dbgmod[0]; numcorrel=0; for(j=1;j<pdbg;j++){ if((unsigned short)omodule!=dbgmod[j]){ (corinfo+numcorrel)->count=(unsigned short)(j-(corinfo+numcorrel)->startline); (corinfo+numcorrel)->end=dbgloc[j]-1; numcorrel++; corinfo=(struct _COR_INFO_ *)REALLOC(corinfo,sizeof(_COR_INFO_)*(numcorrel+1)); (corinfo+numcorrel)->ofs=dbgloc[j]; (corinfo+numcorrel)->startline=j; omodule=(corinfo+numcorrel)->file=dbgmod[j]; } } (corinfo+numcorrel)->count=(unsigned short)(pdbg-(corinfo+numcorrel)->startline); (corinfo+numcorrel)->end=dbgloc[j-1]+1; numcorrel++; hout=CreateOutPut("tds","wb"); if(am32)retcode=CreateW32Debug(); else retcode=CreateDosDebug(); if(retcode==0&&fwrite(output,outptr,1,hout)!=1)retcode=-1; if(retcode!=0)ErrWrite(); fclose(hout); hout=NULL; } }
static void near MsgAreaWrite(MAINFO *pmi, int closeit) { static int mai_fd=-1; static int ma_fd=-1; unsigned size; OVRLIST ol; struct _mfidx mfi; if (!do_marea) return; if (!pmi && ma_fd != -1 && closeit) { MAREA ma; long pos=lseek(ma_fd, 0L, SEEK_END); /* Find out the position of the last area in the file, so that we * * can fix the wraparound pointer in the first record to point * * to it. */ pos -= cbLast + ADATA_START; lseek(ma_fd, ADATA_START, SEEK_SET); if (read(ma_fd, (char *)&ma, sizeof ma) != sizeof ma) { printf("Error reading final msg area data!\n"); exit(1); } lseek(ma_fd, ADATA_START, SEEK_SET); ma.cbPrior=-pos; if (write(ma_fd, (char *)&ma, sizeof ma) != sizeof ma) { printf("Error writing final msg area data!\n"); exit(1); } close(ma_fd); close(mai_fd); ma_fd=-1; return; } if (ma_fd==-1 && !closeit) { char fname[PATHLEN]; dword dwId; dwId =MAREA_ID; if (strings[prm.marea_name]==0) { printf("Error! MSGAREA.CTL cannot be SILTed separately. Use\n" "\"SILT MAX\" and ensure that you have a \"Messages marea\"\n" "keyword in the Session Section.\n"); exit(1); } strcpy(fname, strings + prm.marea_name); strcat(fname, ".dat"); if ((ma_fd=sopen(fname, O_CREAT | O_TRUNC | O_RDWR | O_BINARY, SH_DENYNO, S_IREAD | S_IWRITE))==-1) { printf("\nCan't open msg area data file %s!\n", fname); exit(1); } if (write(ma_fd, (char*) &dwId, sizeof dwId) != sizeof dwId) { printf("\aError writing key to msg data file %s\n", fname); exit(1); } strcpy(fname, strings + prm.marea_name); strcat(fname, ".idx"); if ((mai_fd=sopen(fname, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, SH_DENYNO, S_IREAD | S_IWRITE))==-1) { printf("\nCan't open msg area index file %s!\n", fname); exit(1); } } if (pmi) { /* Fill out the structure length information */ pmi->ma.cbArea=sizeof(pmi->ma); pmi->ma.cbHeap=pmi->h.end - pmi->h.heap; pmi->ma.cbPrior=cbLast; /* Record the size of this area */ cbLast=pmi->ma.cbArea + pmi->ma.cbHeap + pmi->ma.num_override * sizeof(OVERRIDE); /* Default to Squish format */ if (!pmi->ma.type) pmi->ma.type=MSGTYPE_SQUISH; if ((pmi->ma.attribs & (MA_PUB|MA_PVT))==0) pmi->ma.attribs |= MA_PUB; /* Strip the trailing backslash for Squish-style msg areas */ if (pmi->ma.type & MSGTYPE_SQUISH) { char *p=pmi->h.heap + pmi->ma.path; int len; if (p[len=strlen(p)-1]==PATH_DELIM) p[len]=0; } /* Write the location of this area to the index file */ strnncpy(mfi.name, pmi->h.heap + pmi->ma.name, sizeof(mfi.name)); mfi.name_hash=SquishHash(pmi->h.heap + pmi->ma.name); mfi.ofs=tell(ma_fd); /* Touch the area's header, if necessary */ if ((pmi->ma.attribs & (MA_DIVBEGIN|MA_DIVEND))==0) assert_msgarea(pmi->h.heap + pmi->ma.path, pmi->ma.type, pmi->ma.killbyage, pmi->ma.killbynum, pmi->ma.killskip); /* Do a little bit of error checking */ if (pmi->ma.attribs & (MA_AUDIT) && pmi->ma.type != MSGTYPE_SQUISH) { printf("\n\aError! Style Audit can only be used in Squish areas! (area ending on line %d)\n", linenum); Compiling(-1, NULL, NULL); pmi->ma.attribs &= ~MA_AUDIT; } if (pmi->ma.attribs & (MA_ATTACH) && pmi->ma.type != MSGTYPE_SQUISH) { printf("\n\aError! Style Attach can only be used in Squish areas! (area ending on line %d)\n", linenum); Compiling(-1, NULL, NULL); pmi->ma.attribs &= ~MA_ATTACH; } /* Write the header to disk */ if (write(mai_fd, (char *)&mfi, sizeof mfi) != sizeof mfi) ErrWrite(); /* Write the main area data structure */ if (write(ma_fd, (char *)&pmi->ma, sizeof pmi->ma) != sizeof pmi->ma) ErrWrite(); /* Write all of the message area overrides */ for (ol=pmi->ol; ol; ol=ol->next) if (write(ma_fd, (char *)&ol->or, sizeof ol->or) != sizeof ol->or) ErrWrite(); /* Figure out the size of the zstr heap and write it, too */ size=pmi->h.end-pmi->h.heap; if (write(ma_fd, (char *)pmi->h.heap, size) != (signed)size) ErrWrite(); } #ifdef MAX_TRACKER if (*toNewOwner) { TRK t; if ((t=TrkOpen("TRK", TRUE)) != NULL) { TrkSetDefaultOwner(t, pmi->h.heap + pmi->ma.name, toNewOwner); TrkClose(t); } *toNewOwner=0; } #endif }
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; psize = Align(outptr, FILEALIGN); //физический размер секции кода } // 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); peheader->sign = 'P' + ('E' << 8); 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; }
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; }
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); 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) { case 'P'+('E'<<8): case 'N'+('E'<<8): case 'L'+('E'<<8): case 'L'+('X'<<8): 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); } }