我有一个加载的 DLL 的开始地址,如何发现和调用其导出?



我正在编写一个在进程中运行的加载项。我能够可靠地发现该进程中已加载的 DLL 的内存地址。偏移处的内存清楚地显示"MZ"DOS接头和"PE"接头。后来,似乎有导出函数的名称等。这就像一个加载的DLL一样走路和说话。

所以,现在,我想更多地了解DLL是什么,更有趣的是,我可以用它做什么

我过去使用过 PE 实用程序,但它们始终使用基于文件的 DLL。除了在十六进制编辑器中检查进程之外,如何列出内存中 DLL 的导出函数?有没有办法发现当前加载的基于文件的DLL?(我不太熟悉我认为加载 dll 时发生的链接。

如果我有导出函数的名称,是否只是尝试调用这些函数并猜测它们的参数和返回值?或者是否有一些更强大的逆向工程可以执行?

给定 DLL 的起始地址和函数名称,我将如何在 C# 中进行调用?

这里实际上有很多问题(有些问题非常广泛)。我会尝试为一些提供答案。

  • 要获取当前进程中加载的模块 (.dll) 的句柄,请使用 [MSDN]:GetModuleHandleEx 函数,无论其名称或地址是否已知(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS标志)

  • 若要获取包含已加载.dll代码的文件名,请使用 [MSDN]:GetModuleFileName 函数。此时,您将能够使用您提到的 PE 实用程序(Dependency Walker 或 [MSDN]:Sysinternals Suite 可能非常有用)

显然,从.dll获取函数签名并不是一项简单的任务(有时这是不可能的)。这里有 3 个网址,但谷歌会在这个主题上产生大量结果:

  • [MSDN]:如何获取 C++ dll 的元数据(带有参数和返回类型的签名)
  • [SO]:是否有任何本机 DLL 导出函数查看器?
  • [SO]:获取 DLL 中导出函数的签名

但是.dll附带一个或多个文件,其中包含(除其他外)函数/类声明。缺少标头意味着:

  • .dll符号仅用于内部目的(而不是"手动")
  • 它们是私有的(例如受许可证保护),在这种情况下,对它们进行逆向工程就不是很合乎道德了。

无论如何,考虑到您以某种方式获取函数名称和签名,您可以通过 [MSDN]:GetProcAddress 函数加载函数,然后调用它们。

.NET(C#) 执行所有操作(同样,需要函数名称和签名)只会增加额外的复杂性,因为 C#代码在托管环境中运行,而C/C++ 在本机环境中运行,并且在 2 个环境之间交换数据时,需要对其进行封送/取消编组([MSDN]:C++中的送处理概述)。
以下是 3 个 URL,但同样,互联网上充满了信息:

  • [MSDN]:从托管代码调用本机函数
  • [SO]:是否可以从 C#.Net 调用 C 函数
  • [SO]:从 C# 调用 C DLL

最新更新