开发者

how to build an executable without import table in c/c++?

开发者 https://www.devze.com 2023-01-19 14:33 出处:网络
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++?Just don\'t use CRT, and don\'t use any imported functions

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


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);
}


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消