-1

I'm having some strange errors with the following function which adds a section to a pe executable. When I run the program I get the success message, when I proceed to try to open the executable in ollydbg I get an invalid file error, I then open it in LordPE and find that the section has been added and everything seems to be in order, when I again open the executable in ollydbg it opens the executable and I can see that the section has been added though all the fields aside from section name are set to 0. I have tried this many times and get the same result with different executables.

void addSection(char* fileName)
{
HANDLE hFile = CreateFile(fileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile !=INVALID_HANDLE_VALUE){
    DWORD fileSize = GetFileSize(hFile, NULL);
    BYTE *byte = new BYTE[fileSize];
    DWORD numberOfBytesReadTracker;
    ReadFile(hFile, byte, fileSize, &numberOfBytesReadTracker, NULL);

    IMAGE_DOS_HEADER *dosHeader = (IMAGE_DOS_HEADER*)byte;
    IMAGE_NT_HEADERS *ntHeader = (IMAGE_NT_HEADERS*)((DWORD)byte+dosHeader->e_lfanew);
    if(dosHeader->e_magic==IMAGE_DOS_SIGNATURE && ntHeader->Signature == IMAGE_NT_SIGNATURE){
        IMAGE_FILE_HEADER *fileHeader = (IMAGE_FILE_HEADER*)((DWORD)byte+dosHeader->e_lfanew+sizeof(IMAGE_NT_SIGNATURE));
        IMAGE_OPTIONAL_HEADER *optionalHeader = (IMAGE_OPTIONAL_HEADER*)((DWORD)byte+dosHeader->e_lfanew+sizeof(IMAGE_NT_SIGNATURE)+sizeof(IMAGE_FILE_HEADER));
        IMAGE_SECTION_HEADER *sectionHeader = (IMAGE_SECTION_HEADER*)((DWORD)ntHeader+sizeof(IMAGE_NT_HEADERS));

        const char *sectionName = "AddedSec";
        ZeroMemory(&sectionHeader[fileHeader->NumberOfSections], sizeof(IMAGE_SECTION_HEADER));
        CopyMemory(&sectionHeader[fileHeader->NumberOfSections].Name, sectionName, 8);
        sectionHeader[fileHeader->NumberOfSections].Characteristics = 0x60500060;
        sectionHeader[fileHeader->NumberOfSections].Misc.VirtualSize = 0x1000;
        sectionHeader[fileHeader->NumberOfSections].VirtualAddress = sectionHeader[fileHeader->NumberOfSections-1].VirtualAddress+optionalHeader->SectionAlignment;
        sectionHeader[fileHeader->NumberOfSections].SizeOfRawData = optionalHeader->FileAlignment;
        sectionHeader[fileHeader->NumberOfSections].PointerToRawData = sectionHeader[fileHeader->NumberOfSections-1].PointerToRawData+sectionHeader[fileHeader->NumberOfSections-1].SizeOfRawData;

        fileHeader->NumberOfSections = fileHeader->NumberOfSections+1;
        optionalHeader->SizeOfImage = optionalHeader->SizeOfImage+alignToSectionAlignment(sectionHeader[fileHeader->NumberOfSections].Misc.VirtualSize, optionalHeader->SectionAlignment);
        cout << "ADDED SECTION" << endl;
        SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
        WriteFile(hFile, byte, fileSize, &numberOfBytesReadTracker, NULL);
    }else{
        cout << "Is not a PE executbale" << endl;
    }
    CloseHandle(hFile);
}

}

2 Answers 2

3
IMAGE_SECTION_HEADER *sectionHeader = (IMAGE_SECTION_HEADER*)((DWORD)ntHeader+sizeof(IMAGE_NT_HEADERS));

The line above is incorrect. It should be:

IMAGE_SECTION_HEADER *sectionHeader = (IMAGE_SECTION_HEADER*)((DWORD)ntHeader+sizeof(IMAGE_NT_SIGNATURE)+sizeof(IMAGE_FILE_HEADER)+fileHeader->SizeOfOptionalHeader);

You're setting the IMAGE_SCN_ALIGN_16BYTES flag in Characteristics, though this is only valid for object files.

sectionHeader[fileHeader->NumberOfSections].VirtualAddress = sectionHeader[fileHeader->NumberOfSections-1].VirtualAddress+optionalHeader->SectionAlignment;

The line above will cause problems if the last section in the original PE file has a virtual size greater than the section alignment.

sectionHeader[fileHeader->NumberOfSections].PointerToRawData = sectionHeader[fileHeader->NumberOfSections-1].PointerToRawData+sectionHeader[fileHeader->NumberOfSections-1].SizeOfRawData;

The line above will cause problems if the last section in the original PE file has a raw size that is not a multiple of the file alignment.

fileHeader->NumberOfSections = fileHeader->NumberOfSections+1;

The line above will cause problems if the original PE file had 65535 sections.

optionalHeader->SizeOfImage = optionalHeader->SizeOfImage+alignToSectionAlignment(sectionHeader[fileHeader->NumberOfSections].Misc.VirtualSize, optionalHeader->SectionAlignment);

The line above should be:

optionalHeader->SizeOfImage = optionalHeader->SizeOfImage+alignToSectionAlignment(sectionHeader[fileHeader->NumberOfSections-1].Misc.VirtualSize, optionalHeader->SectionAlignment);

Your code assumes that there's space between the last IMAGE_SECTION_HEADER and the beginning of the first section to add another IMAGE_SECTION_HEADER; this isn't always the case.

Also, it's very likely that the new section's PointerToRawData + SizeOfRawData is greater than the size of the file, which will cause the loader to fail.

In the future, please post these types of programming questions to https://stackoverflow.com/ instead.

0

Consider using TitanEngine (https://bitbucket.org/mrexodia/titanengine-update)

and its function AddNewSection or AddNewSectionEx.

Or have a look how its implemented there https://bitbucket.org/mrexodia/titanengine-update/src/50379e53e9f3a1d9cf835e37e2fd7cbade61dc6a/TitanEngine/TitanEngine.PE.Section.cpp?at=master#cl-512

Not the answer you're looking for? Browse other questions tagged or ask your own question.