微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

是否可以在 C# 中获取方法地址?

如何解决是否可以在 C# 中获取方法地址?

我想获取方法地址以便稍后在我的自定义作弊保护中使用它(我想检查方法是否被挂钩)。我目前正在尝试使用 typeof(MyClass).getmethod("MyMethod").MethodHandle.GetFunctionPointer(); 但这并没有给我正确的偏移量。对不起,如果我的问题看起来很愚蠢,但我认为这是做我需要的唯一方法。谢谢。

UPD:我正在将我的偏移量与 Cheat Engine 的偏移量进行比较。我知道地址总是不同的

UPD 2:我想读取我自己的应用程序的内存,所以我可以检查它是否被更改(我只对非常重要的方法这样做)

解决方法

您有一个 X/Y problem,由于您对 CLR 和托管代码在 Windows 台式计算机中的执行方式缺乏了解而恶化。我会详细说明。

我要获取方法地址

未通过 AOT 编译为本机代码的计算机程序,例如用 C#/.NET、Java 和 JavaScript 编写的程序,不会将其函数/方法位于内存中的单个位置.

这是因为:

  • 函数可以通过解释器执行,通常称为字节码解释器或类似的。发生这种情况时,根本没有函数的本机代码表示。
  • 当一个函数最终被 JIT 编译时,它可以存在于内存中的多个位置,因为 JIT 编译器可能会根据运行时行为多次重新编译一个函数(例如,JIT 可以重新编译一个函数并删除所有的 if( x == null ) 检查是否在遵循热门路径时意识到它们是不必要的。
  • 当使用 monomorphicreified 泛型系统(在 .NET 中使用,而不是在 Java 中使用)时,如果存在任何泛型函数(包括泛型类型的非泛型成员) ) 对于泛型类型参数参数的每个不同组合,这些函数将在内存中实例化
    • 这是因为编译后的 List<String>.Add(String s) 方法不能用于 List<FileInfo> 更不用说 List<Int32>(请记住,.NET 不使用类型擦除)。

简而言之:C# 方法没有单一地址。

稍后在我的自定义作弊保护中使用它

如果这对你来说是一个学习练习,那么继续 - 忽略仇恨者和他们的口号:“不要推出你自己的加密货币”、“构建完美的 DRM 系统在数学上是不可能的”和“构建您自己的作弊保护只是在欺骗自己”:执行傻瓜差事可能是了解为什么这是傻瓜差事的最佳方式 - 不要在生产中使用它 所以您不会让其他用户处于危险之中。

我想检查方法是否被钩住

我想你误解了钩子的工作原理。 “钩子”是 Win32 特有的(因为它是 Win32 的一个设计特性),但你不能“钩子”软件中的任意方法/函数。

我目前正在尝试使用 typeof(MyClass).GetMethod("MyMethod").MethodHandle.GetFunctionPointer(); 获取指针,但这并没有给我正确的偏移量。

您应该阅读文档

The documentation for MethodHandle says(强调我的):

获取方法的内部元数据表示的句柄。

The documentation for GetFunctionPointer says(强调我的):

返回的 IntPtr 用于内部运行时使用,不应用于从本机代码调用函数。使用 Marshal.GetFunctionPointerForDelegate 以获得可以传递给本机代码的函数指针。

一般来说,如果有“内部”字样,您可能不应该使用它。

我知道 MethodHandleGetFunctionPointerForDelegate 的文档确实表明它返回 C 风格的函数指针,但就您而言,文档是不正确的。

(实际上,如果您在 GetFunctionPointerForDelegate 上调用 MethodInfo 以获得开放式泛型方法,您将得到一个 InvalidProgramException!- 这根本没有记录,呃)。

UPD:我正在将我的偏移量与 Cheat Engine 的偏移量进行比较。我知道地址总是不同的

由于我已经讨论过的原因,Cheat Engine 不适用于非本地程序。

如果您在 Cheat Engine 的论坛上搜索“.NET”或“Java”,您会发现数百篇来自与您遇到相同问题的人的帖子。

UPD 2:我想读取我自己的应用程序的内存,所以我可以检查它是否被更改(我只对非常重要的方法这样做)

由于上述原因,您不能对任何非确定性 JIT 编译的软件执行此操作。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。