Search code examples
c++cportable-executable

Adding a section to a PE file, change Entry Point to the new section and execute any code


I am working on a PE file packer and I can succesfully encrypt the .text section of an executable, change its entry point and add a new section. The newly added section will take care of decrypting the .text section and then jump to the original entry point.

Now, I would like to go a little bit further and execute more code in the new section. I can do pretty much everything I want, but if I call an external function (cout from iostream for example), the modified executable will crash while attempting to execute an illegal instruction. The disassembly of the stub in the new section looks like this :

.newsec:0042C020                 push    ebp
.newsec:0042C021                 mov     ebp, esp
.newsec:0042C023                 push    offset loc_40EB50
.newsec:0042C028                 mov     eax, ds:dword_40E0B0
.newsec:0042C02D                 push    eax
.newsec:0042C02E                 call    loc_41A350
.newsec:0042C033                 add     esp, 8
.newsec:0042C036                 pop     ebp
.newsec:0042C037                 retn

The line at address 0x42c033 will jump in the .text section but the code there is unrelated to what std::cout should do.

To help you help me, the code added in the new section is in a file stub.h/cpp :

#pragma comment(linker, "/OPT:NOREF")
#pragma optimize( "", off )
#pragma section(".stub",read,write,execute)

__declspec(code_seg(".stub"))
void hello_test()
{
    std::cout << "hello world";
}

__declspec(code_seg(".stub"))
void default_stub_start(void) {
    __asm {
        call hello_test

        mov eax, 0x400000 //oep
        jmp eax
    }
}

Then, the entire .stub section will be copied as is in the new section that I added to the executable. The compilation runs smoothly but the modified executable will crash, as I explained above. If I remove the line

std::cout << "hello world";

and replace it with some basic maths, it works fine.

My question is : how can I use external functions without breaking the executable ?


Solution

  • I forgot this question but actually found the solution months after having asked it. The problem here is that one must manually link to external functions, because their addresses are not known at run-time once the code is unpacked into memory.

    To do this, one should do the following:

    • Walk the Process Environment Block to iterate on the linked list of loaded libraries.
    • Locate the library kernel32.dll and walk its export table, for instance to get the addresses of GetProcAddress and LoadLibrary.
    • Use the API resolved before to load and resolve any other API.

    For more information, the Chapter 10 of "The Rootkit Arsenal" is a must-read.