_CorExeMain
或RHBinder__ShimExeMain
。最后,即使是打包文件,它们也不会具有主模块的导入功能,仍将具有启动和解压缩文件所需的导入。 .exe PE文件是否可能具有绝对零导入但仍在计算机上运行并执行任何有用的功能?为其功能出口。我说的是一个独立的.exe文件。#1 楼
尽管blabb的答案显示的是没有任何导入的可执行文件,但我假设OP在问的是功能更强大的可执行文件,而不是该级别的理论练习。我可以想到四种合理的类型,可能没有任何导入的可用可执行文件类型:
不需要任何OS API的可执行文件。
这有点类似于布拉布的答案,但想出一个更现实的例子。提供一个执行某种复杂计算的可执行文件可能是一个示例。仍然,这似乎不是OP所寻找的可执行文件。操作系统具有不同的默认库,但这并非总是可能的,但是在Windows上,例如,始终将
ntdll.dll
和kernel32.dll
加载到进程中,还可能加载其他库,具体取决于PE文件标志。其中一些甚至在大多数PE文件格式(特别是导入目录)被处理之前由内核完成,其他库由加载程序自动加载或由其他库依赖项加载。可执行文件可以使用那些可用的API,而无需进行任何导入,但是将需要一些额外的工作来手动解析API。 可执行文件根据默认加载的库解析其自身的导入。
使用前面提到的库中的可用API,可执行文件可以实现自己的API搜索甚至没有实际导入所需API的库加载代码。这就是某些包装工的工作。具体来说,那些在Windows上实现自己的
GetProcAddr
功能或使用GetProcAddr
和LoadLibrary
来动态加载带有空导入表的API的可执行文件。直接执行系统调用以使用OS服务的可执行文件。br />
这种可能性是最复杂,最脆弱的,因为直接实施syscall很难,并且可能会在操作系统更新之间更改而没有事先警告。基本上,大多数API都以一条syscall指令结尾,该指令将控制权转移到内核,所请求的操作实际上是由内核执行的。只要需要OS服务,可执行文件就可以直接发出这些文件。
评论
我看不出2和3之间的区别。(尽管我通常同意您的意见并投了赞成票。)
– conio
17年6月27日在2:20
我拆分了“仅使用可用的API”和“加载其他库”。自然地,这些差异中的大多数几乎是相似的,只是略有不同。感谢您的支持:)
– NirIzr
17-6-27在2:24
#2 楼
void main (void)
{
__asm
{
retn
}
}
使用
编译和链接
cl /nologo /W4 /Ox /analyze noimpo.cpp /link /DEBUG:NONE /RELEASE /ENTRY:main /INCREMENTAL:NO /FIXED /SUBSYSTEM:windows /ALIGN:128 /DRIVER
将创建有效的PE文件
**编辑**
// win 7 sp1 32 bit machine and ewdk 1703 cl.exe
unsigned long long time = 0xdeadbeefdeadbeef;
__declspec(naked) void main (void)
{
__asm
{
push OFFSET time
call ntqst
retn
}
ntqst:
__asm
{
mov eax,107h
mov edx , 7ffe0300h
call dword ptr ds:[edx]
retn 4
}
}
在调试器下运行以查看它是否确实有帮助
评论
我感谢您的答复,并且该知识很有用,但是,我认为您错过了这句话的一部分:“。exe PE文件是否有可能绝对为零导入,但仍然可以在计算机上运行并执行任何有用的功能? ” “任何有用的东西。”
–the_endian
17年6月26日在23:16
如果您认为查询系统时间有用,请在编辑中输入
– blabb
17年6月27日在9:31
#3 楼
是的,可以,但可能取决于您要在其上运行的操作系统。亚历山大·索蒂洛夫(Alexander Sotirov)在TinyPE页面上发表的内容:不幸的是,该97字节的PE文件在Windows 2000上不起作用。但是
KERNEL32.DLL未加载。 Windows的所有其他版本会自动加载它,但在Windows 2000上,我们必须确保可执行文件的导入表中列出了KERNEL32.DLL。不可能导入。
因此,如果您使用XP或更高版本,则可以依靠kernel32内存并使用其功能。我怀疑(但没有检查)即使在Windows 2000上,
ntdll.dll
也是由内核映射的,因此您也许可以使用它来完成有用的工作(例如,LdrLoadDll
加载其他DLL,LdrGetProcedureAddress
解析功能)。 >
评论
我仍然不清楚-您是说一个程序根本不使用任何导入函数吗?没有API,您甚至无法在屏幕上打印。然后,这成为如何定义“有用”的问题。另外,所有Crinkler打包文件都具有一个空的导入表,但是通过解析内存结构以找到加载程序,然后在运行时解析导入,可以做很多令人惊奇的事情。是的,程序可以轻松地从PEB查找“ kernel32.dll”的基址。然后遍历PE标头并导出目录,并动态查找函数地址。