`
冤大头_718
  • 浏览: 23897 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

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

    博客分类:
  • C++
阅读更多
#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;  

}

上面代码要编译为Release版本才能运行,如果编译为Debug版本在远程方法注入会出现内存读取错误,导致目标进程崩溃.
分享到:
评论

相关推荐

    vb6的dll线程注入示例,CreateRemoteThread ,GetProcAddress

    VB的dll注入示例,2020202020202020

    DLL注入之远线程方式

    使用插入到目标进程中的远程线程将该DLL插入到目标进程的地址空间,即利用该线程通过调用Windows API LoadLibrary函数来加载DLL,从而实现获取目标进程空间的使用权。如下摘自ReactOS 3.14的代码所示,...

    CreateRemoteThread注入API函数代码

    原理:1,查找目标进程号,打开远程空间 2,在目标进程申请代码控件、参数空间 3,CreateRemoteThread执行远端线程

    DLL远线程注入Demo 源码

    枚举目标进程ID,利用CreateRemoteThread的方式对目标进程进行注入,另其执行一个DLL中的函数

    代码注入的三种方法

    将代码注入不同的进程地址空间,然后在该进程的上下文中执行注入的代码。本文将介绍三种方法: 1、Windows 钩子 2、CreateRemoteThread 和 LoadLibrary 技术 ——进程间通信 3、CreateRemoteThread 和...

    远程线程注入.rar_VirtualAllocEx_dll卸载_riverlpg_skill1bc_远程

    使用CreateRemoteThread和LoadLibrary把你的DLL映射近远程进程。 //5. 等待远程线程结束(WaitForSingleObject),即等待LoadLibrary返回。也就是说当我们的DllMain(是以DLL_PROCESS_ATTACH为参数调用的)返回时...

    CreateRemoteThread 使用,源代码例子,还有说明。

    CreateRemoteThread 使用,源代码例子,还有说明。

    CreateRemoteThread DLL源码

    C++编写的DLL C#程序调用 远程线程执行DLL注入

    远程注入 实例源码

    如今远线程注入已经是泛滥成灾,杀毒软件对于远程线程已经做了检查和警示。 此代码对初学者了解远程注入起到学习的作用。 远程注入方式: 使用CreateRemoteThread注入 使用apc QueueUserApc方式

    易语言创建远程线程

    易语言创建远程线程源码,创建远程线程,CALL,GetProcessID,OpenProcess,VirtualAllocEx,WriteProcessMemoryByte,CreateRemoteThread,WaitForSingleObject,CreateToolhelp32Snapshot,Process32Next,Process32First,...

    动态加载驱动程序源代码

    源代码包含三种不同的驱动加载方法,使用ZwSetSystemInformation函数加载驱动,使用NtLoadDriver函数加载...函数注入线程,使用CreateRemoteThread函数注入线程,使用NtCreateThreadEx函数注入线程,源代码包含C,C#的demo

    C++实现dll注入其它进程

     DLL注入技术才具有强大的功能和使用性,同时简单易用,因为DLL中可以实现复杂的功能和很多的技术。  技术要点:  1、宿主进程调用LoadLibrary,可以完成DLL的远程注入。可以通过CreateRemoteThread将...

    DLL注入实例+教程

    这里介绍一种用 CreateRemoteThread 远程建立线程的方式注入DLL. 首先,我们要提升自己的权限,因为远程注入必不可免的要访问到目标进程的内存空间,如果没有足够的系统权限,将无法作任何事.下面是这个函数是...

    线程守护实例 远程线程 木马常用技术 VC6.0

    线程守护实例 远程线程 木马常用技术 VC6.0 CreateRemoteThread

    RemoteCall

    利用远程线程注入DLL 1)、取得远程进程的进程ID;... 5)、调用CreateRemoteThread函数以从Kernel32.dll中取得的LoadLibrary函数的地址为线程函数的地址,以我们要注入的DLL文件名为参数,创建远程线程;

    WinCodeInjection:Dll注入和代码注入示例

    WinCode注入 此存储库包含 2 个示例: 带有要注入的 Dll 的 Dll Injector 代码注入器 Dll Injector 示例使用未公开的函数... 在本示例中,我使用简单的CreateRemoteThread在另一个进程中插入自定义函数。

    hook_delphi_remote_createremotethread_hook_

    create remote thread

    EDA/PLD中的用Visual C++实现远程线程嵌入技术

    但是很少有人知道,通过CreateRemoteThread也同样可以在另一个进程内创建新线程,被创建的远程线程同样可以共享远程进程(是远程进程耶!)的地址空间,所以,实际上,我们通过一个远程线程,进入了远程进程的内存...

    用Visual C++实现远程线程嵌入技术

    但是很少有人知道,通过CreateRemoteThread也同样可以在另一个进程内创建新线程,被创建的远程线程同样可以共享远程进程(是远程进程耶!)的地址空间,所以,实际上,我们通过一个远程线程,进入了远程进程的内存...

    Python-DLL-Injector:用Python编写的没有依赖项的DLL注入器

    当前仅使用LoadLibraryA和CreateRemoteThread支持最基本的DLL注入样式。 根据您使用64位还是32位运行此命令,Python会更改您可能注入的进程。怎么跑只需克隆存储库并使用python main.py运行,因为没有其他依赖项。

Global site tag (gtag.js) - Google Analytics