3

我想解析来自 C stdlib 的函数的地址,例如malloc在运行时从 .NET 代码(这样我就可以为我的 VM 调用这些地址的 JIT 机器代码)。我相信我应该使用LoadLibraryGetProcAddress提供 kernel32.dll 但这不起作用。使用 F# 交互式我得到:

> [<DllImport("kernel32.dll", CharSet=CharSet.Ansi, SetLastError=true)>]
  extern IntPtr LoadLibrary(string fileName);;
val LoadLibrary : string -> IntPtr

> [<DllImport("kernel32.dll", CharSet=CharSet.Ansi, SetLastError=true)>]
  extern uint32 GetProcAddress(IntPtr hModule, string fn);;
val GetProcAddress : IntPtr * string -> uint32

> let kernel32 = LoadLibrary @"kernel32.dll";;
val kernel32 : IntPtr = 1993146368n

> let malloc = GetProcAddress(kernel32, "malloc");;
val malloc : uint32 = 0u

所以这似乎已经获得了 DLL 的句柄,但试图解析malloc却返回了一个 NULL 指针。

我该怎么做?

4

3 回答 3

3

AFAIKmalloc不是kernel32.dll. 它是 MS C 运行时 DLL 的一部分 - 因为您没有提供有关如何/在何处使用它的任何详细信息,只是一些包含相关信息的链接:

基本上,您必须加载相应的 DLL,然后解析所需的函数,例如:

let SomeMSCRT = LoadLibrary @"SomeMSCRT.dll";;
let malloc = GetProcAddress(SomeMSCRT, "malloc");;

一个注意事项:

根据您到底想做什么,您可能会遇到严重且难以调试的问题 - 例如,使用mallocF# 恕我直言是个坏主意......您需要记住 C 运行时需要正确初始化(如果是 MS您需要首先调用 CRT CRT_INIT)等。C 运行时不知道任何 .NET 细节,因此可能导致不稳定的行为......尤其是。因为 CLR 可能在内部使用 CRT(可能是不同的版本)......

还有一点:

在运行时生成机器代码并通过跳转到该内存区域来执行它需要采取多种安全措施(取决于 Windows 版本等)。您可能需要将相应的内存段标记为“可执行”,这无法通过 C 运行时实现,只能使用具有适当权限的 Windows API 调用(如)...参见此处此处VirtualAllocEx的起点。

于 2012-03-29T18:04:22.747 回答
3

我不相信mallockernel32.dll. 但是,如果我没记错的话,所有malloc实现最终都会深入到HeapAlloc,它在kernel32.dll.

于 2012-03-29T18:06:20.003 回答
2

我想解析C stdlib中的函数的地址

有你的问题。你说的好像只有一个 C 运行时库。事实上有很多。每个编译器都提供了自己的,有几种不同的风格(调试、发布、静态链接、动态链接),所有这些都是相互不兼容的。

如果您知道要使用哪一个,那么您的问题的答案将变得显而易见。

如果您希望在所有 Windows 应用程序之间共享操作系统提供的库,那么kernel32.dll是正确的查看位置,但这些函数符合 Win32 API 规范,而不是 ANSI 或 ISO C 标准。

于 2012-03-29T18:13:34.560 回答