强制卸载进程的模块

时间:2014-11-15 10:25:41

标签: c++ visual-c++

我想在一个进程中卸载一些模块。

我使用这个功能:

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模块或一些来自它的其他模块。我想要一个函数来强制进程从我想要的进程中删除任何模块。

1 个答案:

答案 0 :(得分:1)

你想做的事情是完全危险的(据我所知,幸运的是,不可能)。

您的程序或库与某些其他DLL链接。这些库反过来也引用其他库,依此类推,等等。当您的程序或DLL由Windows加载程序加载到内存空间时,这些“依赖项”也将被加载,您的导入地址表将被修补,以便您的调用知道在执行它们时将跳转到哪里。所有代码都将作为原子实体硬连接在一起。

卸载以这种方式静态链接的DLL(.dll文件也可以静态链接,不要与静态.lib文件混淆)基本上强制你的应用程序崩溃第二次任何调用依赖于libarary - 尤其是ntdll.dll,它将成为您链接的所有lib的大部分根。这些电话将被抛入虚空。这些库无法卸载,因为它们在程序中属于某种意义。

如果您在运行时动态加载了库,则可以随时卸载它。由于您可能无论如何都使用GetProcAddress通过动态地址工作,因此您需要确保您的函数指针具有有效目标。

你可以随心所欲地戴上帽子,但你不能(也不应该)撕掉你的心脏;)

虽然我知道,它并没有完全回答你的问题,但是这只是一个警告,你不应该在没有非常好的理由(我不知道你真的有)的情况下这样做,我是相当积极的你不能做你所要求的 - 但我很高兴让其他人在这里纠正我。

如果你想对加载的库做一些事情,并且你已经在这个破坏性的过程中,只需直接覆盖内存中的库或IAT。当然,你可以用撬棍进去,但我认为你不会想要找到你想要的东西......

相关问题