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
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);
}
7 Comments
ollydbg
Can you provide a hello world example in its entirety?
Abyx
@ollydbg It' rather complete for MSVC. Compile it as "release" with /MT /GS- and it won't have any imports.
ollydbg
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.
Abyx
@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
|