8

我编写了这个函数来将 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 时,我无法找到有关脱钩的信息。我试图构建一些功能来做到这一点,我想我已经接近了,这就是我到目前为止:

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

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;
}
4

2 回答 2

11

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

如果要在 64 位 Windows 上使用代码,线程退出代码会被截断为 32 位DWORD,因此无法使用。您必须在远程进程中创建一个可调用的例程(如 Necrolis 建议的那样),或者求助于通过 psapi 或Toolhelp API ( CreateToolhelp32Snapshot, Module32First, Module32Next) 查找 DLL 的模块库。

于 2011-12-04T01:40:55.840 回答
6

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

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

但是,通常您注入的 dll 应在主机关闭时手动或自动卸载自身(请参阅如何DllMain工作)。

于 2011-12-04T01:33:04.270 回答