找回密码
 立即注册
首页 业界区 业界 远程线程注入引出的问题

远程线程注入引出的问题

云卦逾 2025-5-29 16:15:32
远程线程注入引出的问题

 


一、远程线程注入基本原理
远程线程注入——相信对Windows底层编程和系统安全熟悉的人并不陌生,其主要核心在于一个Windows API函数CreateRemoteThread,通过它可以在另外一个进程中注入一个线程并执行。在提供便利的同时,正是因为如此,使得系统内部出现了安全隐患。常用的注入手段有两种:一种是远程的dll的注入,另一种是远程代码的注入。后者相对起来更加隐蔽,也更难被杀软检测。本文具体实现这两种操作,在介绍相关API使用的同时,也会解决由此引发的一些问题。
顾名思义,远程线程注入就是在非本地进程中创建一个新的线程。相比而言,本地创建线程的方法很简单,系统API函数CreateThread可以在本地创建一个新的线程,其函数声明如下:
HANDLE WINAPI CreateThread(
    LPSECURITY_ATTRIBUTES lpThreadAttributes,
    SIZE_T dwStackSize,
    LPTHREAD_START_ROUTINE lpStartAddress,
    LPVOID lpParameter,
    DWORD dwCreationFlags,
    PDWORD lpThreadId
    );
这里最关心的两个参数是lpStartAddresslpParameter,它们分别代表线程函数的入口和参数,其他参数一般设置为0即可。由于参数的类型是LPVOID,因此传入的参数数据需要用户自己定义,而入口函数地址类型必须是LPTHREAD_START_ROUTINE类型。LPTHREAD_START_ROUTINE类型定义为:
typedef DWORD (WINAPI *PTHREAD_START_ROUTINE)(LPVOID lpThreadParameter);
typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE;


    按照上述定义声明的函数都可以作为线程函数的入口,和CreateThread类似,CreateRemoteThread的声明如下:  HANDLE WINAPI CreateRemoteThread(
    HANDLE hProcess,
    LPSECURITY_ATTRIBUTES lpThreadAttributes,
    SIZE_T dwStackSize,
    LPTHREAD_START_ROUTINE lpStartAddress,
    LPVOID lpParameter,
    DWORD dwCreationFlags,
    LPDWORD lpThreadId
    );


    可见该函数就是比CreateThread多了一个参数用于传递远程进程的打开句柄,而我们知道打开一个进程需要函数OpenProcess,其函数声明为: HANDLE WINAPI OpenProcess(
    DWORD dwDesiredAccess,
    BOOL bInheritHandle,
    DWORD dwProcessId
    );
    第一个参数表示打开进程所要的访问权限,一般使用PROCESS_ALL_ACCESS来获得所有权限,第二个参数表示进程的继承属性,这里设置为false,最关键的参数是第三个参数——进程的ID。因此在此之前必须获得进程名字和PID的对应关系,TlHelp32.h库内提供的函数CreateToolhelp32SnapshotProcess32FirstProcess32Next提供了对当前进程的遍历访问,使用这里有段公用代码可以使用:

//获取进程name的ID
DWORD getPid(LPTSTR name)
{
    HANDLE hProcSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//获取进程快照句柄
    assert(hProcSnap!=INVALID_HANDLE_VALUE);
    PROCESSENTRY32 pe32;
    pe32.dwSize=sizeof(PROCESSENTRY32);
    BOOL flag=Process32First(hProcSnap,&pe32);//获取列表的第一个进程
    while(flag)
    {
        if(!_tcscmp(pe32.szExeFile,name))
        {
            CloseHandle(hProcSnap);
            return pe32.th32ProcessID;//pid
        }
        flag=Process32Next(hProcSnap,&pe32);//获取下一个进程
    }
    CloseHandle(hProcSnap);
    return 0;
}



    因此,按照以上的方式,使用getpid获取指定名称进程pid,传入OpenProcess打开进程获取进程句柄。但是你会发现这时候进程是无法打开的,或者说进程不能以完全访问的权限打开,因此必须提高本地程序的权限,这是远程注入线程引发的第一个问题,这里也有一段通用代码: //提升进程权限
int EnableDebugPrivilege(const LPTSTR name)
{
    HANDLE token;
    TOKEN_PRIVILEGES tp;
    //打开进程令牌环
    if(!OpenProcessToken(GetCurrentProcess(),
        TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&token))
    {
        cout
您需要登录后才可以回帖 登录 | 立即注册