[C++] PE Header

10/03/2011 13:43 yihaaa#1
Hallo, ich habe folgendes Problem.
Ich möchte eine neue Section in einen PE Header einbauen, aber mein Versuch scheitert daran, dass er mir meinen neuen PE Header nicht als valid ansieht.

Code:
	char* bnewSectionName = ".Test";

	IMAGE_SECTION_HEADER* newSection = (IMAGE_SECTION_HEADER*)((DWORD)&NTHeader->OptionalHeader + NTHeader->FileHeader.SizeOfOptionalHeader + (9 * sizeof(IMAGE_SECTION_HEADER)));
	memcpy(newSection->Name, &bnewSectionName, IMAGE_SIZEOF_SHORT_NAME);

	IMAGE_SECTION_HEADER* oldSection = (IMAGE_SECTION_HEADER*)((DWORD)&NTHeader->OptionalHeader + NTHeader->FileHeader.SizeOfOptionalHeader + (8 * sizeof(IMAGE_SECTION_HEADER)));

	newSection->Misc.PhysicalAddress = oldSection->Misc.PhysicalAddress + oldSection->Misc.VirtualSize;
	newSection->Misc.VirtualSize = 20;
	newSection->VirtualAddress = NULL; // ???
	newSection->SizeOfRawData = NULL;
	newSection->PointerToRawData = NULL;
	newSection->PointerToRelocations = 0x00000000;
	newSection->PointerToLinenumbers = 0x00000000;
	newSection->NumberOfRelocations = NULL;
	newSection->NumberOfLinenumbers = NULL;
	newSection->Characteristics = 0x00000000;
Ich habe die Anzahl der PE Header in meinem Programm erhöht. Die Image Size muss ich noch erhöhen und da ist auch schon meine erste Frage. Desweitern bin ich mit bei VirtualAddress und bei SizeOfRawData unsicher ob das so stimmt.
Wäre schön wenn mit jemand erklären würde wie man die Fehler die ich gemacht habe beheben kann.

MfG
10/03/2011 19:39 link#2
IMAGE_SECTION_HEADER.Misc ist eine Union, heißt also, beides individuell zu setzen, ergibt keinen Sinn.

Misc.VirtualSize ist halt die Größe der Sektion. Also PhysicalSize (sprich Größe des Codes) + Anzahl der Bytes die z.B. für uninitialisierte Variablen alloziiert werden sollen.
VirtualAddress ist die RVA der Sektion im Speicher. Mind. VirtualAddress der letzten Sektion + deren VirtualSize, aligned auf OptionalHeader.SectionAlignment.
SizeOfRawData ist gleich PhysicalSize, aligned auf OptionalHeader.FileAlignment.
PointerToRawData ist das FileOffset der Sektion, also PointerToRawData der letzten Sektion + deren SizeOfRawData.

Dann erhöhst du NumberOfSections, addierst zu SizeOfHeaders die Größe des neuen Sectionheaders und alignst ggf. auf OptionalHeader.FileAlignment.
Zuletzt addierst du zu ImageSize die VirtualSize der neuen Sektion und alignst auf OptionalHeader.SectionAlignment.

Vorrausgesetzt dass die vorherigen Angaben alle stimmen, ansonsten musst du sie halt neu berechnen
10/03/2011 21:44 yihaaa#3
Danke für den Post. Aber kannste du mir das mal mit dem align erklären? Habe ich noch nie mit gearbeitet.

MfG

Edit:

Code:
	char* bnewSectionName = ".Test";

	IMAGE_SECTION_HEADER* newSection = (IMAGE_SECTION_HEADER*)((DWORD)&NTHeader->OptionalHeader + NTHeader->FileHeader.SizeOfOptionalHeader + (9 * sizeof(IMAGE_SECTION_HEADER)));
	memcpy(newSection->Name, &bnewSectionName, IMAGE_SIZEOF_SHORT_NAME);

	IMAGE_SECTION_HEADER* oldSection = (IMAGE_SECTION_HEADER*)((DWORD)&NTHeader->OptionalHeader + NTHeader->FileHeader.SizeOfOptionalHeader + (8 * sizeof(IMAGE_SECTION_HEADER)));

	NTHeader->OptionalHeader.SizeOfHeaders = NTHeader->OptionalHeader.SizeOfHeaders + 0x20;
	NTHeader->OptionalHeader.SizeOfImage = NTHeader->OptionalHeader.SizeOfImage + 0x20;
	NTHeader->FileHeader.NumberOfSections = 9;

	//newSection->Misc.PhysicalAddress = oldSection->Misc.PhysicalAddress + oldSection->Misc.VirtualSize;
	newSection->Misc.VirtualSize = 0x20;

	DWORD candidate = oldSection->VirtualAddress + oldSection->Misc.VirtualSize;
	DWORD rest = candidate % NTHeader->OptionalHeader.SectionAlignment;
	DWORD diff = diff = NTHeader->OptionalHeader.SectionAlignment - rest;
	DWORD newAlignedVirtualAddress = candidate + diff;
	newSection->VirtualAddress = newAlignedVirtualAddress;

	newSection->SizeOfRawData = 0x20;
	newSection->PointerToRawData = oldSection->PointerToRawData + oldSection->SizeOfRawData;
	newSection->PointerToRelocations = 0x00000000;
	newSection->PointerToLinenumbers = 0x00000000;
	newSection->NumberOfRelocations = NULL;
	newSection->NumberOfLinenumbers = NULL;
	newSection->Characteristics = 0x00000000;
Ich hoffe ich hab ein wenig verbessert, so wie du es meintest. Geht leider immer nocht nicht.

MfG
10/03/2011 21:51 ms​#4
Das heißt, dass du den Wert erhöhen musst auf das nächste Vielfache des Alignments.
10/04/2011 22:19 Tyrar#5
Quote:
Originally Posted by Metin2Spieler97 View Post
Das heißt, dass du den Wert erhöhen musst auf das nächste Vielfache des Alignments.
Code:
alignment = (imagebase+filealignment)-(imagebase%filealignment)
müsste das sein
10/07/2011 15:42 yihaaa#6
Kann mir noch wer weiterhelfen?

MfG