【问题标题】:Getting Ptr Value of a Function获取函数的 Ptr 值
【发布时间】:2013-07-31 15:22:31
【问题描述】:

我的应用程序中有一个 API 函数:

    <Runtime.InteropServices.DllImport("kernel32.dll", SetLastError:=True, CharSet:=Runtime.InteropServices.CharSet.Ansi, ExactSpelling:=True)>
    Private Shared Function GetProcAddress(ByVal hModule As IntPtr, ByVal procName As String) As IntPtr
    End Function

我只是想了解这个函数的指针'IntPtr'值。我该怎么做?

注意:我将在 C++ 中向您展示我想要的确切内容

void* fnGetProcAddress;
fnGetProcAddress = GetProcAddress;

【问题讨论】:

  • 您是否要查找 Win32 调用 GetProcAddress 的位置? (也就是说,这是一个 p/invoke 签名吗?) 编辑:哈 - 通过编辑,我可以看到这是一个 pinvoke 调用 - 现在你到底需要什么?
  • 这个问题是否可能与“什么是 IntPtr?”重复?题?你在开玩笑吗?
  • 我想获取这个地址并将其作为 UInt32 写入 BinaryStream。

标签: c# .net vb.net


【解决方案1】:

好吧,你可以继续使用 P/Invoke...

(注意,这是在 C# 中,但很容易转换)

[System.Runtime.InteropServices.DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

[System.Runtime.InteropServices.DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(string moduleName);


var hModule = GetModuleHandle("kernel32.dll");
var procAddress = GetProcAddress(hModule, "GetProcAddress");

【讨论】:

  • 我正在尝试。谢谢你的回答:)
  • @MuhammedUğurNazlı 很高兴它正在工作,但请查看下面 Hans 的回答,因为它提出了一些非常好的观点!
【解决方案2】:

我想获取此地址并将其作为 UInt32 写入 BinaryStream

这是一个非常麻烦的计划。除了错误的数据类型之外,您没有保证您写入的地址在您读取流时仍然有效:

  • 当您读取流时,可能根本就没有加载 DLL。它确实需要调用 LoadLibrary() 才能在此过程中获取它。因此,您至少还必须序列化 DLL 路径。

  • DLL 确实承诺再次加载到完全相同的地址。嵌入在 DLL 标头中的加载地址只是一个请求,很常见的是请求的地址已被另一个 DLL 使用,从而迫使 Windows 重新定位该 DLL。重新定位的地址是不可预测的。一个更大的问题是在现代 Windows 版本上有意进行重定位。一个称为地址空间布局随机化的功能,当 DLL 与 /DYNAMICBASE 链接器选项链接时启用。这是一项反恶意软件功能,故意让恶意软件难以修补代码。

当然有更好的方法来做你想做的事。但是你犯了一个常见的错误,就是不解释你的原因,这是不可能猜到的。

【讨论】:

  • @MuhammedUğurNazlı 汉斯在这里提出的所有观点都是绝对正确的;虽然我上面所说的应该......“有点工作”,但推荐
  • 其实我是在将c++代码翻译成VB.NET。 C++ 代码运行良好。所以如果c++中也存在这个问题,那也没关系。
  • 这在 C++ 中也是错误的。那是你到目前为止很幸运并不构成证据。特别是考虑到托管程序的 VM 布局截然不同。以及启用了 ASLR 的托管程序。
猜你喜欢
  • 1970-01-01
  • 2021-06-06
  • 2015-05-29
  • 2020-11-09
  • 2016-01-01
  • 2021-05-30
  • 2011-12-16
  • 1970-01-01
  • 2018-09-02
相关资源
最近更新 更多