线程注入

来源:互联网 发布:linux下qt串口通信 编辑:程序博客网 时间:2024/05/16 09:08

下面是一段线程注入的源代码.写在这边,以后用起来方便.

要说这线程注入也就几个步骤.

1).获取宿主进程句柄

2).在宿主进程空间中申请地址空间

3).将预载入线程体写入宿主进程中

4).在宿主进程中创建线程.

这4个步骤就是进行线程注入的一般步骤.这里面当然也可以载入动态链接库.

这里还有一点需要说明:

每一个用户进程都有它自己私有的地址空间,也就是可以被那个进程访问的内存集合的区域.一个用户进程不可以直接访问另外一个用户进程的地址空间.属于用户进程的线程运行在用户级权限.

#include <windows.h>
#include <TlHelp32.h>
#include <iostream>
//#include "stdafx.h"

typedef struct _RemoteParam {
    char szMsg[12];    //MessageBox函数中显示的字符提示
    DWORD dwMessageBox;//MessageBox函数的入口地址
} RemoteParam, * PRemoteParam;

typedef int (__stdcall * PFN_MESSAGEBOX)(HWND, LPCTSTR, LPCTSTR, DWORD);

//根据进程名称得到进程的ID,如果有多个实例在同时运行的话,只返回第一个枚举到的进程ID
DWORD processNameToId(LPCTSTR lpszProcessName)
{
   HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//为系统中所有进程建立一个快照
   PROCESSENTRY32 pe;
   pe.dwSize = sizeof(PROCESSENTRY32);

   if (!Process32First(hSnapshot, &pe))//进程获取函数,获取进程句柄
   {
       MessageBox(NULL,
           "The frist entry of the process list has not been copyied to the buffer",
           "Notice", MB_ICONINFORMATION | MB_OK);
       return 0;
   }

    while (Process32Next(hSnapshot, &pe)) //进程获取函数,获取下一个进程句柄
 {
        if (!strcmp(lpszProcessName, pe.szExeFile)) //如果找到该进程,则记录其进程ID
  {
            return pe.th32ProcessID;
        }
    }
 
    return 0;
}


//要插入宿主进程中的线程函数
DWORD __stdcall threadProc(LPVOID lParam)
{
    RemoteParam* pRP = (RemoteParam*)lParam;
 
    PFN_MESSAGEBOX pfnMessageBox;
    pfnMessageBox = (PFN_MESSAGEBOX)pRP->dwMessageBox;
    pfnMessageBox(NULL, pRP->szMsg, pRP->szMsg, 0);
// TerminateProcess(GetCurrentProcess(),NULL);
    return 0;
}

bool enableDebugPriv()
{
    HANDLE hToken;
    LUID sedebugnameValue;
    TOKEN_PRIVILEGES tkp;
 
    if (!OpenProcessToken(GetCurrentProcess(),
        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
        return false;
    }

    if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue)) {
        CloseHandle(hToken);
        return false;
    }

    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = sedebugnameValue;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL)) {
        CloseHandle(hToken);
        return false;
    }

    return true;
}


int main(int argc, char* argv[])
{
    const DWORD dwThreadSize = 4096;
    DWORD dwWriteBytes;
 enableDebugPriv();

    std::cout << "Please input the name of target process" << std::endl;
    char szExeName[MAX_PATH] = { 0 };
    //等待输入宿主进程名称
    std::cin >> szExeName;
 
    //得到指定名称进程的进程ID,如果有多个进程实例,则得到第一个进程ID
    DWORD dwProcessId = processNameToId(szExeName);//根据进程名称,得到进程ID
    HANDLE hTargetProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);//打开一个已存在的进程对象。
    if (!hTargetProcess)
 {
        MessageBox(NULL, "Open target process failed !",
            "Notice", MB_ICONINFORMATION | MB_OK);
        return 0;
    }
 void* pRemoteThread = VirtualAllocEx(hTargetProcess, 0,
    dwThreadSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);//在宿主进程中申请一块存储区域
    //把线程体写入宿主进程中
    if (!WriteProcessMemory(hTargetProcess,
        pRemoteThread, &threadProc, dwThreadSize, 0))
 {
        MessageBox(NULL, "Write data to target process failed !",
            "Notice", MB_ICONINFORMATION | MB_OK);
        return 0;
    }
 
 //定义线程参数结构体变量
    RemoteParam remoteData;
    ZeroMemory(&remoteData, sizeof(RemoteParam));
 
 //填充结构体变量中的成员
 HINSTANCE hUser32 = LoadLibrary("User32.dll");
    remoteData.dwMessageBox = (DWORD)GetProcAddress(hUser32, "MessageBoxA");
    strcat(remoteData.szMsg, "Hello/0");
 
 //为线程参数在宿主进程中开辟存储区域
 RemoteParam* pRemoteParam = (RemoteParam*)VirtualAllocEx(
    hTargetProcess , 0, sizeof(RemoteParam), MEM_COMMIT, PAGE_READWRITE);
 
    if (!pRemoteParam) {
        MessageBox(NULL, "Alloc memory failed !",
            "Notice", MB_ICONINFORMATION | MB_OK);
        return 0;
    }
 
 //将线程参数拷贝到宿主进程地址空间中
    if (!WriteProcessMemory(hTargetProcess ,
            pRemoteParam, &remoteData, sizeof(remoteData), 0))
 {
        MessageBox(NULL, "Write data to target process failed !",
            "Notice", MB_ICONINFORMATION | MB_OK);
        return 0;
    }
    //在宿主进程中创建线程
    HANDLE hRemoteThread = CreateRemoteThread(
        hTargetProcess, NULL, 0, (DWORD (__stdcall *)(void *))pRemoteThread,
        pRemoteParam, 0, &dwWriteBytes);
    if (!hRemoteThread)
 {
        MessageBox(NULL, "Create remote thread failed !", "Notice", MB_ICONSTOP);
        return -1;
    }
 CloseHandle(hRemoteThread);
    return 0;