Опубликован: 28.06.2006 | Уровень: специалист | Доступ: платный | ВУЗ: Московский государственный технический университет им. Н.Э. Баумана
Дополнительный материал 1:

Приложение A

< Лекция 15 || Дополнительный материал 1: 1234 || Дополнительный материал 2 >

A.3. pe.c

#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "pe.h"
#include "macros.h"

void  make_headers    (FILE* file, PINPUT_PARAMETERS inP);
void  make_text_section  (FILE* file, PINPUT_PARAMETERS inP);
void  make_cli_section  (FILE* file, PINPUT_PARAMETERS inP);
void  make_reloc_section (FILE* file, PINPUT_PARAMETERS inP);

unsigned long align(unsigned long x, unsigned long alignment)
{
  div_t t = div(x,alignment);
  return t.rem == 0 ? x : (t.quot+1)*alignment;
};

void make_file (FILE* file, PINPUT_PARAMETERS inP)
{
  make_headers(file, inP);      	// Stage 1
  make_text_section(file, inP); 	// Stage 2
  make_cli_section(file, inP);	// Stage 3
  make_reloc_section(file, inP);	// Stage 4
}

unsigned char msdos_header[128] = {
  0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 
  0x04, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 
  0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x40, 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, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 
  0x0E, 0x1F, 0xBA, 0x0E, 0x00, 0xB4, 0x09, 0xCD, 
  0x21, 0xB8, 0x01, 0x4C, 0xCD, 0x21, 0x54, 0x68, 
  0x69, 0x73, 0x20, 0x70, 0x72, 0x6F, 0x67, 0x72, 
  0x61, 0x6D, 0x20, 0x63, 0x61, 0x6E, 0x6E, 0x6F, 
  0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6E, 
  0x20, 0x69, 0x6E, 0x20, 0x44, 0x4F, 0x53, 0x20, 
  0x6D, 0x6F, 0x64, 0x65, 0x2E, 0x0D, 0x0D, 0x0A, 
  0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

// initialize constant fields in HEADERS structure
void make_headers_const(PHEADERS Hdr){
  memcpy(Hdr->ms_dos_header, msdos_header, 128);

  Hdr->signature = 0x00004550;

  Hdr->PeHdr.Machine = IMAGE_FILE_MACHINE_I386;
  Hdr->PeHdr.PointerToSymbolTable = 0;
  Hdr->PeHdr.NumberOfSymbols = 0;
  Hdr->PeHdr.OptionalHeaderSize = 0xe0;

  // Optional Header
  Hdr->OptHdr.Magic  = 0x010B;
  Hdr->OptHdr.LMajor = 6;
  Hdr->OptHdr.LMinor = 0;
  Hdr->OptHdr.SizeOfUninitializedData   = 0;
  Hdr->OptHdr.SectionAlignment      = SECTION_ALIGNMENT;
  Hdr->OptHdr.OSMajor = 4;
  Hdr->OptHdr.OSMinor = 0;
  Hdr->OptHdr.UserMajor = 0;
  Hdr->OptHdr.UserMinor = 0;
  Hdr->OptHdr.SubsysMajor = 4;
  Hdr->OptHdr.SubsysMinor = 0;
  Hdr->OptHdr.Reserved = 0;
  Hdr->OptHdr.FileCheckSum = 0;
  Hdr->OptHdr.DllFlags  = 0x400;
  Hdr->OptHdr.StackReserveSize  = 0x100000;
  Hdr->OptHdr.StackCommitSize = 0x1000;
  Hdr->OptHdr.HeapReserveSize = 0x100000;
  Hdr->OptHdr.HeapCommitSize = 0x1000;
  Hdr->OptHdr.LoaderFlags = 0;
  Hdr->OptHdr.NumberOfDataDirectories = 16;

  // TEXT section
  Hdr->TEXT_SECTION.PointerToRelocations = 0;
  Hdr->TEXT_SECTION.PointerToLinenumbers = 0;
  Hdr->TEXT_SECTION.NumberOfRelocations  = 0;
  Hdr->TEXT_SECTION.NumberOfLinenumbers  = 0;
  Hdr->TEXT_SECTION.Characteristics    = 0x60000020;
  
  // CLI section
  Hdr->CLI_SECTION.PointerToRelocations  = 0;
  Hdr->CLI_SECTION.PointerToLinenumbers  = 0;
  Hdr->CLI_SECTION.NumberOfRelocations  = 0;
  Hdr->CLI_SECTION.NumberOfLinenumbers  = 0;
  Hdr->CLI_SECTION.Characteristics    = 0x60000020;

  // .RELOC section
  Hdr->RELOC_SECTION.PointerToRelocations = 0;
  Hdr->RELOC_SECTION.PointerToLinenumbers = 0;
  Hdr->RELOC_SECTION.NumberOfRelocations = 0;
  Hdr->RELOC_SECTION.NumberOfLinenumbers = 0;
  Hdr->RELOC_SECTION.Characteristics   = 0x42000040;

  // initialize to 0
  memset(&Hdr->STUB1.RVA, 0, SIZEOF_DATA_DIRECTORY);
  memset(Hdr->STUB2, 0, 3 * SIZEOF_DATA_DIRECTORY);
  memset(Hdr->STUB3, 0, 6 * SIZEOF_DATA_DIRECTORY);
  memset(&Hdr->STUB4.RVA, 0, SIZEOF_DATA_DIRECTORY);
  memset(&Hdr->STUB5.RVA, 0, SIZEOF_DATA_DIRECTORY);

};

// initialize HEADERS structure
void make_headers(FILE* file ,PINPUT_PARAMETERS inP){

  struct HEADERS Hdr;
  char * image;

  make_headers_const(&Hdr);
  Hdr.PeHdr.NumberOfSections = 3;
  Hdr.PeHdr.TimeDateStamp = (long)time(NULL);
  
  if(inP->Type == EXE_TYPE)
    Hdr.PeHdr.Characteristics = 0x010E;
  else 
    Hdr.PeHdr.Characteristics = 0x210E;

  Hdr.OptHdr.CodeSize = SIZEOF_TEXT_M(inP);
  Hdr.OptHdr.SizeOfInitializedData = SIZEOF_TEXT_M(inP);
  Hdr.OptHdr.EntryPointRVA = RVA_OF_CLI(inP);
  Hdr.OptHdr.BaseOfCode = RVA_OF_TEXT;
  Hdr.OptHdr.BaseOfData = 0;
  Hdr.OptHdr.ImageBase = inP->ImageBase;
  Hdr.OptHdr.FileAlignment = inP->FileAlignment;
  Hdr.OptHdr.ImageSize = RVA_OF_RELOC(inP) + SIZEOF_RELOC_M;
  Hdr.OptHdr.HeaderSize = SIZEOF_HEADERS(inP);
  Hdr.OptHdr.Subsystem = inP->Subsystem;

  // Import Directory
  Hdr.IMPORT_DIRECTORY.RVA    = RVA_OF_CLI(inP) + 
    OFFSETOF(struct CLI_SECTION_IMAGE,
      IMPORT_TABLE.ImportLookupTableRVA);
  Hdr.IMPORT_DIRECTORY.Size        = 0x53;

  // Import Address Directory
  Hdr.IAT_DIRECTORY.RVA    = RVA_OF_CLI(inP) + 
    OFFSETOF(struct CLI_SECTION_IMAGE, IMPORT_TABLE.HintNameTableRVA2);
  Hdr.IAT_DIRECTORY.Size         = 0x08;

  // Base Reloc Directory
  Hdr.BASE_RELOC_DIRECTORY.RVA = RVA_OF_RELOC(inP);
  Hdr.BASE_RELOC_DIRECTORY.Size      = 0x0C;

  // CLI Directory
  Hdr.CLI_DIRECTORY.RVA    = RVA_OF_CLI(inP) + SIZEOF_JMP_STUB;
  Hdr.CLI_DIRECTORY.Size   = SIZEOF_CLI_HEADER;

  //TEXT section
  memset(Hdr.TEXT_SECTION.Name, 0, sizeof(Hdr.TEXT_SECTION.Name));
  strcpy((char*)Hdr.TEXT_SECTION.Name, ".text");

  Hdr.TEXT_SECTION.VirtualSize    = SIZEOF_TEXT_NOTALIGNED(inP);
  Hdr.TEXT_SECTION.VirtualAddress   = SIZEOF_HEADERS_M(inP);
  Hdr.TEXT_SECTION.SizeOfRawData   = SIZEOF_TEXT(inP);
  Hdr.TEXT_SECTION.PointerToRawData  = SIZEOF_HEADERS(inP);
  //END of initializing TEXT section

  //.cli section
  memset(Hdr.CLI_SECTION.Name, 0, sizeof(Hdr.CLI_SECTION.Name));
  strcpy((char*)Hdr.CLI_SECTION.Name, ".cli");

  Hdr.CLI_SECTION.VirtualSize     = SIZEOF_CLI_NOTALIGNED;
  Hdr.CLI_SECTION.VirtualAddress   = SIZEOF_HEADERS_M(inP) + 
                     SIZEOF_TEXT_M(inP);
  Hdr.CLI_SECTION.SizeOfRawData    = SIZEOF_CLI(inP);
  Hdr.CLI_SECTION.PointerToRawData  = SIZEOF_HEADERS(inP) + 
                     SIZEOF_TEXT(inP);
  //END of initializing CLI section

  //.RELOC section
  memset(Hdr.RELOC_SECTION.Name, 0, sizeof(Hdr.RELOC_SECTION.Name));
  strcpy((char*)Hdr.RELOC_SECTION.Name, ".reloc");

  Hdr.RELOC_SECTION.VirtualSize     = SIZEOF_RELOC_NOTALIGNED;
  Hdr.RELOC_SECTION.VirtualAddress  = RVA_OF_RELOC(inP);
  Hdr.RELOC_SECTION.SizeOfRawData   = SIZEOF_RELOC(inP);
  Hdr.RELOC_SECTION.PointerToRawData = SIZEOF_HEADERS(inP) +
                     SIZEOF_TEXT(inP) + SIZEOF_CLI(inP); 
  //END of initializing .RELOC section

  image = malloc(SIZEOF_HEADERS(inP));

  memset(image,0,SIZEOF_HEADERS(inP));
  memcpy(image,(char *)&Hdr, SIZEOF_HEADERS_NOTALIGNED);
  fwrite(image,1,SIZEOF_HEADERS(inP),file);
  free(image);
};

// initialize .TEXT section
void make_text_section(FILE * file, PINPUT_PARAMETERS inP) {
  char * image;

  image = malloc(SIZEOF_TEXT(inP));
  memset(image, 0, SIZEOF_TEXT(inP));
  memcpy(image, inP->metadata, inP->SizeOfMetadata);
  memcpy(image+inP->SizeOfMetadata, inP->cilcode, 
			inP->SizeOfCilCode);

  fwrite(image, 1, SIZEOF_TEXT(inP), file);
  free(image);
}

// initialize .CLI section
void  make_cli_section(FILE * file, PINPUT_PARAMETERS inP) {
  struct CLI_SECTION_IMAGE cls;
  char * image;

  //JMP_STUB
  cls.JMP_STUB.JmpInstruction = 0x25FF;

  cls.JMP_STUB.JmpAddress   = RVA_OF_CLI(inP) + 
    OFFSETOF(struct CLI_SECTION_IMAGE, IMPORT_TABLE.Hint) + 
    inP->ImageBase;

  //CLI_HEADER
  cls.CLI_HEADER.cb           = SIZEOF_CLI_HEADER;
  cls.CLI_HEADER.MajorRuntimeVersion   = 2;
  cls.CLI_HEADER.MinorRuntimeVersion   = 0;
  cls.CLI_HEADER.MetaData.RVA      = RVA_OF_TEXT;
  cls.CLI_HEADER.MetaData.Size      = inP->SizeOfMetadata;
  cls.CLI_HEADER.Flags          = 1;
  cls.CLI_HEADER.EntryPointToken     = inP->EntryPointToken;

  memset(cls.CLI_HEADER.NotUsed, 0, 
			 6*sizeof(struct IMAGE_DATA_DIRECTORY));

  //Import Table
  cls.IMPORT_TABLE.ImportLookupTableRVA  = RVA_OF_CLI(inP) + 	
		OFFSETOF(struct CLI_SECTION_IMAGE, 
			IMPORT_TABLE.HintNameTableRVA1);

  cls.IMPORT_TABLE.TimeDateStamp   = 0;
  cls.IMPORT_TABLE.ForwarderChain   = 0;

  cls.IMPORT_TABLE.NameRVA      = RVA_OF_CLI(inP) +
    OFFSETOF(struct CLI_SECTION_IMAGE, IMPORT_TABLE.DllName);

  cls.IMPORT_TABLE.ImportAddressTableRVA = RVA_OF_CLI(inP) + 
    OFFSETOF(struct CLI_SECTION_IMAGE, 	IMPORT_TABLE.HintNameTableRVA2);

  memset(cls.IMPORT_TABLE.zero, 0, 20);

  cls.IMPORT_TABLE.HintNameTableRVA1 = (RVA_OF_CLI(inP) +
    OFFSETOF(struct CLI_SECTION_IMAGE, IMPORT_TABLE.Hint)) ;

  cls.IMPORT_TABLE.zero1 = 0;

  cls.IMPORT_TABLE.HintNameTableRVA2 = (RVA_OF_CLI(inP) +
    OFFSETOF(struct CLI_SECTION_IMAGE, IMPORT_TABLE.Hint));

  cls.IMPORT_TABLE.zero2 = 0;

  cls.IMPORT_TABLE.Hint = 0;

  if(inP->Type == EXE_TYPE) 
    strcpy(cls.IMPORT_TABLE.Name, "_CorExeMain");
  else 
    strcpy(cls.IMPORT_TABLE.Name, "_CorDllMain");

  strcpy(cls.IMPORT_TABLE.DllName, "mscoree.dll");

  image = malloc(SIZEOF_CLI(inP));
  memset(image, 0, SIZEOF_CLI(inP));
  memcpy(image, (char *) &cls, SIZEOF_CLI_NOTALIGNED);
  fwrite(image,1, SIZEOF_CLI(inP),file);
  free(image);
};

// initialize .RELOC section
void  make_reloc_section(FILE* file, PINPUT_PARAMETERS inP) {
  struct RELOC_SECTION  rls;
  char * image;

  rls.PageRVA   = RVA_OF_CLI(inP);
  rls.BlockSize  = SIZEOF_RELOC_NOTALIGNED;
  rls.TypeOffset  = TYPE_OFFSET(0x3,0x2);
  rls.Padding   = 0;
  
  image = malloc(SIZEOF_RELOC(inP));
  memset(image, 0, SIZEOF_RELOC(inP));
  memcpy(image, (char *)&rls, SIZEOF_RELOC_NOTALIGNED);
  fwrite(image,1, SIZEOF_RELOC(inP),file);
  free(image);
};
< Лекция 15 || Дополнительный материал 1: 1234 || Дополнительный материал 2 >
Анастасия Булинкова
Анастасия Булинкова
Рабочим названием платформы .NET было
Bogdan Drumov
Bogdan Drumov
Молдова, Республика
Azamat Nurmanbetov
Azamat Nurmanbetov
Киргизия, Bishkek