1

我的应用程序中有一个 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;
4

2 回答 2

2

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

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

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

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

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

于 2013-07-31T15:57:35.593 回答
2

好吧,您可以继续使用 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");
于 2013-07-31T15:41:59.247 回答