您的位置:首页 > 编程语言 > C语言/C++

使用C++中CreateRemoteThread进行线程注入

2015-05-29 08:58 453 查看

#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <Tlhelp32.h>

HANDLE CreateRemoteThreadProc(char* ProcessName);
DWORD WINAPI WatchThread(LPVOID lparam);
DWORD WINAPI remote(LPVOID pvparam);
DWORD processtopid(char *processname);
BOOL EnablePriv();
HANDLE MyCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE pThreadProc, LPVOID pRemoteBuf);
BOOL IsVistaOrLater();
//先打开notepad,在运行本程序

typedef struct _remoteparameter
{
DWORD rpWaitForSingleObject;
DWORD rpOpenProcess;
DWORD rpWinExec;
DWORD rpProcessPID;
HANDLE rpProcessHandle;
char path[MAX_PATH];
}REMOTEPARAM;

typedef DWORD (WINAPI *PFNTCREATETHREADEX)
(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
BOOL CreateSuspended,
DWORD dwStackSize,
DWORD dw1,
DWORD dw2,
LPVOID Unknown
);

int main(int argc, char* argv[])
{
HANDLE RemoteThreadHandle;
HANDLE LocateThreadHandle;
EnablePriv();
RemoteThreadHandle=CreateRemoteThreadProc("notepad.exe");
//本地线程循环注入notepad
LocateThreadHandle=CreateThread(NULL,NULL,WatchThread,(LPVOID)RemoteThreadHandle,NULL,NULL);
WaitForSingleObject(LocateThreadHandle,INFINITE);
WaitForSingleObject(RemoteThreadHandle,INFINITE);//线程等待,循环等待notepad的远程线程执行完毕。即 notepad关闭本程序才关闭
return 0;
}
//创建远程线程,线程注入
HANDLE CreateRemoteThreadProc(char* ProcessName)
{
HANDLE ThreadHandle;
char FilePath[MAX_PATH];

GetModuleFileName(NULL,FilePath,MAX_PATH);//得到文件所在路径
printf("%s\n",FilePath);
//根据进程名获取进程ID
int procID=processtopid(ProcessName);
printf("The process pid is %d\n",procID);
HINSTANCE hkernel32;
HANDLE rphandle;
char *remotethr;
char *remotepar;
int cb;
//根据ID打开notepad的进程空间
rphandle=OpenProcess(PROCESS_ALL_ACCESS, FALSE,procID);
if(rphandle==NULL)
{
printf("Open Remote Process is Error\n");
}
else
{
printf("open process is ok\n");
}

/*****************************************************************/
/*将远程线程函数代码拷入目标进程*/
/*****************************************************************/
cb=sizeof(TCHAR)*4*1024;
//在notepad进程中分配空间,存储函数remote
remotethr=(PTSTR)VirtualAllocEx(rphandle,NULL,cb,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if(remotethr==NULL)
{
printf("VirtualAllocEx for Thread Error\n");
CloseHandle(rphandle);
}
else
printf("VirtualAllocEx is ok\n");
//往notepad空间中写入数据指针remote指向的数据,大小为cb
if(WriteProcessMemory(rphandle,remotethr,(LPVOID)remote,cb,NULL)==FALSE)
{
printf("WriteProcessMemory for Thread Error\n");
CloseHandle(rphandle);
}
else
printf("WriteProcessMemory is ok\n");

/*****************************************************************/
/*将远程线程函数参数拷入目标进程*/
/*这里需要重定位远程线程需要的API*/
/*****************************************************************/
REMOTEPARAM rp;
memset((char*)&rp,0,sizeof(rp));

hkernel32=GetModuleHandle("kernel32.dll");

if(hkernel32==NULL)
{
printf("hKernel32 is Error\n");
}
//通过让目标进程执行OpenProcess,WinExec,WaitForSingleObject,函数重新打开本程序

rp.rpProcessPID =GetCurrentProcessId();
rp.rpOpenProcess =(DWORD)GetProcAddress(hkernel32,"OpenProcess");
rp.rpWinExec =(DWORD)GetProcAddress(hkernel32,"WinExec");
rp.rpWaitForSingleObject=(DWORD)GetProcAddress(hkernel32,"WaitForSingleObject");
strcpy_s(rp.path,FilePath);
cb=sizeof(char)*sizeof(rp);
//rphandle指向notepad进程,分配空间,存储参数
remotepar=(PTSTR)VirtualAllocEx(rphandle,NULL,cb,MEM_COMMIT,PAGE_READWRITE);
if(remotepar==NULL)
{
printf("VirtualAllocEx for Parameter Error\n");
CloseHandle(rphandle);
}
//往notepad进程写入传给remote的参数
if(WriteProcessMemory(rphandle,remotepar,(LPVOID)&rp,cb,NULL)==FALSE)
{
printf("WriteProcessMemory for Parameter Error\n");
CloseHandle(rphandle);
}

/*****************************************************************/
/*将远程线程注入目标进程*/
/*****************************************************************/
//在noetpad进程中创建新线程执行remote函数,参数为remotepar,返回线程句柄
ThreadHandle=MyCreateRemoteThread(rphandle,(LPTHREAD_START_ROUTINE)remotethr,(LPVOID)remotepar);

if(ThreadHandle==NULL)
{
printf("CreateRemotThreadHandle Error\n");
CloseHandle(rphandle);
}
else
printf("CreateRemotThreadHandle is ok\n");

return ThreadHandle;
}
//获取进程ID
DWORD processtopid(char *processname)
{
// 变量及初始化
STARTUPINFO st;
PROCESS_INFORMATION pi;
PROCESSENTRY32 ps;
HANDLE hSnapshot;
DWORD procID;
memset(&st,0,sizeof(st));
memset(&pi,0,sizeof(pi));
st.cb = sizeof(STARTUPINFO);
memset(&ps,0,sizeof(ps));
ps.dwSize = sizeof(PROCESSENTRY32);
// 遍历进程
hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0);
if(hSnapshot == INVALID_HANDLE_VALUE)
{
return FALSE;
}

if(!Process32First(hSnapshot,&ps))
{
return FALSE;
}
do
{
// 比较进程名
if(lstrcmpi(ps.szExeFile,processname)==0)
{
// 找到了
procID=ps.th32ProcessID;
CloseHandle(hSnapshot);
return procID;
}
}
while(Process32Next(hSnapshot,&ps));
// 没有找到
CloseHandle(hSnapshot);
return 0;
}
//提升进程权限
BOOL EnablePriv()
{
HANDLE hToken;
if ( OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken) )
{
TOKEN_PRIVILEGES tkp;

LookupPrivilegeValue( NULL,SE_DEBUG_NAME,&tkp.Privileges[0].Luid ); //修改进程权限
tkp.PrivilegeCount=1;
tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges( hToken,FALSE,&tkp,sizeof tkp,NULL,NULL ); //通知系统修改进程权限
}
return 0;
}
//远程线程要执行的函数
DWORD WINAPI remote(LPVOID pvparam)
{
REMOTEPARAM *rp=(REMOTEPARAM*)pvparam;

typedef UINT (WINAPI *EWinExec) (LPCSTR, UINT);
typedef HANDLE (WINAPI *EOpenProcess) (DWORD, BOOL, DWORD);
typedef DWORD (WINAPI *EWaitForSingleObject) (HANDLE, DWORD);


EWinExec tWinExec;
EOpenProcess tOpenProcess;
EWaitForSingleObject tWaitForSingleObject;


tOpenProcess =(EOpenProcess)rp->rpOpenProcess;
tWaitForSingleObject =(EWaitForSingleObject)rp->rpWaitForSingleObject;
tWinExec =(EWinExec)rp->rpWinExec;

// 重新打开本进程ID,使本进程可以访问
rp->rpProcessHandle=tOpenProcess(PROCESS_ALL_ACCESS,FALSE,rp->rpProcessPID);

tWaitForSingleObject(rp->rpProcessHandle,INFINITE);
//打开本程序
tWinExec(rp->path, SW_SHOW);
return 0;
}
//守护进程
DWORD WINAPI WatchThread(LPVOID lparam)
{
HANDLE RemoteThreadHandle=(HANDLE)lparam;
DWORD ExitCode;

GetExitCodeThread(RemoteThreadHandle,&ExitCode);

while(true)
{
if(ExitCode!=STILL_ACTIVE)//如果远程线程不激活,就重新激活
{
printf("RemoteThreadHandle is over\n");
RemoteThreadHandle=CreateRemoteThreadProc("notepad.exe");
}
Sleep(3000);
}
return 0;
}

HANDLE MyCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE pThreadProc, LPVOID pRemoteBuf)
{
HANDLE hThread = NULL;
FARPROC pFunc = NULL;
if( IsVistaOrLater() ) // Vista, 7, Server2008
{
pFunc = GetProcAddress(GetModuleHandle("ntdll.dll"), "NtCreateThreadEx");
if( pFunc == NULL )
{
printf("MyCreateRemoteThread() : GetProcAddress(\"NtCreateThreadEx\") 调用失败!错误代码: [%d]/n",
GetLastError());
return FALSE;
}
((PFNTCREATETHREADEX)pFunc)(&hThread,
0x1FFFFF,
NULL,
hProcess,
pThreadProc,
pRemoteBuf,
FALSE,
NULL,
NULL,
NULL,
NULL);
if( hThread == NULL )
{
printf("MyCreateRemoteThread() : NtCreateThreadEx() 调用失败!错误代码: [%d]/n", GetLastError());
return FALSE;
}
}
else // 2000, XP, Server2003
{
hThread = CreateRemoteThread(hProcess,
NULL,
0,
pThreadProc,
pRemoteBuf,
0,
NULL);
if( hThread == NULL )
{
printf("MyCreateRemoteThread() : CreateRemoteThread() 调用失败!错误代码: [%d]/n", GetLastError());
return FALSE;
}
}
if( WAIT_FAILED == WaitForSingleObject(hThread, INFINITE) )
{
printf("MyCreateRemoteThread() : WaitForSingleObject() 调用失败!错误代码: [%d]/n", GetLastError());
return FALSE;
}
return hThread;

}

BOOL IsVistaOrLater()
{
OSVERSIONINFO osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi);
if( osvi.dwMajorVersion >= 6 )
return TRUE;
return FALSE;

}

[size=large][color=orange]上面代码要编译为Release版本才能运行,如果编译为Debug版本在远程方法注入会出现内存读取错误,导致目标进程崩溃.[/color][/size]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: