Skip to content

Instantly share code, notes, and snippets.

@TinkerWorX
Created May 23, 2012 23:02
Show Gist options
  • Save TinkerWorX/2778387 to your computer and use it in GitHub Desktop.
Save TinkerWorX/2778387 to your computer and use it in GitHub Desktop.
...
private static void BindNative(IntPtr functionPtr, String name, String prototype)
{
// Manual implementation of __fastcall.
// Moves the two first arguments to the registers, and pushes the rest on the stack.
var code = new byte[32];
var stream = new MemoryStream(code);
var writer = new BinaryWriter(stream);
var codePtr = Kernel32.VirtualAlloc(IntPtr.Zero, code.Length, AllocationType.Commit, MemoryProtection.ExecuteReadWrite);
var namePtr = Marshal.StringToHGlobalAnsi(name);
var prototypePtr = Marshal.StringToHGlobalAnsi(prototype);
// (68) push, prototype string pointer
writer.Write((Byte)0x68);
writer.Write((UInt32)prototypePtr);
// (BA) mov edx, name string pointer
writer.Write((Byte)0xBA);
writer.Write((UInt32)namePtr);
// (B9) mov ecx, function pointer
writer.Write((Byte)0xB9);
writer.Write((UInt32)functionPtr);
// (E8) call, BindNative relative offset
writer.Write((Byte)0xE8);
writer.Write((UInt32)((Int32)Addresses.BindNative - (Int32)codePtr - (Int32)writer.BaseStream.Position - 4));
// (C3) retn
writer.Write((Byte)0xC3);
Marshal.Copy(code, 0, codePtr, code.Length);
((EmptyBindNativePrototype)Marshal.GetDelegateForFunctionPointer(codePtr, typeof(EmptyBindNativePrototype)))();
Kernel32.VirtualFree(codePtr, code.Length, 0x8000);
}
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment