Example #1
0
        private object GetClassInstance(Guid classguid, Guid interfguid, Guid classfactoryguid, Guid classfactory2guid)
        {
            object classinstance = null;

            // create instance via raw dll functions
            // ensures we get the real vtable
            try
            {
                if (classinstance == null)
                {
                    // Single do..while loop - to support "break;"
                    do
                    {
                        Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey("CLSID\\{" + classguid.ToString() + "}\\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;
                        }
                        DllGetClassObjectDelegate factoryDel = (DllGetClassObjectDelegate)Marshal.GetDelegateForFunctionPointer(factoryFunc, typeof(DllGetClassObjectDelegate));
                        object classfactoryO;
                        // Try with IClassFactory first
                        factoryDel(ref classguid, ref classfactoryguid, out classfactoryO);
                        if (classfactoryO != null)
                        {
                            IClassFactory classfactory = (IClassFactory)classfactoryO;
                            classfactory.CreateInstance(null, ref interfguid, out classinstance);
                            Marshal.FinalReleaseComObject(classfactory);
                        }
                        else
                        {
                            // Now try with IClassFactory2
                            factoryDel(ref classguid, ref classfactory2guid, out classfactoryO);
                            if (classfactoryO == null)
                            {
                                break;
                            }
                            IClassFactory2 classfactory = (IClassFactory2)classfactoryO;
                            classinstance = classfactory.CreateInstance(null, interfguid);
                            Marshal.FinalReleaseComObject(classfactory);
                        }
                    } while (false);
                }
            }
            catch { }

            return(classinstance);
        }
 public static extern HRESULT CoGetClassObject(
     ref Guid rclsid,
     CLSCTX dwContext,
     IntPtr pvReserved,
     ref Guid riid,
     [MarshalAs(UnmanagedType.Interface)] out IClassFactory2 ppv);
Example #3
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);
        }
Example #4
0
        /// <summary>
        /// Creates an instance of a COM server using the specified license key.
        /// </summary>
        public static object CreateInstanceWithLicenseKey(Guid clsid, string hostName, NetworkCredential credential, string licenseKey)
        {
            var            serverInfo   = new ServerInfo();
            COSERVERINFO   coserverInfo = serverInfo.Allocate(hostName, credential);
            object         instance     = null;
            IClassFactory2 factory      = null;

            try
            {
                // Check whether connecting locally or remotely.
                uint clsctx = ComConstants.CLSCTX_INPROC_SERVER | ComConstants.CLSCTX_LOCAL_SERVER;

                if (!string.IsNullOrEmpty(hostName))
                {
                    clsctx = ComConstants.CLSCTX_LOCAL_SERVER | ComConstants.CLSCTX_REMOTE_SERVER;
                }

                // Get the class factory.
                object unknown = null;

                CoGetClassObject(
                    clsid,
                    clsctx,
                    ref coserverInfo,
                    typeof(IClassFactory2).GUID,
                    out unknown);

                factory = (IClassFactory2)unknown;

                // Set the proper connect authentication level
                var security = (IClientSecurity)factory;

                uint   pAuthnSvc        = 0;
                uint   pAuthzSvc        = 0;
                var    pServerPrincName = "";
                uint   pAuthnLevel      = 0;
                uint   pImpLevel        = 0;
                IntPtr pAuthInfo        = IntPtr.Zero;
                uint   pCapabilities    = 0;

                // Get existing security settings.
                security.QueryBlanket(
                    factory,
                    ref pAuthnSvc,
                    ref pAuthzSvc,
                    ref pServerPrincName,
                    ref pAuthnLevel,
                    ref pImpLevel,
                    ref pAuthInfo,
                    ref pCapabilities);

                pAuthnSvc   = ComConstants.RPC_C_AUTHN_DEFAULT;
                pAuthnLevel = ComConstants.RPC_C_AUTHN_LEVEL_CONNECT;

                // Update security settings.
                security.SetBlanket(
                    factory,
                    pAuthnSvc,
                    pAuthzSvc,
                    pServerPrincName,
                    pAuthnLevel,
                    pImpLevel,
                    pAuthInfo,
                    pCapabilities);

                // Create instance.
                factory.CreateInstanceLic(
                    null,
                    null,
                    IUnknownIID,
                    licenseKey,
                    out instance);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                serverInfo.Deallocate();
            }

            return(instance);
        }