强制卸载进程的模块

force unload modules of a process

本文关键字:模块 进程 卸载      更新时间:2023-10-16

我想卸载进程中的某个模块。

我使用这个函数:

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。当然,你可以拿着撬棍进去,但我认为你不会实现你想要的东西......