Quantcast
Channel: New Topics
Viewing all articles
Browse latest Browse all 4617

Add a new PE section & Code insede of it

$
0
0

Hi to you all! It has been a while since i posted something interesting,and i feel like i have to contribute more to this forum.

I've seen some people here,and on some other forums that pretend to understand the PE file format,and that they know how to corrupt one.
Alot of code out there that is useless,that is buggy or makes the infected PE unstable or simply just crashes it!

This is met to be an introduction to PE corruption,ofcourse for those interested!

The program im going to show you is reading a file,tests if it is a valid PE and eventualy inserts a new PE section.With PE infection in my mind, i insert some string into the newly created section,just to make an example of this situation!

Here it is,improve and do whatever you like with it!
ENJOY!!!

 

#include <stdio.h>
#include <windows.h>

DWORD align(DWORD size, DWORD align, DWORD addr){
	if (!(size % align))
		return addr + size;
	return addr + (size / align + 1) * align;
}

bool AddSection(char *filepath, char *sectionName, DWORD sizeOfSection){
	HANDLE file = CreateFile(filepath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (file == INVALID_HANDLE_VALUE) 
		return false;
	DWORD fileSize = GetFileSize(file, NULL);
	//so we know how much buffer to allocate
	BYTE *pByte = new BYTE[fileSize];
	DWORD dw;
	//lets read the entire file,so we can use the PE information
	ReadFile(file, pByte, fileSize, &dw, NULL);

	PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)pByte;
	if (dos->e_magic != IMAGE_DOS_SIGNATURE)
		return false; //invalid PE
	PIMAGE_FILE_HEADER FH = (PIMAGE_FILE_HEADER)(pByte + dos->e_lfanew + sizeof(DWORD));
	PIMAGE_OPTIONAL_HEADER OH = (PIMAGE_OPTIONAL_HEADER)(pByte + dos->e_lfanew + sizeof(DWORD)+sizeof(IMAGE_FILE_HEADER));
	PIMAGE_SECTION_HEADER SH = (PIMAGE_SECTION_HEADER)(pByte + dos->e_lfanew + sizeof(IMAGE_NT_HEADERS));

	ZeroMemory(&SH[FH->NumberOfSections], sizeof(IMAGE_SECTION_HEADER));
	CopyMemory(&SH[FH->NumberOfSections].Name, sectionName, 8); 
	//We use 8 bytes for section name,cause it is the maximum allowed section name size

	//lets insert all the required information about our new PE section
	SH[FH->NumberOfSections].Misc.VirtualSize = align(sizeOfSection, OH->SectionAlignment, 0);
	SH[FH->NumberOfSections].VirtualAddress = align(SH[FH->NumberOfSections - 1].Misc.VirtualSize, OH->SectionAlignment, SH[FH->NumberOfSections - 1].VirtualAddress);
	SH[FH->NumberOfSections].SizeOfRawData = align(sizeOfSection, OH->FileAlignment, 0);
	SH[FH->NumberOfSections].PointerToRawData = align(SH[FH->NumberOfSections - 1].SizeOfRawData, OH->FileAlignment, SH[FH->NumberOfSections - 1].PointerToRawData);
	SH[FH->NumberOfSections].Characteristics = 0xE00000E0;
	/*
		0xE00000E0 = IMAGE_SCN_MEM_WRITE |
					 IMAGE_SCN_CNT_CODE  |
					 IMAGE_SCN_CNT_UNINITIALIZED_DATA  |
					 IMAGE_SCN_MEM_EXECUTE |
					 IMAGE_SCN_CNT_INITIALIZED_DATA |
					 IMAGE_SCN_MEM_READ 
	*/
	SetFilePointer(file, SH[FH->NumberOfSections].PointerToRawData + SH[FH->NumberOfSections].SizeOfRawData, NULL, FILE_BEGIN);
	//end the file right here,on the last section + it's own size
	SetEndOfFile(file);
	//now lets change the size of the image,to correspond to our modifications
	//by adding a new section,the image size is bigger now
	OH->SizeOfImage = SH[FH->NumberOfSections].VirtualAddress + SH[FH->NumberOfSections].Misc.VirtualSize;
	//and we added a new section,so we change the NOS too
	FH->NumberOfSections += 1;
	SetFilePointer(file, 0, NULL, FILE_BEGIN);
	//and finaly,we add all the modifications to the file
	WriteFile(file, pByte, fileSize, &dw, NULL);
	CloseHandle(file);
	return true;
}

bool AddCode(char *filepath){
	HANDLE file = CreateFile(filepath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (file == INVALID_HANDLE_VALUE) 
		return false;
	DWORD filesize = GetFileSize(file, NULL);
	BYTE *pByte = new BYTE[filesize];
	DWORD dw;
	ReadFile(file, pByte, filesize, &dw, NULL);
	PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)pByte;
	PIMAGE_NT_HEADERS nt = (PIMAGE_NT_HEADERS)(pByte + dos->e_lfanew);

	//since we added a new section,it must be the last section added,cause of the code inside
	//AddSection function,thus we must get to the last section to insert our secret data :)
	PIMAGE_SECTION_HEADER first = IMAGE_FIRST_SECTION(nt);
	PIMAGE_SECTION_HEADER last = first + (nt->FileHeader.NumberOfSections - 1);

	SetFilePointer(file, last->PointerToRawData, NULL, FILE_BEGIN);
	char *str = "ATHENIAN WAS HERE";
	WriteFile(file, str, strlen(str), &dw, 0);
	CloseHandle(file);
	return TRUE;
}

void main()
{
	if (AddSection("C:\\Users\\M\\Desktop\\Athena.exe", ".ATH", 400)){
		printf("Section added!\n");
		//Lets insert data into the last section
		if (AddCode("C:\\Users\\M\\Desktop\\Athena.exe")){
			printf("Code written!\n");
		}
		else
			printf("Error writting code!\n");
	}
	else
		printf("Error adding section!\n");
}

To verify if the section is added,and the string inside of it,i recomand using PE Explorer!

Here are some screenshots:

 

Attached Thumbnails

  • before.png
  • after.png
  • secret.png

Viewing all articles
Browse latest Browse all 4617

Latest Images

Trending Articles



Latest Images