Извлечение после внедрения DLL из запущенного процесса - PullRequest
8 голосов
/ 04 декабря 2011

Я написал эту функцию, чтобы внедрить 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;
}

Ответы [ 2 ]

11 голосов
/ 04 декабря 2011

В 32-разрядных системах значение ThreadTeminationStatus после GetExitCodeThread содержит возвращаемое значение LoadLibraryA в удаленном процессе. Это дескриптор модуля недавно загруженной библиотеки DLL. Вы можете использовать его в качестве параметра FreeLibrary в удаленном потоке.

Если вы хотите использовать код в 64-битной Windows, код завершения потока усекается до 32-битной DWORD, поэтому его нельзя использовать. Вы должны создать вызываемую подпрограмму в удаленном процессе (как предложил Necrolis) или прибегнуть к поиску модульной базы DLL через psapi или Toolhelp API (CreateToolhelp32Snapshot, Module32First, Module32Next ).

6 голосов
/ 04 декабря 2011

Вам нужно передать ему HANDLE введенной вами dll, иначе вы можете передать его VirtualMem, но тогда ваша процедура удаленного потока должна быть такой:

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

Однако, как правило,Внедренная вами dll должна выгружаться сама (см. как DllMain работает ), либо вручную, либо автоматически, когда хост закрыт.

...