-1

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

我试着做GetModuleHandle,然后FreeLibrary没有结果......

感谢您的所有回复

感谢您的所有回复。我在这里找到了一篇有趣的 msdn 文章:

http://blogs.msdn.com/b/jmstall/archive/2006/09/28/managed-create-remote-thread.aspx

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

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

这是我在 c# 中尝试做的事情: [code] protected const int PROCESS_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF); 受保护的 const int STANDARD_RIGHTS_REQUIRED = 0xF0000; 受保护的 const 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]
4

2 回答 2

8

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

这里是龙

也就是说,它可以做到,而且相当容易。

您所要做的就是使用CreateRemoteThread,将句柄传递给您要强制卸载的进程,并将函数指针传递给调用GetModuleHandleand的函数FreeLibrary。非常简单。

示例代码(未经测试,用vi编写,无论如何都不要使用):

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);
}
于 2012-05-06T10:29:14.213 回答
1

您不能强制外部进程卸载它的模块。您需要从外部进程内部运行该代码。您能希望的最好结果就是终止拥有外部 DLL 的进程。如果您可以从外部进程中卸载 dll,那将是非常危险的,代码可能在您将其从 RAM 中拉出时正在运行。

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

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

于 2012-05-06T10:25:58.330 回答