从运行进程注入DLL后弹出

时间:2011-12-04 01:22:07

标签: c++ dll-injection

我写了这个函数来将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 instade中传递什么参数(在注入函数中使用)...

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

2 个答案:

答案 0 :(得分:11)

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

如果要在64位Windows上使用代码,则线程退出代码将被截断为32位DWORD,因此无法使用。 你必须在远程进程中创建一个可调用的例程(如Necrolis建议的那样)或者通过psapi或Toolhelp API(CreateToolhelp32SnapshotModule32First,{Module32Next找到DLL的模块库。 {1}})。

答案 1 :(得分:6)

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

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

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