有人知道如何卸载外部进程加载的dll或任何其他类型的模块吗?
我试着做GetModuleHandle
然后FreeLibrary
没有结果......
感谢您的所有回复
感谢您的所有回复。我在这里找到了一篇有趣的msdn文章:
http://blogs.msdn.com/b/jmstall/archive/2006/09/28/managed-create-remote-thread.aspx
问题是当我尝试执行OpenProcess时,外部进程崩溃。
从中卸载模块的最低进程访问权限是多少?
这是我在 c# 中尝试做的事情:[代码]受保护的常量整数PROCESS_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED |同步 |0xFFF);受保护的常量 int STANDARD_RIGHTS_REQUIRED = 0xF0000;受保护的常量 int 同步 = 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:alogerr.txt"))
{
sw.AutoFlush = true;
sw.WriteLine("In Unload Module");
StringBuilder sb_module_name =new StringBuilder(@"C:WindowsSystem32MyDll.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]
你可以做到,但老实说,我必须问为什么?你很可能会把事情搞砸,超出你的意識。说真的,如果你这样做,没有什么可以做的。不要阅读这篇文章的其余部分,关闭浏览器,做一些冥想,弄清楚你做错了什么让你问这个问题。
这里是龙
也就是说,它可以做到,而且也很容易。
您所要做的就是使用 CreateRemoteThread
,将句柄传递给要强制卸载的进程,以及指向调用 GetModuleHandle
和 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);
}
不能强制外部进程卸载其模块。您需要从外部进程内部运行该代码。您能希望的最好的结果是杀死拥有外部 DLL 的进程。如果您可以从外部进程卸载 dll,那将是非常危险的,代码可能在您将其从 RAM 中拉出时正在运行。
如果要替换 DLL,最好的办法就是重命名 DLL 并保存新 DLL。这样,DLL 将在下次外部进程加载时使用。
对上面斜体的更正:你可以这样做,但如果你这样做,你就会带来大麻烦。我仍然认为最好的方法是执行我上面列出的操作,重命名 DLL 并将新 DLL 放在它的位置,以便下次外部进程启动时。如果要替换 DLL,这是一种更安全的方法。