Question

Quand un ActiveXObject est hébergé dans un bureau Windows / Sidebar Gadget, que ActiveXObject est une sorte de mise en mémoire cache et le fichier DLL car il est verrouillé (ce qui signifie qu'il ne peut pas être déplacé, supprimé ou renommé). Le problème est; lorsque le gadget est ensuite fermé, la DLL est toujours verrouillé par Windows Sidebar et il ne peut pas être supprimé. Cela provoque un problème important par lequel une nouvelle version du gadget ne peut pas être installé sur le dessus d'une version précédente du gadget, il échoue pendant le processus de suppression sans aucun message d'erreur.

Ce n'est pas très convivial, donc je suis à la recherche d'un moyen de liens « rompre » au contrôle ActiveX en quelque sorte lors de l'événement de déchargement du gadget. J'espère que quelqu'un peut me dire c'est de savoir si possible et si elle est me donner quelques idées sur la façon de le mettre en œuvre.

Pour votre information, la barre latérale de Windows Gadgets sont en fait que des fenêtres de serveur d'Internet Explorer, il est probablement prudent de supposer IE présente le même comportement.

EDIT: Unlocker semble faire à peu près ce que je dois à faire, alors comment puis-je obtenir la même chose dans .NET programme?

Était-ce utile?

La solution

Ok c'est un problème assez complexe. Je l'ai vu ce comportement avant, je ne suis pas familier avec le Windows Desktop / Sidebar Gadget que je ne l'utilise pas. Cependant, j'ai réussi à trouver trois méthodes possibles d'attaque

1. Poignée de TechNet

Ce ne fut pas mon idée, Examiner Informations sur Windows NT System Level Primitives

  • Suppression fichiers verrouillés
  • Injecter une DLL dans l'espace d'adressage d'un autre processus
  • Malheureusement, je ne pouvais pas que cela fonctionne de façon transparente. Je l'ai testé cette méthode en utilisant un ActiveX chargé dans MS Word. J'ai ensuite essayé de déverrouiller le ActiveX, ce n'est pas très stable et mot souvent causé crash. Je suppose que je n'ai pas les blessures de guerre c ++ nécessaires pour déchiffrer correctement les programmes ci-dessus.

    Avec cet exemple de CreateRemoteThread en C # J'ai mis ce code ensemble.

    public struct ProcessInfo
    {
        public Process Process;
        public ProcessModule Module;
    
        public ProcessInfo(Process process, ProcessModule module)
        {
            this.Process = process;
            this.Module = module;
        }
    }
    
    private static List<ProcessInfo> getProcessInfo(string fileName, bool partialMatch)
    {
        List<ProcessInfo> myProcesses = new List<ProcessInfo>();
    
        Process[] runningProcesses = Process.GetProcesses();
        int i = 0;
        for (i = 0; i < runningProcesses.Length; i++)
        {
            Process currentProcess = runningProcesses[i];
            try
            {
                if (!currentProcess.HasExited)
                {
                    try
                    {
                        ProcessModuleCollection modules = currentProcess.Modules;
                        int j = 0;
                        for (j = 0; j < modules.Count; j++)
                        {
                            if (partialMatch)
                            {
                                if ((modules[j].FileName.ToLower().IndexOf(fileName.ToLower()) != -1))
                                {
                                    myProcesses.Add(new ProcessInfo(currentProcess, modules[j]));
                                    break;
                                }
                            }
                            else
                            {
                                if ((modules[j].FileName.ToLower().CompareTo(fileName.ToLower()) == 0))
                                {
                                    myProcesses.Add(new ProcessInfo(currentProcess, modules[j]));
                                    break;
                                }
                            }
                        }
                    }
                    catch (NotSupportedException)
                    {
                        // You are attempting to access the Modules property for a process that is running on a remote computer. 
                        // This property is available only for processes that are running on the local computer. 
                    }
                    catch (InvalidOperationException)
                    {
                        // The process Id is not available.
                    }
                    catch (Win32Exception)
                    {
                        // You are attempting to access the Modules property for either the system process or the idle process. 
                        // These processes do not have modules.
                    }
                }
            }
            catch (InvalidOperationException)
            {
                // There is no process associated with the object. 
            }
            catch (Win32Exception)
            {
                // The exit code for the process could not be retrieved. 
            }
            catch (NotSupportedException)
            {
                // You are trying to access the HasExited property for a process that is running on a remote computer.
                // This property is available only for processes that are running on the local computer.
    
            }
        }
        return myProcesses.Count > 0 ? myProcesses : null;
    }
    
    private static void forceRemoteCloseHandle(ProcessInfo processInfo)
    {
        // Open remote process for write
        IntPtr hProcess = NativeMethods.OpenProcess(NativeMethods.PROCESS_CREATE_THREAD | NativeMethods.PROCESS_VM_OPERATION |
                NativeMethods.PROCESS_VM_WRITE | NativeMethods.PROCESS_VM_READ, false, processInfo.Process.Id);
    
        // Get the handle to CloseHandle in kernel32.dll
        IntPtr hKernel32 = NativeMethods.LoadLibrary("kernel32.dll");
        IntPtr hCloseHandle = NativeMethods.GetProcAddress(hKernel32, "CloseHandle");
        uint temp = 0;
    
        // Create the remote thread and point it to CloseHandle
        IntPtr hCreateRemoteThread = NativeMethods.CreateRemoteThread((IntPtr)hProcess, (IntPtr)0, 0, hCloseHandle, (IntPtr)processInfo.Module.BaseAddress, 0, out temp);
    
        // Wait for thread to end
        NativeMethods.WaitForSingleObject(hCreateRemoteThread, 2000);
    
        //Closes the remote thread handle
        NativeMethods.CloseHandle(hCreateRemoteThread);
    
        //Free up the kernel32.dll
        if (hKernel32 != null)
            NativeMethods.FreeLibrary(hKernel32);
    
        //Close the process handle
        NativeMethods.CloseHandle(hProcess);
    }
    
    private static void forceRemoteFreeLibrary(ProcessInfo processInfo)
    {
        // Open remote process for write
        IntPtr hProcess = NativeMethods.OpenProcess(NativeMethods.PROCESS_CREATE_THREAD | NativeMethods.PROCESS_VM_OPERATION |
                NativeMethods.PROCESS_VM_WRITE | NativeMethods.PROCESS_VM_READ, false, processInfo.Process.Id);
    
        // Get the handle to FreeLibrary in kernel32.dll
        IntPtr hKernel32 = NativeMethods.LoadLibrary("kernel32.dll");
        IntPtr hFreeHandle = NativeMethods.GetProcAddress(hKernel32, "FreeLibrary");
    
        // Create the remote thread and point it to FreeLibrary
        uint temp = 0;
        IntPtr hCreateRemoteThread = NativeMethods.CreateRemoteThread((IntPtr)hProcess, (IntPtr)0, 0, hFreeHandle, (IntPtr)processInfo.Module.BaseAddress, 0, out temp);
    
        // Wait for thread to end
        NativeMethods.WaitForSingleObject(hCreateRemoteThread, 2000);
    
        //Closes the remote thread handle
        NativeMethods.CloseHandle(hCreateRemoteThread);
    
        //Free up the kernel32.dll
        if (hKernel32 != null)
            NativeMethods.FreeLibrary(hKernel32);
    
        // Close the process handle
        NativeMethods.CloseHandle(hProcess);        
    }
    
    public static void Main()
    {
        string strFile = @"C:\Program Files\Microsoft Office\OFFICE11\MSCAL.OCX";
        List<ProcessInfo> lockingProcesses = getProcessInfo(strFile, false);
    
        foreach (ProcessInfo processInfo in lockingProcesses)
        {
            forceRemoteCloseHandle(processInfo);
            // OR
            forceRemoteFreeLibrary(processInfo);
        }
    
        // OR
        foreach (ProcessInfo procInfo in lockingProcesses)
        {
            procInfo.Process.Kill();
        }
    
    }
    
    internal static class NativeMethods
    {
        internal const int PROCESS_TERMINATE = 0x0001;
        internal const int PROCESS_CREATE_THREAD = 0x0002;
        internal const int PROCESS_VM_OPERATION = 0x0008;
        internal const int PROCESS_VM_READ = 0x0010;
        internal const int PROCESS_VM_WRITE = 0x0020;
    
        internal const int PROCESS_QUERY_INFORMATION = 0x0400;
    
        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        internal static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
    
        [DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
        internal static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
    
        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        internal static extern int WaitForSingleObject(IntPtr hHandle, int dwMilliseconds);
    
        [DllImport("kernel32", SetLastError = true)]
        internal static extern IntPtr LoadLibrary(string lpFileName);
    
    
        [DllImport("kernel32.dll", SetLastError = true)]
        internal static extern bool FreeLibrary(IntPtr hModule);
    
        [DllImport("kernel32")]
        public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out uint lpThreadId);
    
        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        internal static extern int CloseHandle(IntPtr hPass);
    }
    

    ...


    3. Il suffit d'utiliser Unlocker

    est ma meilleure recommandation. Poignée de technet ne peut pas gérer les verrous dll / ocx chargés (sous mes tests). Win32 est en désordre et sans papier.

    Unlocker permet un accès en ligne de commande de sorte que vous pouvez l'appeler exactement de la même manière que Handle.exe. Juste un wack /? après Unlocker.exe dans une invite de commande pour voir les commutateurs.

    Il y a aussi un version portable de Unlocker disponible de sorte que vous pouvez regrouper dans votre déploiement sans forcer les utilisateurs finaux à installer l'application.

    Si tout le reste échoue, vous pouvez contacter l'auteur de Unlocker, consultez ce de son readme.

      

    Permis

         

    Si vous êtes intéressé par   redistribuer Unlocker, soit en   forme originale ou modifiée, ou si vous souhaitez   utiliser le code source Unlocker dans un produit,   s'il vous plaît envoyer un courrier électronique à   ccollomb@yahoo.com avec des détails.

    ...


    4. Utilisation Process Hacker bibliothèques partagées

    Je viens de découvrir ce brillant outil: Process Hacker qui est écrit dans 100% du code C # (même si il utilise beaucoup de fonctions WinAPI via P / Invoke sous le capot).

    La meilleure chose à ce sujet: il est open source (LGPL'd) et fournit deux bibliothèques que les développeurs peuvent faire référence dans leurs solutions: Processus ProcessHacker.CommonHacker.Native.

    J'ai téléchargé la source et juste un mot d'avertissement, il est une solution assez grand, peut prendre un peu de temps pour savoir exactement quoi / comment l'utiliser.

    Il utilise les fonctions API non documentées (de ntdll.dl) j'ai parlé dans l'option 2 et peut tout faire Unlocker peut et beaucoup plus.

    Autres conseils

    Je ne sais pas si cela fonctionne pour les objets ActiveX mais il définitivement pour les assemblages .NET. Je l'utilise pour UnitTesting où les DLL doivent être remplacées facilement. Le mécanisme utilisé est ombre copie .

    Fermeture poignées à l'extérieur une application ne semble pas vraiment une option très sûr.

    Il est pas la solution peut-être une idée ou la direction ...

    Licencié sous: CC-BY-SA avec attribution
    Non affilié à StackOverflow
    scroll top