使用非托管 C++ .dll 从 C# .exe 调用函数

Posted

技术标签:

【中文标题】使用非托管 C++ .dll 从 C# .exe 调用函数【英文标题】:Call a function from C# .exe with unmanaged C++ .dll 【发布时间】:2011-05-23 20:16:17 【问题描述】:

所以,我有一个用 C# 制作的可执行文件,我没有它的源代码,但我用 IDA 反汇编了它,它给了我很多面向对象的程序集。

我已经创建了一个 .exe 文件,它将一个 .dll 注入另一个 .exe,我已经将这个新的 C++ DLL 注入到 C# .exe 中,没有问题,调用了 DLLMain 等等...

但是当我将这个 DLL 注入到一个用 C++ 制作的普通 .exe 文件中时,我可以调用 .exe 中的一个函数,它的内存地址可以在 IDA 上使用。

问题是,面向对象的程序集在其函数中没有地址,即使函数名被反汇编。

那么,有什么方法可以用我在 C# .exe 文件上注入的 DLL 调用这个函数?

如果可能,有没有办法可以使用在 C# .exe 文件中声明的命名空间及其所有函数和变量,甚至是私有的?

反汇编代码示例:

.namespace MyCSharpApp

.class public auto ansi Test extends [mscorlib]System.Object

  .field public value class [Microsoft.Xna.Framework]Microsoft.Xna.Framework.Vector2 pos

  .field public int32 foo
....

【问题讨论】:

即使可以获取地址也没有多大意义——代码是 MSIL,而不是本地代码。需要启动 CLR(我不知道这会如何发生)。 @pst:由于应用程序是 .NET,因此 CLR 将启动并运行。但是,要调用的特定函数可能尚未经过 JIT 处理,因此您的担忧是有效的。 【参考方案1】:

您正在尝试做一些棘手的事情,我不太清楚它是什么。根据您的描述,您至少有四件事:

托管 EXE 托管 DLL 非托管 EXE 非托管 DLL

您可以控制其中的一些(即源代码),而有些则不能。

您想使用您称为“注入”的过程来更改您可以控制的模块,从而调用您可以控制的模块。为此,您使用的工具要求您在进程的地址空间中有一个非托管入口点。

如果您想通过非托管模块获得所需的功能,那么您需要做的就是编写一个新的混合模式模块(显然您可以控制它)来调用您无法控制的托管 DLL。现在您有效地拥有了一个非托管 DLL(用于导出目的),并且它被托管的问题已经消失了。

要从新的非托管包装模块调用托管代码,您可以使用这篇介绍性文章中描述的技术:

An Overview of Managed/Unmanaged Code Interoperability

基本上,您需要一个 C++/CLI 项目,该项目引用您的黑盒托管 DLL 并调用它并导出一个非托管入口点,您可以为注入“获取地址”。搜索会发现更多想法。

最后,您能否使用此方法在托管 DLL(您无法控制)中调用 private 方法?不,不是直接的。但是,它是一个托管 DLL,因此它必须有 一些 public 入口点才能对任何人有用,您可以调用它们。如果这还不够,您可以使用 C++/CLI 中的反射来调用私有方法并访问私有成员。

【讨论】:

【参考方案2】:

您需要使用非托管托管/调试 API。如果您可以注入托管 DLL,这会容易得多,您只需使用反射即可。

【讨论】:

我尝试注入一个托管 DLL,它编译得很好,但是,我无法在 DllMain 上启动我的线程,因为它在运行时给我一个错误:"Attempt to use MSIL code from this assembly during native code initialization"(甚至虽然我在初始化时没有使用 MSIL 代码),但我必须使用 DllMain,因为目标 .exe 不会调用我的 DLL 中的任何方法,这意味着在 .exe 完全加载之前我无法执行任何操作。 @Flavio:将 DllMain 放入一个没有/clr 编译的文件中,并将所有内容链接在一起。

以上是关于使用非托管 C++ .dll 从 C# .exe 调用函数的主要内容,如果未能解决你的问题,请参考以下文章

从 C++ 非托管 dll 传递 C# 函数

从 C# 调用 C++ dll。 “无法封送'返回值':托管/非托管类型组合无效。”

使用 C# 访问非托管 C++ DLL 时出现 AccessViolationException

C# Windows 窗体无法在 Windows10 上加载非托管 C++ DLL

从非托管 C++ mfc active x dll 启动 C# 对话框

如何从 C# 导入和使用非托管 C++ 类?