This is the ninth part of the .NET Inside Out series. For your convenience you can find other parts in the table of contents in Part 1 – Virtual and non-virtual calls in C#
We know how to generate delegate from a byte array. Last time we did it by modifying some code using jumps here and there. Today we are going to use GetDelegateForFunctionPointer method.
Most important difference is in method generating the delegate:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// Returns delegate of type T using class U for stubbing public static T Generate< T>(byte[] data) { // Address of machine code in array // We omit first 8 bytes (array type and size) var arrayCodeAddress = ((int)Pin(data)) + 8; // Unlock page so we can execute code from it UnlockPage(arrayCodeAddress); Console.WriteLine("Machine code in array address: " + arrayCodeAddress.ToString("X")); return (T)(object)Marshal.GetDelegateForFunctionPointer< T>((IntPtr)arrayCodeAddress); } |
Instead of modifying the machine code we just generate the pointer using .NET methods. We have our delegate but this doesn’t support generics, so we need the following:
1 2 |
delegate void ActionInt(int x); delegate int FunctionInt(int x); |
This is just for type safety so we can pass correct parameters.
Our first test method looks like this:
1 2 3 4 5 6 7 |
public static void MyWriteLine(int a, int b, int text) { // Type is ByteToFunc.ActionInt because we are jumping around in the code! Console.WriteLine("I'm in the MyWriteLine"); Console.WriteLine(text); Console.WriteLine(); } |
You can see that we use dummy parameters just to adhere to the calling convention but generally this works correctly. Also notice, that the method is static, that’s because we don’t pass any instance.
Second test looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
static void FuncTest() { FunctionInt function = FuncGenerator.Generate<FunctionInt>( new byte[]{ // Accessing variables on the stack directly instead via base pointer since we are too lazy to generate method frame 0x8B, 0x44, 0x24, 0x04, // mov eax, DWORD PTR [esp + 0x4] 0x83, 0xC0, 0x04, // add eax, 4 0xc3 // retn } ); // Should print 23 + 4 == 27 Console.WriteLine(function(23)); } |
Last time we were accessing parameters through registers, this time they are passed via stack because there are additional delegate parameters which we don’t need. We also don’t build the method frame so we use esp
register.
And we are done. Tested with .NET Framework 4.5 and Windows 10 x64 Enterprise compiled as AnyCPU and executed as x86.