使用远程线程来注入DLL

使用远程线程来注入DLL

DLL注入技术要求我们目标进程中的一个线程调用LoadLibrary来载入我们想要的DLL

(1)用OpenProcess函数打开目标进程
(2)用VirtualAllocEx函数在远程进程的地址空间中分派一块内存
(3)用WriteProcessMemory函数把DLL的路径名复制到第一步分配的内存中
(4)用GetProcAddress函数来得到LoadLibraryW函数(在Kernel32.dll中)的实际地址
(5)用CreateRemoteThread函数在远程进程中创建一个线程,让新线程调用LoadLibraryW函数并在参数中传入第1步分配的内存地址。这时,DLL已经被注入到远程进程的地址空间中,DLL的DllMain函数会收到DLL_PROCESS_ATTACH通知并且可以执行我们想要执行的代码。当DllMain返回的时候,远程线程会从LoadLibraryW调用返回到BaseThreadStart函数。BaseThreadStart函数然后调用ExitThread,使远程线程终止。

补充:
(1)OpenProcess函数的作用是打开一个已存在的进程对象,并返回进程的句柄
(2)VirtualAllocEx函数的作用是在指定进程的虚拟空间申请内存,执行成功返回分配内存的首地址,不成功返回NULL
(3)WriteProcessMemory函数的作用是在某一进程的内存区域写入数据
(4)GetProcAddress函数的作用是获取DLL导出函数的地址,使用返回的函数指针调用DLL函数
(5)CreateRemoteThread函数的作用是创建一个在其它进程地址空间中运行的线程

示例代码:

BOOL WINAPI InjectLibW(DWORD dwProcessId, PCWSTR pszLibFile) {

    HANDLE hProcess = NULL, hThread = NULL;
    PWSTR pszLibFileRemote = NULL;

    // Get a handle for the target process.
    hProcess = OpenProcess(
        PROCESS_QUERY_INFORMATION |   // Required by Alpha
        PROCESS_CREATE_THREAD     |   // For CreateRemoteThread
        PROCESS_VM_OPERATION      |   // For VirtualAllocEx/VirtualFreeEx
        PROCESS_VM_WRITE,             // For WriteProcessMemory
        FALSE, dwProcessId);
    if (hProcess == NULL) return false;

    // Calculate the number of bytes needed for the DLL's pathname
    int cch = 1 + lstrlenW(pszLibFile);
    int cb  = cch * sizeof(wchar_t);

    // Allocate space in the remote process for the pathname
    pszLibFileRemote = (PWSTR)VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
    if (pszLibFileRemote == NULL) return false;

    // Copy the DLL's pathname to the remote process' address space
    if (!WriteProcessMemory(hProcess, pszLibFileRemote, (PVOID) pszLibFile, cb, NULL)) 
        return false;

    // Get the real address of LoadLibraryW in Kernel32.dll
    PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
    if (pfnThreadRtn == NULL) return false;

    // Create a remote thread that calls LoadLibraryW(DLLPathname)
    hThread = CreateRemoteThread(hProcess, NULL, 0, pfnThreadRtn, pszLibFileRemote, 0, NULL);
    if (hThread == NULL) return false;

    // Wait for the remote thread to terminate
    WaitForSingleObject(hThread, INFINITE);

    // Free the remote memory that contained the DLL's pathname
    if (pszLibFileRemote != NULL) 
        VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);

    if (hThread != NULL) 
        CloseHandle(hThread);

    if (hProcess != NULL) 
        CloseHandle(hProcess);

    return true;
}

 源自《Windows核心编程(第5版)》

posted @ 2013-09-27 16:14  代金桥  阅读(816)  评论(0编辑  收藏  举报