5

I found a tool to repair import table here, but how are PE executable without import table built in the first place in c/c++?

2 Answers 2

8

Just don't use CRT, and don't use any imported functions.

#pragma comment(linker, "/entry:start")
int start()
{
   return 42; 
}

To use WinAPI functions, find kernel32 base, parse it's export directory and find LoadLibrary() function (you should already have something like GetProcAddress() to find LoadLibrary())

This may looks like this:

// compile as console application, "release" configuration with /MT /GS-
#include <Windows.h>
#pragma comment(linker, "/entry:start")
void start()
{
    HMODULE kernel32base = *(HMODULE*)(*(DWORD*)(*(DWORD*)(*(DWORD*)(*(DWORD*)(__readfsdword(0x30) + 0x0C) + 0x14))) + 0x10);

    DWORD base = (DWORD)kernel32base;
    IMAGE_NT_HEADERS* pe = PIMAGE_NT_HEADERS(base + PIMAGE_DOS_HEADER(base)->e_lfanew);
    IMAGE_EXPORT_DIRECTORY* exportDir = PIMAGE_EXPORT_DIRECTORY(base + pe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
    DWORD* namePtr = (DWORD*)(base + exportDir->AddressOfNames);
    WORD* ordPtr = (WORD*)(base + exportDir->AddressOfNameOrdinals);
    for(; strcmp((const char*)(base + *namePtr), "GetProcAddress"); ++namePtr, ++ordPtr)
        ;
    DWORD funcRVA = *(DWORD*)(base + exportDir->AddressOfFunctions + *ordPtr * 4);

    typedef FARPROC (WINAPI *GetProcAddress_t)(HMODULE, const char*);
    GetProcAddress_t GetProcAddress = (GetProcAddress_t)(base + funcRVA);

    HANDLE (WINAPI *GetStdHandle)(DWORD);
    *(FARPROC*)&GetStdHandle = GetProcAddress(kernel32base, "GetStdHandle");

    HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE);

    BOOL (WINAPI *WriteFile)(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED);
    *(FARPROC*)&WriteFile = GetProcAddress(kernel32base, "WriteFile");

    const char* greeting = "Hello world!\n";

    DWORD written;
    WriteFile(stdout, greeting, strlen(greeting), &written, NULL);
}
Sign up to request clarification or add additional context in comments.

7 Comments

Can you provide a hello world example in its entirety?
@ollydbg It' rather complete for MSVC. Compile it as "release" with /MT /GS- and it won't have any imports.
You managed to create an executable without import table that can run without problem,don't you?What I was expecting was one that will report a run time error due to lack of import table.
@ollydbg: "managed"? I just wrote it. And I know that it works because I know how it works, why it works and I tested it. Did you expect that it don't work? First test it, and find out why it works or don't works, if you don't understand it. Use google, there is answers to all your questions.
It's probably easier to use interrupts to write a "hello world" program without any imports
|
0

To strip imports from existing executable module, you should parse it's imports directory to get its imports, then generate and add a code to get those imports, then remove imports directory.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.