Example #1
0
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);
}
Example #2
0
//создание отладочного файла
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;
	}
}
Example #3
0
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
}
Example #4
0
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;
}
Example #5
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;
}
Example #6
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);
	}
}