Skip to content

F# Metaprogramming part 1: JIT Some Native Code on the Fly

March 4, 2012

Comes out doing this is not hard at all! The snippet below is taken from my answer on StackOverflow that, in turn, is F# translation of C#-expressed approach:

open System
open System.Runtime.InteropServices

type AllocationType =
    | COMMIT=0x1000u
    | RESERVE=0x2000u
    | RESET=0x80000u
    | LARGE_PAGES=0x20000000u
    | PHYSICAL=0x400000u
    | TOP_DOWN=0x100000u
    | WRITE_WATCH=0x200000u

type MemoryProtection =
    | EXECUTE=0x10u
    | EXECUTE_READ=0x20u
    | NOACCESS=0x01u
    | READONLY=0x02u
    | READWRITE=0x04u
    | WRITECOPY=0x08u
    | GUARD_Modifierflag=0x100u
    | NOCACHE_Modifierflag = 0x200u
    | WRITECOMBINE_Modifierflag = 0x400u

type FreeType =
    | DECOMMIT = 0x4000u
    | RELEASE = 0x8000u

[<DllImport("kernel32.dll", SetLastError=true)>]
extern IntPtr VirtualAlloc(IntPtr lpAddress, UIntPtr dwSize, AllocationType flAllocationType, MemoryProtection flProtect);

[<DllImport("kernel32.dll", SetLastError=true)>]
extern bool VirtualFree(IntPtr lpAddress, UIntPtr dwSize, FreeType freeType);

let JITcode: byte[] = [|
                            0x55uy;                 // PUSH EBP
                            0x8Buy;0xECuy;          // MOV EBP,ESP
                            0x8Buy;0x45uy;0x08uy;   // MOV EAX,[EBP + 8]
                            0xD1uy;0xC8uy;          // ROR EAX,1
                            0x5Duy;                 // POP EBP
                            0xC3uy                  // RET

type Ret1ArgDelegate = delegate of (uint32) -> uint32

let main (args: string[]) =
    let executableMemory = VirtualAlloc(IntPtr.Zero, UIntPtr(uint32(JITcode.Length)), AllocationType.COMMIT, MemoryProtection.EXECUTE_READWRITE)
    Marshal.Copy(JITcode, 0, executableMemory, JITcode.Length)
    let jitedFunc = Marshal.GetDelegateForFunctionPointer(executableMemory, typeof<Ret1ArgDelegate>) :?> Ret1ArgDelegate
    let mutable test = 0xFFFFFFFCu
    printfn "Value before: %X" test
    test <- jitedFunc.Invoke test
    printfn "Value after: %X" test
    VirtualFree(executableMemory, UIntPtr.Zero, FreeType.DECOMMIT) |> ignore

Being built apparently for x86 architecture to align with to-be-injected native code it happily executes yielding

Value before: FFFFFFFC
Value after: 7FFFFFFE

I’m looking at the stuff above with a certain unease as I, while being in a managed .NET environment, just brought in and executed a piece of completely alien native code Oc8


From → F#

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: