我需要创建一个没有导入表的exe程序
iam使用C ++我不使用任何API甚至loadlibrary和getprocaddress我在运行时获取句柄
当我使用visual studio 2013构建应用程序时[也尝试过visual studio 6]
生成的exe有很多来自kernel32.dll的导入
地址序号库
------- ------- ---- -------
0040E000 MultiByteToWideChar KERNEL32
0040E004 RtlUnwind KERNEL32
0040E008 HeapAlloc KERNEL32
<00> 0040E00C ExitProcess KERNEL320040E010 TerminateProcess KERNEL32
0040E014 GetCurrentProcess KERNEL32
0040E018 GetCommandLineA KERNEL32
<00> 0040E01C GetVersion KERNEL320040E020 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
我使用调试和发布选项都给出了同样的问题 我使用多线程MD同样的问题
任何想法
感谢您提前的时间 [注意:我的代码包含一些内联汇编]
=============================================== ===================
减少问题的大小。我在链接器选项i上配置了入口点,指向main
这有助于将导入表减少到以下
地址序号库
------- ------- ---- -------
00406000 HeapAlloc KERNEL32
00406004 ExitProcess KERNEL32
00406008 TerminateProcess KERNEL32
0040600C GetCurrentProcess KERNEL32
00406010 HeapFree KERNEL32
00406014 VirtualAlloc KERNEL32
00406018 HeapReAlloc KERNEL32
=============================================== ================
减少更多
1st - 取消选中链接器选项中的include默认库
2nd - 将MSVCRT.LIB添加到链接器命令
现在导入表是
地址序号库
------- ------- ---- -------
00405000 malloc MSVCRT
00405004退出MSVCRT
00405008 rand MSVCRT
答案 0 :(得分:2)
您在IAT中看到kernel32.dll的所有这些条目,因为visual c ++运行时代码直接调用所有这些函数。例如:
#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
...
}
另请注意,即使您与kernel32.lib链接并且不直接调用其任何函数(毕竟这是导入库的目的),您的二进制文件甚至不会包含{{1}对于kernel32.dll,所以在这种情况下,与kernel32.lib的链接绝对没有效果。
使用以下代码创建控制台应用程序:
IMAGE_IMPORT_DESCRIPTOR
要创建没有导入的exe文件,请按照以下步骤操作:
这将告诉编译器不要发出对安全检查函数的调用,因此链接器不必解析它们。
编译您的程序。在PE资源管理器中检查它以确保它没有导入(int my_entry_point()
{
return 0;
}
为0)。
请注意,您的程序与kernel32.lib和系统dll的其他导入库链接(请参阅链接器 - &gt;输入 - &gt;其他依赖项)。但是它没有任何效果,因为您不使用CRT并且不在您自己的代码中调用所有这些函数。
有趣的是,您不需要导入DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress
。当ExitProcess
函数返回时,Windows将立即从ntdll.dll调用RtlExitUserThread
。此调用指令不使用IAT或任何其他重定向,调用将直接引导我们my_entry_point
函数。
答案 1 :(得分:1)
实际上,如果没有导入地址表(IAT),则无法拥有Windows可执行文件(众所周知的Win PE)。但是,当然,从技术上讲,可能有一个空IAT的可执行文件,这样的可执行文件没有用,或者很难编码和维护。
众所周知,计算机程序被定义为至少有一个输出,因此存在某种类型的库依赖。这个库依赖关系足以填充IAT。只使用函数printf()的C ++程序将导致在IAT中有少量条目。
正如您所列,正常的可执行文件将在IAT中包含大量条目。有人做加密来保护可执行文件。他们将使用一种称为IAT Mangling的技术。它们将大大减少IAT中存在的条目。
实际上,至少,导入表应包含“Kernel32.dll”的模块条目,该条目应包含“LoadLibrary”和“GetProcAddress”API的子部分。了解Windows Loader如何加载并开始执行可执行文件将有助于理解IAT所扮演的关键角色。
每当Loader加载一个可执行文件时,它将检查IAT的完整性。任何不匹配(例如缺少DLL,函数签名不匹配)都将取消可执行文件的执行。
Matt Pietrek撰写了一系列有关Win PE的学术文章。它清楚地解释了IAT所起的作用。您可以从here阅读。
顺便说一句,如果您的目标是缩小可执行文件的大小,请查看有关吸脂工具的this文章。