【问题标题】:WinAPI functions in new .exe新 .exe 中的 WinAPI 函数
【发布时间】:2010-11-01 22:52:38
【问题描述】:

我最近一直在研究创建一种新的母语。我了解 PE 格式的(非常)基础知识,并且我已经从网上获取了一个具有相当友好接口的汇编程序,我已经成功地使用它来实现一些简单的功能。但是我在使用库中的函数时遇到了问题。我之前从动态编译的函数中调用库函数的唯一方法是手动传入函数指针——如果我创建 PE 文件并在它们自己的进程中执行它们,这是我无法做到的。现在,我不打算使用 CRT,但我需要访问 Win API 来实现我自己的标准库。如何生成对 WinAPI 函数的引用,以便 PE 加载程序对其进行修补?

【问题讨论】:

  • 是否也在使用链接器verboten
  • @Hans:我将使用链接器。

标签: winapi assembly portable-executable


【解决方案1】:

您需要编写一个导入表。它基本上是您希望在应用程序中使用的函数名称列表。它由 PE 标头指向。加载器为您将 DLL 文件加载到进程内存空间中,在它们的导出表中找到请求的函数,并将其地址留在导入表中。然后你通常会取消引用它并在那里jmp

查看 Izelion's assembly tutorial 了解完整详情和 asm 示例。

【讨论】:

  • 所以,基本上,我为指针留出空间,然后通过 PE 加载器和格式完成其余的魔法。
  • 是的,只有指针必须是特定结构的一部分。
  • 对于调用常规函数指针,我还需要执行这个技巧吗?还有- call 和 jmp 有什么区别?
  • 你有你自己的函数的地址,所以你不需要这个技巧。它只是为了获取可能在加载的 DLL 中移动或随它移动的导入/WinAPI 函数的地址。至于 jmp/call,使用 call 因为它确保函数有一个上下文可以返回。
【解决方案2】:

从发出 C 而不是汇编开始怎么样?那么直接写入 ASM 只是一种优化。

我不是在开玩笑:大多数编译器会在最终的本机代码通过之前生成某种中间代码。

我意识到您正试图摆脱所有以空分隔的繁琐,但无论如何您都需要 WinAPI 函数。

重新阅读您的问题:您确实意识到可以通过调用 LoadLibrary(),然后调用 GetProcAddress(),然后设置调用来获取 WinAPI 函数地址...对吗?

如果您想了解如何从纯汇编引导它:旧的 SDK 有 ASM 示例代码,可能新的 SDK 仍然有。如果他们不这样做,DDK 会。

【讨论】:

  • 我知道。我不发出 C 的一半原因是因为我不想被绑定到 CRT、const char* 字符串和#include 等。另一个原因是因为我只有一个即时汇编程序。现在,我绝对会生成一个 AST 和一个中间代码等,但我想确保我的系统作为一个整体能够正常工作,然后我才开始实施这一切。可行性研究,如果你愿意的话。
  • LoadLibrary 是 WinAPI 的一部分。如果不访问 WinAPI,我将如何使用它?
  • 它在 KERNEL 中,它从一开始就自动映射到您的进程中。如果不是,那么您或系统将如何加载任何其他库,包括 KERNEL?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多