C# 卸载外部进程的已加载DLL

C# 卸载外部进程的已加载DLL,c#,winapi,visual-c++,C#,Winapi,Visual C++,有人知道如何卸载dll或外部进程加载的任何其他类型的模块吗 我尝试了GetModuleHandle,然后freebrary,但没有结果 谢谢你的回复 谢谢你的回复。我在这里发现了一篇有趣的msdn文章: 问题是,当我尝试执行OpenProcess时,外部进程崩溃 从中卸载模块的最小进程访问权限是多少 以下是我在c#中要做的事情: [守则] 受保护的const int PROCESS_ALL_ACCESS=(需要标准权限|同步| 0xFFF); 受保护的const int标准权限要求=0xF00

有人知道如何卸载dll或外部进程加载的任何其他类型的模块吗

我尝试了
GetModuleHandle
,然后
freebrary
,但没有结果


谢谢你的回复


谢谢你的回复。我在这里发现了一篇有趣的msdn文章:

问题是,当我尝试执行OpenProcess时,外部进程崩溃

从中卸载模块的最小进程访问权限是多少

以下是我在c#中要做的事情: [守则] 受保护的const int PROCESS_ALL_ACCESS=(需要标准权限|同步| 0xFFF); 受保护的const int标准权限要求=0xF0000; 受保护常量int SYNCHRONIZE=0x100000

    public static bool UnloadRemoteModule(FileEntry le)
    {
        try
        {
            Process process = System.Diagnostics.Process.GetProcessById(le.ProcessID);

            if (process == null) return false;
            StringBuilder sb = new StringBuilder(le.File);

            UnloadModuleThreadProc umproc = new UnloadModuleThreadProc(UnloadModule);
            IntPtr fpProc = Marshal.GetFunctionPointerForDelegate(umproc);               

            SafeProcessHandle processHandle = null;

            IntPtr currentProcess = NativeMethods.GetCurrentProcess();
            int processId = le.ProcessID;
            bool remote = (processId != NativeMethods.GetProcessId(currentProcess));

            try
            {
                if (remote)
                {

                    MessageBox.Show("OPENING PROCESS !");
                    processHandle = NativeMethods.OpenProcess(PROCESS_ALL_ACCESS, true, processId);
                    System.Threading.Thread.Sleep(200);
                    uint dwThreadId;

                    if (processHandle.DangerousGetHandle() == IntPtr.Zero)
                    {
                        MessageBox.Show("COULD NOT OPEN HANDLE !");

                    }
                    else
                    {
                        // Create a thread in the first process.
                        IntPtr hThread = CreateRemoteThread(
                            processHandle.DangerousGetHandle(),
                            IntPtr.Zero,
                            0,
                            fpProc, IntPtr.Zero,
                            0,
                            out dwThreadId);

                        System.Threading.Thread.Sleep(200);

                        WaitForThreadToExit(hThread);
                    }

                }
                return true;
            }
            finally
            {
                if (remote)
                {                        
                    if (processHandle != null)
                    {
                        processHandle.Close();
                    }                       
                }
            }

            return false;
        }
        catch (Exception ex)
        {
            //Module.ShowError(ex);
            return false;
        }
    }

    public delegate int UnloadModuleThreadProc(IntPtr sb_module_name);

    static int UnloadModule(IntPtr sb_module_name2)
    {
        using (StreamWriter sw = new StreamWriter(@"c:\a\logerr.txt"))
        {
            sw.AutoFlush = true;
            sw.WriteLine("In Unload Module");

            StringBuilder sb_module_name =new StringBuilder(@"C:\Windows\System32\MyDll.dll");

            IntPtr mh = DetectOpenFiles.GetModuleHandle(sb_module_name.ToString());

            sw.WriteLine("LAST ERROR="+Marshal.GetLastWin32Error().ToString());

            sw.WriteLine("POINTER="+mh.ToInt32());

            if (mh != IntPtr.Zero)
            {
                return (FreeLibrary(mh) ? 1 : 0);
            }

            sw.WriteLine("LAST ERROR 2 =" + Marshal.GetLastWin32Error().ToString());
            sw.WriteLine("EXIT " + mh.ToInt32());
        }

        return 0;
    }[/code]
不能强制外部进程卸载其模块。您需要从外部进程内部运行该代码。您所能期望的最好方法是杀死拥有外部DLL的进程。如果您可以从外部进程卸载dll,那么这将是非常危险的,代码可能在您将其从RAM中拉出时正在运行

如果要替换DLL,最好是重命名DLL并保存新的DLL。这样,DLL将在下次外部进程加载时得到使用


更正上面的斜体字:你可以这么做,但如果你这么做,你会自找麻烦。我仍然认为最好的方法是执行上面列出的操作,重命名DLL,并在下一次外部进程启动时将新的DLL放在适当的位置。如果您想替换DLL,这是一种安全得多的方法。

您可以这样做,但老实说,我必须问一下为什么?你很可能会把事情搞得一团糟。说真的,如果你这么做的话,没有什么事情是对的。不要阅读这篇文章的其余部分,关闭浏览器,做一些冥想,找出你做错了什么让你问这个问题

这里有龙

也就是说,这是可以做到的,而且相当容易

您所要做的就是使用、传递一个句柄到要强制卸载的进程,以及一个指向调用
GetModuleHandle
freebrary
的函数的函数指针。容易极了

示例代码(未经测试,用vi编写,无论发生什么情况都不使用):


这没有多大意义。模块由该进程加载到一个进程中,那么如何将另一个进程加载的模块卸载到另一个进程中呢?换句话说,其他流程正在做的事情与您的流程无关。提示:不要以“我可以拥有codez plz”之类的内容来结束您的问题。是的,您可以,但不应该。看看我的答案。好的,看看你在做什么。哎哟,那太危险了。:)真的。因此,我的新免责声明!希望OP能听到:)我会帮你看看。我关心的不是这件事能否完成。如果你看看马哈茂德的帖子,你肯定能做到。这样做的风险是巨大的。如果您可以控制托管DLL的外部应用程序,那么您应该能够创建某种API,让应用程序从内存中删除库。如果没有,那么在注入新线程时,您不知道应用程序在做什么。它可能在您将其从ram中拉出时正在运行该库中的代码。这是一个很大的危险。这是一个很好的答案,无论是技术上的有效性还是大量重复的警告。我必须说这是一个非常聪明的解决问题的方法。我希望这些警告会得到注意。我只被允许投1票,否则我会给更多:)递归赢:)+1.当然,您忘记了这个函数本身必须首先加载到远程进程中,只有这样,
CreateRemoteProcess
才能成功。但我们不要告诉任何人;)当然,你是对的!(现在是早上6点,我应该去睡觉了。我最初的答案传递了一个指向UnloadModule函数的字符指针。说傻话吧!)谢谢你的回复。我在这里发现了一篇有趣的msdn文章:
DWORD WINAPI UnloadNamedModule(void *)
{
    //If you value your life, don't use this code
    LPCTSTR moduleName = _T("MYMODULE.DLL");
    HMODULE module = GetModuleHandle(moduleName);

    if (module != NULL)
    {
        UnloadModule(hModule);
        //All hell breaks loose. Not even this comment will be reached.
        //On your own head be it. Don't say I didn't warn you.
    }
}

//Warning: this function should never be run!
void UnloadRemoteModule(HANDLE hProcess)
{
    CreateRemoteThread(hProcess, NULL, 0, UnloadNamedModule, NULL, 0);
}