CreatRemoteThread线程注入

 线程注入有很多种方法,有最简单也最方便安全的SetWindowsHookEx的钩子注入,也有代码简洁的远程线程创建注入。


这种方法构思巧妙,但是个人觉得直接硬写目标进程内存空间有一定风险,可谓差之毫厘,谬以千里。本菜鸟这个程序调试了很长时间才成功的,大牛请勿发笑。


CreatRemoteThread从字面意思上不难理解,创建一个远程线程,所以我们可以用他在目标进程中创建一个线程,立即执行。并且将线程的入口地址设置为LoadLibrary函数的入口地址,LoadLibrary只有一个参数,就是动态链接库的绝对地址,我们将这个参数传入就可以调用任意一个我们想要注入的动态链接库,在DllMain函数中放入我们的目标代码就可以实现寄生执行。


这里需要注意的是,我们都知道,进程是一个封闭的空间,里面的所有数据都是私有的,那么这个动态链接库的绝对地址要被这个进程的线程所使用就应该成为这个进程空间中的数据,这也就是关键所在,我们需要先使用VirtualAllocEx进程中的内存空间,然后用WriteProcessMemory将这个参数内容写进进程,这里需要注意任何细节,一点小小错误都会使得目标进程崩溃。


下面我们看看代码:

#include "windows.h"
#include "stdlib.h"
#include "stdio.h"
#include "tlhelp32.h"

DWORD ProcessNameToPID(char Name[20]);//将进程名转化成PID

int main()
{
   DWORD pdwProcessId;
   WCHAR pszLibFileName[MAX_PATH]={0};
   char lpDllFullPathName[MAX_PATH],ProcessName[20];
   HANDLE hRemoteThread,hRemoteProcess;
   PWSTR pszLibFileRemote=NULL;


   printf("请输入进程名称:\n");
   scanf("%s",ProcessName);
   printf("请输入dll地址:\n");
   scanf("%s",lpDllFullPathName);
   MultiByteToWideChar(CP_ACP,MB_ERR_INVALID_CHARS,lpDllFullPathName,strlen(lpDllFullPathName),pszLibFileName,MAX_PATH);
   if((pdwProcessId=ProcessNameToPID(ProcessName))==-1)
	   return 0;


   hRemoteProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pdwProcessId);//打开被注入进程
   if (hRemoteProcess==NULL)
   {
	   printf("OpenProcess Error\n");
	   return 0;
   }
   int cb=(1+lstrlenW(pszLibFileName))*sizeof(WCHAR);
   pszLibFileRemote=(PWSTR)VirtualAllocEx(hRemoteProcess,NULL,cb,MEM_COMMIT,PAGE_EXECUTE_READWRITE);//开辟内存
   if (pszLibFileRemote==NULL)
   {
	   printf("VirtualAllocEx Error\n");
	   return 0;
   }
   if(!WriteProcessMemory(hRemoteProcess,(PVOID)pszLibFileRemote,(PVOID)pszLibFileName,cb,NULL))//将dll模块名称写入被注入进程作为私有变量可供目标进程使用
   {
	   printf("WriteProcessMemory Error  %d\n",GetLastError());
	   return 0;
   }
   PTHREAD_START_ROUTINE pfnStartAddr=(PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("kernel32")),"LoadLibraryW");//获得LoadLibraryW地址
   if(pfnStartAddr==NULL)
   {
	   printf("pfnStartAddr Error\n");
   }
   //创建远程线程,线程回调函数就是LoadLibraryW,pszLibFileRemote中的dll路径作为LoadLibraryW的唯一参数传入
   hRemoteThread=CreateRemoteThread(hRemoteProcess,NULL,0,pfnStartAddr,pszLibFileRemote,0,NULL);
   if (hRemoteThread==NULL)
   {
	   printf("CreatRemoteThread Error\n");
	   return 0;
   }
   return 1;
}


DWORD ProcessNameToPID(char Name[20]) //进程遍历就不用多说了把,方法多的是
{
	PROCESSENTRY32 pe32;

	pe32.dwSize=sizeof(pe32);
	HANDLE hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0)	;
	if(hProcessSnap==INVALID_HANDLE_VALUE)
	{
		printf("CreateToolhelp32Snapshot fuild!\n");
		return -1;
	}
	BOOL bMore=Process32First(hProcessSnap,&pe32);
	while(bMore)
	{
		if (!strcmp(Name,pe32.szExeFile))
		{
			printf("find it %d\n",pe32.th32ProcessID);
			return pe32.th32ProcessID;
		}
		bMore=Process32Next(hProcessSnap,&pe32);

	}

	CloseHandle(hProcessSnap);
	return -1;	
}


下面是被注入进程的动态链接库代码,只输出一个MessageBox,“这是个测试程序!”:

#include "windows.h"

BOOL APIENTRY DllMain(HANDLE hMoudle,DWORD reason,LPVOID lpReserved)
{
	switch(reason)
	{
	case DLL_PROCESS_ATTACH:
		MessageBox(NULL,"this is a test!","Success",MB_OK);
		break;
	default:
		return TRUE;
	}
}


下面是运行效果,我写了个界面:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值