3

I want to resolve the addresses of functions like those from the C stdlib such as malloc at run-time from .NET code (so I can JIT machine code that calls to these addresses for my VM). I believe I should use LoadLibrary and GetProcAddress supplying the kernel32.dll but this does not work. Using F# interactive I get:

> [<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

So this appears to have obtained a handle to the DLL but trying to resolve malloc has returned a NULL pointer.

How should I do this?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
J D
  • 48,105
  • 13
  • 171
  • 274

3 Answers3

3

AFAIK mallocis NOT part of kernel32.dll. It is part of the MS C runtime DLLs - since you don't provide any details about how/where you want to use this just some links with relevant information:

Basically you have to load the respective DLL and then resolve the needed function, as an example:

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

One note though:

Depending on what exactly you want to do you might run into serious and hard to debug problems - for example using malloc from F# is IMHO a bad idea... you need to keep in mind that the C runtime needs proper initialization (in case of MS CRT you need to call CRT_INIT as the very first thing) etc. The C runtime is NOT aware of any .NET specifics and thus may lead to unstable behaviour... esp. since the CLR might be using the CRT (perhaps a different version) internally...

Another point:

Generating machine code at runtime and executing it by jumping into that memory area is subject to several security measures (depending on Windows version etc.). You might need to mark the respective memory segment as "executable" which is NOT possible via C runtime, it is only possible using Windows API calls (like VirtualAllocEx) with proper permissions... see for a starting point here and here.

ildjarn
  • 62,044
  • 9
  • 127
  • 211
Yahia
  • 69,653
  • 9
  • 115
  • 144
  • UAC has no effect whatsoever. JIT compilers such as JVMs and CLR work just fine running as unprivileged users. – Ben Voigt Mar 29 '12 at 18:14
  • @BenVoigt are you sure about that? I've run .Net code as a non-admin user and I do have problems accessing certain resources – Onorio Catenacci Mar 30 '12 at 01:58
  • @OnorioCatenacci: That's not a failure of the JIT compiler to generate executable code into memory. I'm not talking about your code, the protected APIs it calls, or the whole library. The JIT compiler works fine. – Ben Voigt Mar 30 '12 at 04:07
  • I had no idea I had to choose which C run-time to use, thanks. The rest of my JIT compiler is working fine (arithmetic and logical operators, `if` expressions and function calls all from 170 lines of compiler written in F#) thanks to the help I got on this other Stack Overflow question of mine: http://stackoverflow.com/questions/9557293/is-it-possible-to-write-a-jit-compiler-to-native-code-entirely-in-a-managed-n – J D Mar 30 '12 at 08:42
3

I don't believe malloc is part of kernel32.dll. However, if I recall correctly, all malloc implementations eventually drill down to HeapAlloc, which is available in kernel32.dll.

ahawker
  • 3,306
  • 24
  • 23
2

I want to resolve the addresses of functions like those from the C stdlib

There's your problem. You speak as if there's a single C runtime library. In fact there are many. Every compiler provides its own, in several different flavors (debug, release, static link, dynamic link) and all of these are mutually incompatible.

If you knew which one you were trying to use, the answer to your question would become obvious.

If you want the OS-provided libraries shared between all Windows applications, then kernel32.dll is the correct place to look, but the functions conform to the Win32 API specification, not the ANSI or ISO C standard.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720