强制卸载进程的模块
force unload modules of a process
我想卸载进程中的某个模块。
我使用这个函数:
bool UnInjectDll(const TCHAR* ptszDllFile, DWORD dwProcessId)
{
if (NULL == ptszDllFile || 0 == ::_tcslen(ptszDllFile))
{
return false;
}
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
HANDLE hProcess = NULL;
HANDLE hThread = NULL;
hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
if (INVALID_HANDLE_VALUE == hModuleSnap)
{
return false;
}
MODULEENTRY32 me32;
memset(&me32, 0, sizeof(MODULEENTRY32));
me32.dwSize = sizeof(MODULEENTRY32);
if(FALSE == ::Module32First(hModuleSnap, &me32))
{
::CloseHandle(hModuleSnap);
return false;
}
bool isFound = false;
do
{
isFound = (0 == ::_tcsicmp(me32.szModule, ptszDllFile) || 0 == ::_tcsicmp(me32.szExePath, ptszDllFile));
if (isFound)
{
break;
}
} while (TRUE == ::Module32Next(hModuleSnap, &me32));
::CloseHandle(hModuleSnap);
if (false == isFound)
{
return false;
}
hProcess = ::OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION, FALSE, dwProcessId);
if (NULL == hProcess)
{
return false;
}
LPTHREAD_START_ROUTINE lpThreadFun = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "FreeLibrary");
if (NULL == lpThreadFun)
{
::CloseHandle(hProcess);
return false;
}
hThread = ::CreateRemoteThread(hProcess, NULL, 0, lpThreadFun, me32.modBaseAddr , 0, NULL);
if (NULL == hThread)
{
::CloseHandle(hProcess);
return false;
}
::WaitForSingleObject(hThread, INFINITE);
::CloseHandle(hThread);
::CloseHandle(hProcess);
return true;
}
但是当我使用此代码时,它不能从项目中卸载我想要的特殊模块。
我也使用"过程检测"工具来执行此操作,但此工具也无法执行此操作。
现在我想要一个函数,我可以确定它会从我想要的进程中卸载一个特殊的模块。 例如,您创建了一个仅显示消息框的简单程序,现在如果您看到其进程的模块,它有一个模块NTDLL.dll和其他一些模块,现在您无法从中删除NTDLL.dll模块或其他模块。 我想要一个函数来强制进程删除任何模块从我想要的过程。
你想做的事情是完全危险的(据我所知,幸运的是,不可能)。
您的程序或库链接到某些其他 DLL。作为回报,这些库也会引用其他库,依此类推。当您的程序或 DLL 由 Windows 加载程序加载到内存空间时,这些"依赖项"也将加载,并且您的导入地址表将被修补,以便您的调用知道在执行时跳转到何处。所有代码都将作为一个原子实体硬连线在一起。
卸载以这种方式静态链接的 DLL(.dlls 文件也可以静态链接,不要与静态 .lib 文件混淆)基本上会强制您的应用程序在进行任何依赖于该 libarary 的调用时崩溃 - 尤其是ntdll.dll
,这将是您链接的大多数库的根。调用将被抛入虚空。这些库无法卸载,因为它们在某种意义上是程序的一部分。
但是,如果您在运行时动态加载库,则可以随时自由卸载它。由于您可能无论如何都使用 GetProcAddress
通过动态地址工作,因此您需要确保函数指针具有有效的目标。
所欲地戴上帽子,但你不能(也不应该)撕掉你的心;)
虽然我知道它并没有完全回答你的问题,但虽然这只是一个警告,你永远不应该在没有非常非常好的理由的情况下这样做(我不知道你真的有),我很肯定你不能做你所要求的 - 但我很高兴让其他人在这里纠正我。
如果您想对加载的库执行某些操作,并且您已经在这种破坏性过程中,只需直接覆盖内存中的库或 IOT。当然,你可以拿着撬棍进去,但我认为你不会实现你想要的东西......
- boost::进程间消息队列引发错误
- 尝试导入pybind-opencv模块时出现libgtk错误
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 是否可以通过C++扩展强制多个python进程共享同一内存
- IPC使用多个管道和分支进程来运行Python程序
- 异常属于C++中的线程还是进程
- WMI检测进程创建事件-c++
- c++多进程编写一个唯一的文件
- 如何在C++中将函数发送到另一个进程
- 枚举进程模块在有效句柄上返回无效句柄
- 通过进程模块C 枚举时,访问被拒绝
- Visual Studio 在附加到进程时不会加载模块
- 强制卸载进程的模块
- 在同一进程中使用的两个模块中具有同步对象的通用名称是否安全
- 从其他进程获取模块句柄
- 使用Module32First/Next从64位进程中枚举32位进程模块
- 如何将事件处理程序附加到本机 Node.js 模块中的进程出口?
- 内存模块是否映射到进程的虚拟空间?
- 无法在具有无限循环的 boost.python 模块中通过 Ctrl-c 杀死进程
- 列出Windows进程和模块