UserMode下的远程线程注入

这是基础注入中的一种
    利用 CreateRemoteThead 的线程回调函数与 LoadLibrary的函数格式近似的格式,将Dll加载到目标进程来完成注入,再通过 GetExitCodeThread 函数来获取Dll在进程中的句柄
DWORD WINAPI PTHREAD_START_ROUTINE_FUN(
    LPVOID lpThreadParameter
    );

HMODULE WINAPI LoadLibraryA(
    _In_ LPCSTR lpLibFileName

    );

R3注入程序代码

//************************************
// 名称: RemoteThreadInjectDll
// 作用: 远程注入
// 继承: public
// 返回: DWORD
// 参数: DWORD ProcessPid 要注入的进程PID
// 参数: DWORD DllName 要注入的模块名称
//************************************
DWORD RemoteThreadInjectDll(HANDLE hProcess, WCHAR * DllName)
{
    DWORD Pid = NULL, TrueLen = NULL;
    WCHAR * szDllName = DllName; // 为loadlibrary所需要的参数
 
    // 在远程进程中申请空间
    LPVOID DllSpace = VirtualAllocEx(hProcess/*申请内存所在的进程句柄*/,
        NULL/*保留页面的内存地址,一般用NULL自动分配*/, 4096/*分配内存的大小*/,
        MEM_COMMIT/*为特定的页面区域分配内存中或磁盘中的页面文件中的物理存储*/,
        PAGE_EXECUTE_READWRITE/*内存模块可写可执行*/);
    if (NULL == DllSpace)
    {
        return MessageBox(0, L"申请内存空间失败", L"提示", MB_OK);
    }
 
    // 注入线程函数参数
    if (!WriteProcessMemory(hProcess/*由OpenProcess返回的进程句柄*/,
        DllSpace/*要写的内存首地址,在写入之前,此函数将先检查目标地址是否可用,并能容纳待写入的数据。*/,
        szDllName/*要写入数据的首地址*/, MAX_PATH/*要写入的字节数,非零值代表成功。*/,
        &TrueLen/*实际写入的长度*/))
    {
        return MessageBox(0, L"注入线程函数参数失败", L"提示", MB_OK);
    }
 
    // 远程线程创建,设置线程函数的地址
    HANDLE longthread = CreateRemoteThread(hProcess/*句柄*/, NULL/*安全属性*/, 0/*栈大小*/,
        (LPTHREAD_START_ROUTINE)LoadLibraryW/*线程处理函数, 此函数必须存在目标进程中*/,
        DllSpace/*参数*/, NULL/*默认创建后的状态*/, NULL/*线程ID*/);
    if (NULL == longthread)
    {
        return MessageBox(0, L"远程线程创建失败", L"提示", MB_OK);
    }
 
    // 等待线程函数的结束
    DWORD flag = WaitForSingleObject(longthread/*等待的线程句柄*/, INFINITE/*对象被触发信号后,函数才会返回*/);
 
    // 获取线程退出码,即LoadLibrary的返回值,即dll的首地址
    DWORD dwExitCode = NULL;
    GetExitCodeThread(longthread, &dwExitCode);
    HMODULE hMod = (HMODULE)dwExitCode;
 
    // 释放为DLL名字申请的空间
    if (NULL == VirtualFreeEx(hProcess/*目标进程的句柄。该句柄必须拥有 PROCESS_VM_OPERATION 权限*/,
        DllSpace/*指向要释放的虚拟内存空间首地址的指针*/,
        4096/*虚拟内存空间的字节数*/,
        MEM_DECOMMIT/*内存空间不可用,内存页还将存在*/))
    {
    return MessageBox(0, L"释放为DLL名字申请的空间失败", L"提示", MB_OK);
    }
}


原创文章,转载请注明: 转载自Windows内核安全驱动编程

本文链接地址: UserMode下的远程线程注入

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注