tags:

views:

41

answers:

2

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++?

+1  A: 

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);
}
Abyx
Of course it's how to build from source method.
Abyx
Can you provide a hello world example in its entirety?
ollydbg
@ollydbg It' rather complete for MSVC. Compile it as "release" with /MT /GS- and it won't have any imports.
Abyx
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
@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.
Abyx
@Abyx, yes I was expecting it don't work.
ollydbg
A: 

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.

Abyx