【问题标题】:Load Windows executable at a different base address at runtime?在运行时在不同的基地址加载 Windows 可执行文件?
【发布时间】:2020-04-11 03:46:29
【问题描述】:

是否可以在运行时将 Windows 可执行文件加载到不同的基地址。我不是说用/BASE 编译它。它已经编译为在默认基地址0x400000 加载。我想看看当剥离了重定位信息的 PE 加载到与其请求的基地址不同的基地址时的行为。我有限的研究(谷歌的前 2 页)并不表明这是可能的,但我希望有人可以提供可能的黑客攻击。

【问题讨论】:

  • “我想看看当剥离了重定位信息的 PE 被加载到不同于它请求的基地址时的行为” - 很简单:程序将崩溃 因为它的指针不会被重定位,并且某处的某些代码会尝试取消引用它预期被重定位的指针(可能是一些 Win32 函数调用包含在 pre-main 可执行代码中)。
  • 我推荐阅读这篇文章,尤其是“2.2:处理二进制固定地址”部分:blog.sevagas.com/PE-injection-explained
  • already happens,除非您更改了默认链接器设置。 /DYNAMICBASE 选项。

标签: windows portable-executable


【解决方案1】:

我假设您想要的代码可以放置在内存中的任何位置,并且无论您是否只是显式地跳转到它,或者它是否像任何其他文件一样作为可执行映像加载,它仍然可以工作。它不会依赖于“首选”基地址或 .relocation 部分中的数据(如果存在的话)。此代码将不依赖于可执行映像的任何其他部分(例如 IAT、.data 部分或任何各种标头),但它始终是特定于平台的(即 Windows),并且可能特定于某些版本的 Windows取决于它的编写方式,但是可以实现与 Windows 无关的代码。

您只需要以不依赖于硬编码地址或相对图像库的硬编码偏移量的方式编写您的代码。这与用于在安全漏洞中控制程序的代码类型相同。

此代码几乎总是需要使用显式汇编语言指令,包括入口点代码本身。例如。您不能以 Main、WinMain、DllMain 或类似名称开头来使用 C 运行时的启动代码。使用自定义 C 宏和内联汇编可以使这个过程变得不那么复杂,但是您仍然需要对底层汇编指令有一个大致的了解。

您的函数和数据指针必须相对于入口点代码中的某个位置手动构建,而不是使用硬编码指针或相对“图像”基地址来引用函数和数据。这比听起来要容易,并且可以像相对 CALL 一样简单,然后是 POP 指令来获取您的“基”地址(X86 架构)。然后,您的数据可以在代码字节中混合,根据需要跳过它,指针的构建与函数的相对指针没有什么不同。

通过使用与位置无关的指令并在运行时发现入口点的位置,理论上您可以将生成的 PE 图像和 JMP 的 .text 部分放入入口点,即使生成的 EXE 也可以正常运行。只是希望自己做很多肮脏的工作,直到您可以动态解析 Windows API 地址。这可能不适合胆小的人,但它非常直截了当。这一研究领域将使您深入了解 Windows 的幕后工作原理,并且您将成为更好的程序员。

互联网上有大量有关此主题的信息。搜索“shellcode”和有关如何编写打包程序/解包程序的教程。调用 windows API 只是意味着您需要编写自己的引导代码来在运行时解析这些地址;打包机和解包机做同样的事情。

描述此过程的推荐书籍,尤其是导入地址解析:Shellcoder's Programming Uncovered (Kaspersky)、Shellcoder's Handbook (Anley) 和 The Rootkit Arsenal (Blunden);后者涉及到一点 C 宏来管理复杂性方面。一些细节在下面的文章中讨论,Locating KERNEL32 in ASLR memory

祝你好运!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 2019-03-09
    • 1970-01-01
    相关资源
    最近更新 更多