Ejemplo n.º 1
0
        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);
                }
            }
        }
Ejemplo n.º 2
0
 public int GetSlotOfComMethod(Delegate method)
 {
     if (method.Method.DeclaringType != typeof(T))
     {
         throw new ArgumentOutOfRangeException("method");
     }
     return(Marshal.GetComSlotForMethodInfo(method.Method));
 }
Ejemplo n.º 3
0
 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));
 }
Ejemplo n.º 4
0
 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");
     }
 }
Ejemplo n.º 5
0
        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())));
            }
        }
Ejemplo n.º 6
0
        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");
            }
        }
Ejemplo n.º 7
0
 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);
        }
Ejemplo n.º 9
0
        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);
            }
        }
Ejemplo n.º 10
0
        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);
        }
Ejemplo n.º 11
0
        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);
        }