I need to make an exe program that has no import table
iam using C++ i don't use any API even loadlibrary and getprocaddress i get handles to them in runtime
still when i build the application using visual studio 2013 [also tried visual studio 6]
the resulting exe has many imports from kernel32.dll
Address Ordinal Name Library
------- ------- ---- -------
0040E000 MultiByteToWideChar KERNEL32
0040E004 RtlUnwind KERNEL32
0040E008 HeapAlloc KERNEL32
0040E00C ExitProcess KERNEL32
0040E010 TerminateProcess KERNEL32
0040E014 GetCurrentProcess KERNEL32
0040E018 GetCommandLineA KERNEL32
0040E01C GetVersion KERNEL32
0040E020 RaiseException KERNEL32
0040E024 HeapFree KERNEL32
0040E028 HeapReAlloc KERNEL32
0040E02C HeapSize KERNEL32
0040E030 HeapDestroy KERNEL32
0040E034 HeapCreate KERNEL32
0040E038 VirtualFree KERNEL32
0040E03C VirtualAlloc KERNEL32
0040E040 IsBadWritePtr KERNEL32
0040E044 SetHandleCount KERNEL32
0040E048 GetStdHandle KERNEL32
0040E04C GetFileType KERNEL32
0040E050 GetStartupInfoA KERNEL32
0040E054 UnhandledExceptionFilter KERNEL32
0040E058 GetModuleFileNameA KERNEL32
0040E05C FreeEnvironmentStringsA KERNEL32
0040E060 FreeEnvironmentStringsW KERNEL32
0040E064 WideCharToMultiByte KERNEL32
0040E068 GetEnvironmentStrings KERNEL32
0040E06C GetEnvironmentStringsW KERNEL32
0040E070 WriteFile KERNEL32
0040E074 GetLastError KERNEL32
0040E078 SetFilePointer KERNEL32
0040E07C FlushFileBuffers KERNEL32
0040E080 CloseHandle KERNEL32
0040E084 SetUnhandledExceptionFilter KERNEL32
0040E088 IsBadReadPtr KERNEL32
0040E08C IsBadCodePtr KERNEL32
0040E090 GetCPInfo KERNEL32
0040E094 GetACP KERNEL32
0040E098 GetOEMCP KERNEL32
0040E09C GetProcAddress KERNEL32
0040E0A0 LoadLibraryA KERNEL32
0040E0A4 ReadFile KERNEL32
0040E0A8 SetStdHandle KERNEL32
0040E0AC LCMapStringA KERNEL32
0040E0B0 LCMapStringW KERNEL32
0040E0B4 GetStringTypeA KERNEL32
0040E0B8 GetStringTypeW KERNEL32
0040E0BC ReadConsoleInputA KERNEL32
0040E0C0 SetConsoleMode KERNEL32
0040E0C4 GetConsoleMode KERNEL32
0040E0C8 CreateFileA KERNEL32
i used debug and release option both give the same problem i used multithreaded MD same problem
any ideas
Thanks for your time in advance [Note: my code include some inline assembly]
==================================================================
to reduce the size of the problem. I configured the entry point on the linker option i pointed to main
this helped to reduce the import table to the following
Address Ordinal Name Library
------- ------- ---- -------
00406000 HeapAlloc KERNEL32
00406004 ExitProcess KERNEL32
00406008 TerminateProcess KERNEL32
0040600C GetCurrentProcess KERNEL32
00406010 HeapFree KERNEL32
00406014 VirtualAlloc KERNEL32
00406018 HeapReAlloc KERNEL32
===============================================================
reduced even more
1st - uncheck the include default libraries in linker options
2nd - add MSVCRT.LIB to the linker command
now the import table is
Address Ordinal Name Library
------- ------- ---- -------
00405000 malloc MSVCRT
00405004 exit MSVCRT
00405008 rand MSVCRT
You see all these entries in IAT for kernel32.dll because visual c++ runtime code calls all these functions directly. For example:
#include <Windows.h>    // include prototypes
// note that we need to link with kernel32.dll import library 
// (kernel32.lib) to call its functions directly;
// { Project Properties -> Configuration Properties -> Linker -> Input ->
// Additional dependencies } will contain "kernel32.lib" in the list
int main(int argc, char* argv[]);
int mainCRTStartup()
{
    GetCommandLine(...);   // direct call, so linker will create entry in IAT for kernel32.dll
    ...
    main(argc, argv);      // your main function that linker will search for
    ...
}
Also note that even if you link with kernel32.lib and don't call any of its functions directly (that's the purpose of import library after all) your binary will not even contain IMAGE_IMPORT_DESCRIPTOR for kernel32.dll, so linking with kernel32.lib has absolutely no effect in this case.
Create console application with this code:
int my_entry_point()
{
    return 0;
}
To create exe file with no imports follow these steps:
This will tell compiler not to emit calls to security check functions, so linker will not have to resolve them.
Compile your program. Examine it in PE Explorer to make sure it has no imports (DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress is 0).
Note that your program links with kernel32.lib and other import libraries for system dlls (see Linker -> Input -> Additional dependencies). However it has no effect since you don't use CRT and don't call all these functions in your own code.
The interesting thing is that you don't need to import ExitProcess. Windows will immediately call RtlExitUserThread from ntdll.dll when my_entry_point function returns. This call instruction does not use IAT or any other redirection, it is call that will lead us directly to RtlExitUserThread function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With