Is it possible to call functions from C#, to an unmanaged function in a struct (via VTable).
For example, I am in-process hooking an application, and I am re-creating the structs for each class (of the application).
public struct SomeStruct {
[FieldOffset(0x00)]
public IntPtr * VTable;
[FieldOffset(0x10)]
public uint SomeValue;
}
Then, I usually do:
var * data = (SomeStruct*)(Address);
And I wish to call a function from the VTable of the structure in either of the following ways
Invoke<delegate>(data->VTable[0x3C])(delegateArguments)
Or
var eax = Invoke<Func<uint,uint>(data->VTable[0x3C])(arg1,arg2)
Furthermore, could this be done efficiently (as these vtable funcs could be called numerous times)?
Perhaps via Reflection Emit?
From what I know, marshalling has to create the delegate function every time I call the Invoke<>
func.
Given that a virtual method table contains pointers to functions, assuming you know the offset (which it appears you do) you can get the pointer value in an IntPtr
by calling the ReadIntPtr
method on the Marshal class, like so:
IntPtr ptr = Marshal.ReadIntPtr(data.VTable, 0x3C);
Then you can call the GetDelegateForFunctionPointer
method on the Marshal
class to get a delegate of the appropriate type, like so:
// Assuming a signature of f(int, int) returning int
Func<int, int, int> func = (Func<int, int, int>)
Marshal.GetDelegateForFunctionPointer(ptr, typeof(Func<int, int, int>));
Then you can call the delegate as needed.
Well, I have found a possible solution:
I have created a generic Invoke method that creates and caches all delegates for future use Also
public void Select(uint target)
{
fixed (void* pThis = &this)
{
Generic.Invoke<Action<uint, uint>>(this.VTable[0xC0], CallingConvention.ThisCall)
((uint)pThis, target);
}
}
[FieldOffset(0x00)]
public uint* VTable;
Caches:
public static T Invoke<T>(uint addr, CallingConvention conv) where T : class
{
var type = typeof(T);
if (!cache.Contains(type))
cache.Set<T>(type, NativeHelper.GetDelegateForFunctionPointer<T>(addr, conv));
return cache.Get<T>(type);
}
And the function that creates the function (and works for generic Func/Action)
public static T GetDelegateForFunctionPointer<T>(uint ptr, CallingConvention conv)
where T : class
{
var delegateType = typeof(T);
var method = delegateType.GetMethod("Invoke");
var returnType = method.ReturnType;
var paramTypes =
method
.GetParameters()
.Select((x) => x.ParameterType)
.ToArray();
var invoke = new DynamicMethod("Invoke", returnType, paramTypes, typeof(Delegate));
var il = invoke.GetILGenerator();
for (int i = 0; i < paramTypes.Length; i++)
il.Emit(OpCodes.Ldarg, i);
il.Emit(OpCodes.Ldc_I4, ptr);
il.EmitCalli(OpCodes.Calli, conv, returnType, paramTypes);
il.Emit(OpCodes.Ret);
return invoke.CreateDelegate(delegateType) as T;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With