从运行的进程注入DLL后弹出



我编写了这个函数来将DLL注入到运行的进程中:

DLL_Results CDLL_Loader::InjectDll()
{
    DWORD ThreadTeminationStatus;
    LPVOID VirtualMem;
    HANDLE hProcess, hRemoteThread;
    HMODULE hModule;
    if (!isInit())
        return NOT_INIT;
    if (isInjected())
        return DLL_ALREADY_HOOKED;
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);
    if (hProcess == NULL)
        return PROCESS_ERROR_OPEN;
    VirtualMem = VirtualAllocEx (hProcess, NULL, strlen(DllFilePath), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    if (VirtualMem == NULL)
        return PROCESS_ERRORR_VALLOC;
    if (WriteProcessMemory(hProcess, (LPVOID)VirtualMem, DllFilePath, strlen(DllFilePath), NULL) == 0)
    {
        VirtualFreeEx(hProcess, NULL, (size_t)strlen(DllFilePath), MEM_RESERVE|MEM_COMMIT);
        CloseHandle(hProcess); 
        return PROCESS_ERROR_WRITE;
    }
    hModule = GetModuleHandle(L"kernel32.dll");
    hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, 
                        (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "LoadLibraryA"),
                          (LPVOID)VirtualMem, 0, NULL);
    if (hRemoteThread == NULL)
    {
        FreeLibrary(hModule);
        VirtualFreeEx(hProcess, NULL, (size_t)strlen(DllFilePath), MEM_RESERVE | MEM_COMMIT);
        CloseHandle(hProcess); 
        return PROCESS_ERROR_CREATE_RTHREAD;
    }
    WaitForSingleObject(hRemoteThread, INFINITE);
    GetExitCodeThread(hRemoteThread, &ThreadTeminationStatus);
    FreeLibrary(hModule);
    VirtualFreeEx(hProcess, NULL, (size_t)strlen(DllFilePath), MEM_RESERVE | MEM_COMMIT);
    CloseHandle(hRemoteThread);
    CloseHandle(hProcess); 
    injected = true;
    return DLLHOOK_OK;
}

它工作得很好,但是当我试图弹出dll时,我无法找到有关解钩的信息。我试着建立一些函数来做这个,我想我已经很接近了这是我目前得到的:

是正确的方式吗?如果是这样,我应该在createRemoteThread中传递什么参数而不是VirtualMem(在注入函数中使用)…

DLL_Results CDLL_Loader::EjectDll()
{
    DWORD ThreadTeminationStatus;
    HANDLE hProcess, hRemoteThread;
    HMODULE hModule;
    if (isInjected())
        return DLLEJECT_OK;
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);
    if (hProcess == NULL)
        return PROCESS_ERROR_OPEN;
    hModule = GetModuleHandle(L"kernel32.dll");
    hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, 
                        (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "FreeLibrary"),
                          /*(LPVOID)VirtualMem <- What do i need to send here?*/, 0, NULL);
    if (hRemoteThread != NULL)
    {
        WaitForSingleObject(hRemoteThread, INFINITE);
        GetExitCodeThread(hRemoteThread, &ThreadTeminationStatus);
    }
    CloseHandle(hRemoteThread);
    CloseHandle(hProcess); 
    injected = false;
    return DLLEJECT_OK;
}

在32位系统上,GetExitCodeThread后面的ThreadTeminationStatus的值包含远程进程中LoadLibraryA的返回值。这是新加载的dll的模块句柄。您可以将其用作远程线程中FreeLibrary的参数。

如果您想在64位Windows上使用该代码,线程退出代码将被截断为32位DWORD,因此它不可用。您必须在远程进程中创建一个可调用的例程(如Necrolis所建议的),或者通过psapi或Toolhelp API (CreateToolhelp32Snapshot, Module32First, Module32Next)查找DLL的模块基。

你需要把你注入的dll的HANDLE传递给它,否则你可以把VirtualMem传递给它,但是你的远程线程例程需要是:

DWORD WINAPI UnloadDll(void* pMem)
{
    FreeLibrary(GetModuleHandleA((const char*)pMem));
    return 0;
}

然而,通常你注入的dll应该卸载自己(参见DllMain如何工作),手动或自动当主机关闭

最新更新