在阅读“我可以静态链接(而非导入)Windows系统DLL的答案”的答案时?我想到了另一个问题。因此:


是否可以编写没有依赖性的程序(也没有静态编译的程序-它只有我的代码),并且在运行时所有问题都可以通过假设kernel32.dll来解决。会被加载/映射到进程中吗?
我对kernel32.dll的假设是否正确?

在运行时,我的意思是使用PEB结构。

评论

请记住,关于kernel32.dll的规则仅适用于NT平台。并不是说我希望有人仍然使用9x / Me,但以防万一;)

#1 楼

如果您询问的是PE文件,而“无依赖性”则表示“无静态导入的DLL”,那么请回答。以BinaryCorpus_v2.zip为例。

评论


谢谢,这是一个非常有趣的解决方案,他确实假设堆栈已将返回地址返回到kernel32空间中的某个位置(他在这里进行了探讨),并且从那里开始的方式是“直截了当”的:)

– PhoeniX
13年5月25日在6:45

如今,解析kernel32.dll基址的最常见方法是遍历InMemoryOrderModuleList列表,因为即使在Windows 7中DLL的顺序也没有改变。如果您有导出表,则因为可以使用对感兴趣的DLL的转发引用,并且您自己的导出上的GetProcAddress()会导致Windows为您加载DLL。

–彼得·弗里
13年5月25日在15:52

#2 楼

这不是一个非常可移植的技巧,但是当可执行文件启动时,kernel32.dll总是加载在同一地址,这意味着LoadLibraryA和GetProcAddress始终在同一地址。您可以对这些偏移量进行硬编码,然后从那里开始。

评论


那么,如果PE映像在代码中的任何地方都未引用kernel32.dll,它将始终加载到processes事件中吗?

– PhoeniX
13年5月25日在6:25

@ ph0sec是的,Windows加载程序也总是在kernel32.dll中加载,并且始终在同一地址。

– Avery3R
13年5月25日在6:47

@MMavipc有关同一地址的情况并不总是与Vista和Win 7系列中的情况一样正确,因此引入了ASLR来阻止这种假设。

– PhoeniX
13年5月25日在6:53



@MMavipc该行为是Windows XP中引入的,它可以避免当未从kernel32.dll导入进程时出现崩溃问题,因此未明确加载该进程。@ ph0sec也不完全正确-ASLR仅适用于第一次该kernel32.dll(和ntdll.dll也)已加载。之后,它在所有进程中都位于一个公共地址。

–彼得·弗里
13年5月25日在15:41



@peter ferrie原因,因为它仅加载一次并在此之后映射到其他进程。我在这里指的是,您不能(不应)将kernel32.dll基地址硬编码到可执行文件本身中。

– PhoeniX
13年5月25日在17:04



#3 楼

是的,没有依赖性的程序是可能的。

要导入APi,首先需要找到kernel32(通过stack + MZ扫描或PEB),然后找到导出(通过导出解析或硬编码值)。

#4 楼

是。


使用任何已知的技巧(PEB或任何其他方式)查找kernel32的地址。
实现一个简单的导出节解析器,并找到LoadLibraryGetProcAddress的地址。
使用它们来加载所需的任何其他API。