public static void TestNativeCallableValid() { /* * void TestNativeCallable() * { * .locals init ([0] native int ptr) * IL_0000: nop * IL_0002: ldftn int32 CallbackMethod(native int,native int) * * IL_0012: stloc.0 * IL_0013: ldloc.0 * IL_0014: ldsfld native int [mscorlib]System.IntPtr::Zero * IL_0019: call bool NativeMethods::EnumWindows(native int, * native int) * IL_001e: pop * IL_001f: ret * } */ DynamicMethod testNativeCallable = new DynamicMethod("TestNativeCallable", null, null, typeof(Program).Module); ILGenerator il = testNativeCallable.GetILGenerator(); il.DeclareLocal(typeof(IntPtr)); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ldftn, typeof(Program).GetMethod("CallbackMethod")); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldsfld, typeof(IntPtr).GetField("Zero")); il.Emit(OpCodes.Call, typeof(NativeMethods).GetMethod("EnumWindows")); il.Emit(OpCodes.Pop); il.Emit(OpCodes.Ret); NativeMethodInvoker testNativeMethod = (NativeMethodInvoker)testNativeCallable.CreateDelegate(typeof(NativeMethodInvoker)); testNativeMethod(); }
/// <summary> /// Call native method & process any exception /// </summary> /// <param name="nativeClient"></param> /// <param name="serviceCode"></param> /// <param name="opCode"></param> /// <param name="argObject"></param> /// <returns></returns> public NativeMethodTransportObject InvokeNativeMethod( INativeSession nativeClient, int serviceCodeInt, int opCodeInt, NativeMethodTransportObject transportObject) { NativeMethodInvokerInstance = new NativeMethodInvoker(); NativeMethodTransportObject resultObject = NativeMethodInvokerInstance.InvokeNativeMethod( nativeClient, serviceCodeInt, opCodeInt, transportObject); return(resultObject); }
/// <summary> /// Call a service method and return result /// </summary> /// <param name="serviceCode"></param> /// <param name="subServiceCode"></param> /// <param name="parameters"></param> /// <returns></returns> public NativeMethodTransportObject CallServiceMethod( ServiceCodes serviceCode, object subServiceCode, object parameters) { INativeSession nativeClient = CreateNativeSessionProxy(); NativeMethodInvokerInstance = new NativeMethodInvoker(); Services.Native.NativeMethodTransportObject resultObject = NativeMethodInvokerInstance.InvokeNativeMethod( nativeClient, (int)serviceCode, (int)subServiceCode, new NativeMethodTransportObject(parameters)); ((IClientChannel)nativeClient).Close(); return(resultObject); }
public static void NegativeTest_ViaCalli() { Console.WriteLine($"{nameof(NegativeTest_ViaCalli)} function via calli instruction. The CLR _will_ crash."); /* * void TestUnmanagedCallersOnlyViaCalli() * { * .locals init (native int V_0) * IL_0000: nop * IL_0001: ldftn void CallbackViaCalli(int32) * IL_0007: stloc.0 * * IL_0008: ldc.i4 1234 * IL_000d: ldloc.0 * IL_000e: calli void(int32) * * IL_0013: nop * IL_0014: ret * } */ DynamicMethod testUnmanagedCallersOnly = new DynamicMethod("TestUnmanagedCallersOnlyViaCalli", null, null, typeof(Program).Module); ILGenerator il = testUnmanagedCallersOnly.GetILGenerator(); il.DeclareLocal(typeof(IntPtr)); il.Emit(OpCodes.Nop); // Get native function pointer of the callback il.Emit(OpCodes.Ldftn, typeof(Program).GetMethod(nameof(CallbackViaCalli))); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Ldc_I4, 1234); il.Emit(OpCodes.Ldloc_0); il.EmitCalli(OpCodes.Calli, CallingConventions.Standard, null, new Type[] { typeof(int) }, null); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ret); NativeMethodInvoker testNativeMethod = (NativeMethodInvoker)testUnmanagedCallersOnly.CreateDelegate(typeof(NativeMethodInvoker)); // It is not possible to catch the resulting ExecutionEngineException exception. // To observe the crashing behavior set a breakpoint in the ReversePInvokeBadTransition() function // located in src/vm/dllimportcallback.cpp. testNativeMethod(); }
public static void NegativeTest_ViaLdftn() { /* * .locals init (native int V_0) * IL_0000: nop * IL_0001: ldftn void ConsoleApplication1.Program::callback(int32) * IL_0007: stloc.0 * IL_0008: ldc.i4.s 12 * IL_000a: ldloc.0 * IL_000b: calli void(int32) * IL_0010: nop * IL_0011: ret */ DynamicMethod testNativeCallable = new DynamicMethod("TestNativeCallableLdftn", null, null, typeof(Program).Module); ILGenerator il = testNativeCallable.GetILGenerator(); il.DeclareLocal(typeof(IntPtr)); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ldftn, typeof(Program).GetMethod("LdftnCallback")); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Ldc_I4, 12); il.Emit(OpCodes.Ldloc_0); SignatureHelper sig = SignatureHelper.GetMethodSigHelper(typeof(Program).Module, null, new Type[] { typeof(int) }); sig.AddArgument(typeof(int)); // il.EmitCalli is not available and the below is not correct il.Emit(OpCodes.Calli, sig); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ret); NativeMethodInvoker testNativeMethod = (NativeMethodInvoker)testNativeCallable.CreateDelegate(typeof(NativeMethodInvoker)); testNativeMethod(); }