用远程线程技术实现DLL注入

以下摘自《Windows编程循序渐进》--张静盛

使用CreateRemoteThread可以为其它进程创建线程,可以用于以线程形式执行一段存在于目标进程地址空间的代码。

使用远程线程的三个条件:

1. 确保当前进程有足够的权限可以使用OpenProcess打开目标进程。

2. 线程过程函数存在于目标地址空间。

3. 待执行的函数过程的原型必须符合如 DWORD WINAPI ThreadProc(LPVOID lpParameter);

示例程序:(以线程形式执行目标进程的LoadLibraryA函数)

// RemoteThread.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <windows.h>
#include <string>
#include "stdio.h"
#include <iostream>
using namespace std;

#define DEF_BUF_SIZE 1024

// 用于存储注入模块DLL的路径全名
char szDllPath[DEF_BUF_SIZE] = {0} ;

// 使用远程线程向指定ID的进程注入模块
BOOL InjectModuleToProcessById ( DWORD dwProcessId )
{
	if ( dwProcessId == 0 )
		return FALSE ;

	// 打开进程
	HANDLE hProcess = OpenProcess ( PROCESS_ALL_ACCESS, FALSE, dwProcessId ) ;
	if ( hProcess == NULL )
		return FALSE ;

	//申请存放文件名的空间
	UINT	nLen = (UINT)strlen ( szDllPath ) + 1;
	LPVOID	lpRemoteDllName = VirtualAllocEx ( hProcess, NULL, nLen, MEM_COMMIT, PAGE_READWRITE ) ;
	if ( lpRemoteDllName == NULL )
	{
		printf ( "[ERROR]VirtualAllocEx(%d)\n", GetLastError() ); 
		return FALSE ;
	}

	//把dll文件名写入申请的空间
	if ( WriteProcessMemory ( hProcess, lpRemoteDllName, szDllPath, nLen, NULL) == FALSE )
	{
		printf ( "[ERROR]WriteProcessMemory(%d)\n", GetLastError() ); 
		return FALSE ;
	}

	//获取动态链接库函数地址
	HMODULE hModule = GetModuleHandle ( L"kernel32.dll" ) ;
	LPTHREAD_START_ROUTINE fnStartAddr = ( LPTHREAD_START_ROUTINE )GetProcAddress(hModule,"LoadLibraryA") ;
	if ( (DWORD)fnStartAddr == 0 )
	{
		printf ( "[ERROR]GetProcAddress(%d)\n", GetLastError() ); 
		return FALSE ;
	}

	//创建远程线程
	HANDLE hRemoteThread = CreateRemoteThread ( hProcess, NULL, 0,fnStartAddr, lpRemoteDllName, 0, NULL ) ;
	if ( hRemoteThread == NULL )
	{
		printf ( "[ERROR]CreateRemoteThread(%d)\n", GetLastError() ); 
		return FALSE ;
	}

	// 等待远程线程结束
	if ( WaitForSingleObject ( hRemoteThread, INFINITE ) != WAIT_OBJECT_0 )
	{
		printf ( "[ERROR]WaitForSingleObject(%d)\n", GetLastError() ); 
		return FALSE ;
	}

	CloseHandle ( hRemoteThread ) ;
	CloseHandle ( hModule ) ;
	CloseHandle ( hProcess ) ;
	return TRUE ;
}

int _tmain(int argc, _TCHAR* argv[])
{
	// 取得当前工作目录路径
	GetCurrentDirectoryA ( DEF_BUF_SIZE, szDllPath ) ;

	// 生成注入模块DLL的路径全名
	strcat ( szDllPath, "\\DLLSample.dll" ) ;

	DWORD dwProcessId = 0 ;
	// 接收用户输入的目标进程ID
	while ( printf ( "请输入目标进程ID:" ) && cin >> dwProcessId && dwProcessId > 0 ) 
	{
		BOOL bRet = InjectModuleToProcessById ( dwProcessId ) ;
		printf ( bRet ? "注入成功!\n":"注入失败!\n") ;
	}
	return 0;
}

总结以上代码,可以看出远程线程注入主要分为以下几个步骤:

①OpenProcess打开目标进程;

②VirtualAllocEx在目标进程内分配一段内存用于存放所要注入的Dll的路径;

③WriteProcessMemory将dll路径写入目标进程分配的内存;

④在本进程内找到LoadLibraryA函数的地址;

⑤在本进程内给目标进程内创建远程线程,线程函数为LoadLibraryA函数,参数为目标进程内分配的内存的地址,其中存放着所要注入DLL的路径;

⑥在本进程内等待远程进程结束,WaitForSingleObject。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值