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

前端 未结 2 1082
无人共我
无人共我 2021-01-14 02:43

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条回答
  •  北恋
    北恋 (楼主)
    2021-01-14 03:30

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

提交回复
热议问题