private void InitThreadSafeStuff(IDebugClient debugClient) { _myThread = Thread.CurrentThread; // // Save our DebugClientPtr address for later use (if it hasn't been done already) // if (_debugClientPtr == IntPtr.Zero || _createClientDelegate == null) { IntPtr iUnknown = Marshal.GetIUnknownForObject(debugClient); Guid iDebugClientGuid = typeof(IDebugClient).GUID; int hr = Marshal.QueryInterface(iUnknown, ref iDebugClientGuid, out _debugClientPtr); if (hr != 0) { throw new Exception(); } try { MemberInfo createClientMemberInfo = typeof(IDebugClient).GetMember("CreateClient", BindingFlags.Instance | BindingFlags.Public)[0]; int createClientComSlot = Marshal.GetComSlotForMethodInfo(createClientMemberInfo); IntPtr iDebugClientVtbl = Marshal.ReadIntPtr(_debugClientPtr); IntPtr createClientPtr = Marshal.ReadIntPtr(iDebugClientVtbl, IntPtr.Size * createClientComSlot); _createClientDelegate = (CreateClientDelegate)Marshal.GetDelegateForFunctionPointer(createClientPtr, typeof(CreateClientDelegate)); } finally { // leaking this on purpose. Trying to fix refcount bug. //Marshal.Release(iUnknown); } } }
public int GetSlotOfComMethod(Delegate method) { if (method.Method.DeclaringType != typeof(T)) { throw new ArgumentOutOfRangeException("method"); } return(Marshal.GetComSlotForMethodInfo(method.Method)); }
public static void Main() { Console.WriteLine(Marshal.GetComSlotForMethodInfo(typeof(IMixedPropsAndMethods).GetMethod("MyMethod1"))); Console.WriteLine(Marshal.GetComSlotForMethodInfo(typeof(IMixedPropsAndMethods).GetProperty("MyProperty1").GetMethod)); Console.WriteLine(Marshal.GetComSlotForMethodInfo(typeof(IMixedPropsAndMethods).GetMethod("MyMethod2"))); Console.WriteLine(Marshal.GetComSlotForMethodInfo(typeof(IMixedPropsAndMethods).GetProperty("MyProperty2").GetMethod)); Console.WriteLine(Marshal.GetComSlotForMethodInfo(typeof(IMixedPropsAndMethods).GetProperty("MyProperty2").SetMethod)); Console.WriteLine(Marshal.GetComSlotForMethodInfo(typeof(IMixedPropsAndMethods).GetEvent("MyEvent1").AddMethod)); Console.WriteLine(Marshal.GetComSlotForMethodInfo(typeof(IMixedPropsAndMethods).GetEvent("MyEvent1").RemoveMethod)); }
public void TestGetComSlotForMethod_Method_Null() { try { Marshal.GetComSlotForMethodInfo(null); Assert.Fail("#1"); } catch (ArgumentNullException ex) { Assert.AreEqual(typeof(ArgumentNullException), ex.GetType(), "#2"); Assert.IsNull(ex.InnerException, "#3"); Assert.IsNotNull(ex.Message, "#4"); Assert.AreEqual("m", ex.ParamName, "#5"); } }
public void TestGetComSlotForMethodInfo() { Assert.AreEqual(7, Marshal.GetComSlotForMethodInfo(typeof(ITestDefault).GetMethod("DoNothing"))); Assert.AreEqual(7, Marshal.GetComSlotForMethodInfo(typeof(ITestDual).GetMethod("DoNothing"))); Assert.AreEqual(7, Marshal.GetComSlotForMethodInfo(typeof(ITestDefault).GetMethod("DoNothing"))); Assert.AreEqual(3, Marshal.GetComSlotForMethodInfo(typeof(ITestUnknown).GetMethod("DoNothing"))); for (int i = 0; i < 10; i++) { Assert.AreEqual(7 + i, Marshal.GetComSlotForMethodInfo(typeof(ITestInterface).GetMethod("Method" + i.ToString()))); } }
public void TestGetComSlotForMethodInfo_Method_NotOnInterface() { MethodInfo m = typeof(TestCoClass).GetMethod("DoNothing"); try { Marshal.GetComSlotForMethodInfo(m); Assert.Fail("#1"); } catch (ArgumentException ex) { // The MemberInfo must be an interface method Assert.AreEqual(typeof(ArgumentException), ex.GetType(), "#2"); Assert.IsNull(ex.InnerException, "#3"); Assert.IsNotNull(ex.Message, "#4"); Assert.AreEqual("m", ex.ParamName, "#5"); } }
public unsafe void SendMethodCall(IntPtr pIdentity, MethodBase method) { if (this._pTracker != null) { _GUID _guid; Guid guid = Marshal.GenerateGuidForType(method.ReflectedType); memcpy(&_guid, ((int)&guid), 0x10); int comSlotForMethodInfo = 4; if (method.ReflectedType.IsInterface) { comSlotForMethodInfo = Marshal.GetComSlotForMethodInfo(method); } int num2 = *(((int *)this._pTracker)) + 12; * num2[0](this._pTracker, (void *)pIdentity, &_guid, comSlotForMethodInfo); } }
static void DoWithPatchedVtable <T>(T comInterface, Expression <Action <T> > method, Delegate func, Action action) { var methodInfo = ExpressionHelper.GetMethod(method); var funcPtr = Marshal.GetFunctionPointerForDelegate(func); var interfacePtr = Marshal.GetComInterfaceForObject(comInterface, typeof(T)); var vtablePtr = Marshal.ReadIntPtr(interfacePtr); var slot = Marshal.GetComSlotForMethodInfo(methodInfo); var offset = slot * Marshal.SizeOf <IntPtr>(); var originalFuncPtr = PatchVtable(vtablePtr, offset, funcPtr); try { action(); } finally { PatchVtable(vtablePtr, offset, originalFuncPtr); } GC.KeepAlive(func); }
public unsafe void SendMethodReturn(IntPtr pIdentity, MethodBase method, Exception except) { if (this._pTracker != null) { _GUID _guid; Guid guid = Marshal.GenerateGuidForType(method.ReflectedType); memcpy(&_guid, ((int)&guid), 0x10); int comSlotForMethodInfo = 4; if (method.ReflectedType.IsInterface) { comSlotForMethodInfo = Marshal.GetComSlotForMethodInfo(method); } int modopt(IsLong) hRForException = 0; if (except != null) { hRForException = Marshal.GetHRForException(except); } int num3 = *(((int *)this._pTracker)) + 0x10; * num3[0](this._pTracker, (void *)pIdentity, &_guid, comSlotForMethodInfo, 0, hRForException); } }
public unsafe bool Query() { Guid classGuid = Guid.Empty; Guid interfaceGuid = Guid.Empty; Guid classFactoryGuid = typeof(IClassFactory).GUID; Guid classFactory2Guid = typeof(IClassFactory2).GUID; int[] vTableOffsets = null; object classInstance = null; if (ClassType != null) { classGuid = ClassType.GUID; interfaceGuid = InterfaceType.GUID; // get com-slot-number (vtable-index) of function X vTableOffsets = new int[MethodPointers.Length]; for (var i = 0; i < Methods.Length; i++) { vTableOffsets[i] = Marshal.GetComSlotForMethodInfo(Methods[i]); } } else { classGuid = ClassId; interfaceGuid = InterfaceId; // get com-slot-number (vtable-index) of function N vTableOffsets = VTableIndexes; } classInstance = GetClassInstance(classGuid, interfaceGuid, classFactoryGuid, classFactory2Guid); if (classInstance == null) { return(false); } IntPtr interfaceIntPtr = IntPtr.Zero; if (InterfaceType != null) { interfaceIntPtr = Marshal.GetComInterfaceForObject(classInstance, InterfaceType); } else { interfaceIntPtr = Marshal.GetIUnknownForObject(classInstance); } try { int ***interfaceRawPtr = (int ***)interfaceIntPtr.ToPointer(); // get vtable int **vTable = *interfaceRawPtr; // get function-addresses from vtable for (var i = 0; i < vTableOffsets.Length; i++) { int *faddr = vTable[vTableOffsets[i]]; MethodPointers[i] = new IntPtr(faddr); } } finally { // release intptr if (interfaceIntPtr != IntPtr.Zero) { Marshal.Release(interfaceIntPtr); } Marshal.FinalReleaseComObject(classInstance); } return(true); }
public static unsafe void Query(ComClassInfo cci) { Guid classguid = cci.ClassType.GUID; Guid interfguid = cci.InterfaceType.GUID; Guid classfactoryguid = typeof(IClassFactory).GUID; Guid classfactory2guid = typeof(IClassFactory2).GUID; object classinstance = null; #if false // create an instance via .NET built-in functionality // vtable might be hijacked by rpcrt4.dll classinstance = cci.ClassType.InvokeMember("", BindingFlags.CreateInstance, null, null, null); #endif #if false // create via ole-convenience-function // vtable might be hijacked by rpcrt4.dll OLE32.CoCreateInstance(ref classguid, null, 1 + 4, ref interfguid, out classinstance); #endif #if false // create via ole-functions // vtable might be hijacked by rpcrt4.dll try { if (classinstance == null) { object classfactoryO; OLE32.CoGetClassObject(ref classguid, 1 + 4, 0, ref classfactoryguid, out classfactoryO); IClassFactory classfactory = (IClassFactory)classfactoryO; classfactory.CreateInstance(null, ref interfguid, out classinstance); Marshal.FinalReleaseComObject(classfactory); } } catch { } try { if (classinstance == null) { object classfactoryO; OLE32.CoGetClassObject(ref classguid, 1 + 4, 0, ref classfactoryguid, out classfactoryO); IClassFactory2 classfactory = (IClassFactory2)classfactoryO; classinstance = classfactory.CreateInstance(null, interfguid); Marshal.FinalReleaseComObject(classfactory); } } catch { } if (classinstance == null) { // Error... } #endif #if true // create via raw dll functions // no chance for other people to hijack the vtable try { do { RegistryKey rk = Registry.ClassesRoot.OpenSubKey("CLSID\\{" + classguid + "}\\InprocServer32"); if (rk == null) { break; } string classdllname = rk.GetValue(null).ToString(); IntPtr libH = KERNEL32.LoadLibrary(classdllname); if (libH == IntPtr.Zero) { break; } IntPtr factoryFunc = KERNEL32.GetProcAddress(libH, "DllGetClassObject"); if (factoryFunc == IntPtr.Zero) { break; } var factoryDel = (DllGetClassObjectDelegate) Marshal.GetDelegateForFunctionPointer(factoryFunc, typeof(DllGetClassObjectDelegate)); object classfactoryO; factoryDel(ref classguid, ref classfactoryguid, out classfactoryO); if (classfactoryO == null) { break; } var classfactory = (IClassFactory)classfactoryO; classfactory.CreateInstance(null, ref interfguid, out classinstance); Marshal.FinalReleaseComObject(classfactory); } while (false); } catch { } try { if (classinstance == null) { do { RegistryKey rk = Registry.ClassesRoot.OpenSubKey("CLSID\\{" + classguid + "}\\InprocServer32"); if (rk == null) { break; } string classdllname = rk.GetValue(null).ToString(); IntPtr libH = KERNEL32.LoadLibrary(classdllname); if (libH == IntPtr.Zero) { break; } IntPtr factoryFunc = KERNEL32.GetProcAddress(libH, "DllGetClassObject"); if (factoryFunc == IntPtr.Zero) { break; } var factoryDel = (DllGetClassObjectDelegate) Marshal.GetDelegateForFunctionPointer(factoryFunc, typeof(DllGetClassObjectDelegate)); object classfactoryO; factoryDel(ref classguid, ref classfactory2guid, out classfactoryO); if (classfactoryO == null) { break; } var classfactory = (IClassFactory2)classfactoryO; classinstance = classfactory.CreateInstance(null, interfguid); Marshal.FinalReleaseComObject(classfactory); } while (false); } } catch { } if (classinstance == null) { // Error... } #endif IntPtr interfaceIntPtr = Marshal.GetComInterfaceForObject(classinstance, cci.InterfaceType); var interfaceRawPtr = (int ***)interfaceIntPtr.ToPointer(); // get vtable int **vTable = *interfaceRawPtr; // get com-slot-number (vtable-index) of function X // get function-address from vtable int mi_vto = Marshal.GetComSlotForMethodInfo(cci.Method); int *faddr = vTable[mi_vto]; cci.MFunctionPointer = new IntPtr(faddr); // release intptr Marshal.Release(interfaceIntPtr); Marshal.FinalReleaseComObject(classinstance); }