Code shows the example how to use external modules on-the-fly WITHOUT imports table.
The code does the following steps:
- Finds out the KERNEL32.DLL base (see versions below),
- finds out export table at KERNEL32.DLL module space (kernel32!ExportTable),
- finds out the entry point of GetProcAddress in kernel32!ExportTable directly (in memory),
- calls GetProcAddress to get entry point of LoadLibraryA routine,
- calls LoadLibraryA and GetProcAddress to import desired module and symbols.
- 1536 bytes,
- 2 sections (code and data),
- NO imports table and other data directories,
- uses THREAD ENVIRONMENT BLOCK (TEB) to get KERNEL32.DLL base,
- reads entry point of GetAddressProc() directly from KERNEL32 exports,
- then calls it to get entry of LoadLibraryA() routine.
- 1536 bytes,
- 2 sections (code and data),
- NO imports table and other data directories,
- uses RETURN ADDRESS to get KERNEL32.DLL base,
- reads entry point of GetAddressProc() directly from KERNEL32 exports,
- then calls it to get entry of LoadLibraryA() routine.
- 268 bytes,
- no sections,
- NO imports table and other data directories,
- SIZE-OPTIMIZED to fits within 268 bytes,
- uses RETURN ADDRESS to get KERNEL32.DLL base,
- reads entry point of GetAddressProc() directly from KERNEL32 exports,
- then calls it to get entry of LoadLibraryA() routine.
- We assume that entry point in our application is called directly by KERNEL32.DLL,
- so the return address on app start-up should points somwhere in-the-middle of KERNEL32.DLL module,
- we scan memory pointed by return address backward until we found something, which looks like the PE header.
- GS register points to the Thread Environment Block (TEB) on x86-64 Windows (https://en.wikipedia.org/wiki/Win32_Thread_Information_Block),
- We search TEB.PEB.LoaderData.Modules for 'kernel32.dll' entry.
- Code works on x86-64 only (PE32+),
- Minimal version is size-optimized to fit wihin 268 bytes, due to this, literals are stored in the unused PE parts, which are not neccesery to run a program, but some disassemblers or debuggers may fail to load the file.
Based on codes samples from: