【外挂编程】外挂编程技术揭秘(三)DLL注入

3 篇文章 13 订阅
3 篇文章 4 订阅

引言:

一个礼拜没有更新这个主题文章了,这周三看到一个微信推送。某某某博士由于写外挂被抓。当时心里那是一个崩溃,不过之前写了这个主题,还是会继续写完,不能半途而废。不过了解这本技术的千万不要拿去捞偏门。我刚写这篇文章的时候在想这个主题要不要改一改。叫《我们一起写外挂吧,会被抓那种》,^ - ^,玩笑了。开始我们今天的内容吧,我们还是继续讲内存挂,不过我们今天的主题是讲注入。

文中介绍的注入形式都会有一个小例子。

代码地址:

https://github.com/Diamonds-ZhaoYu/hz_example

 

开篇

所谓的dll注入,其实就是在dll注入到另外一个程序地址空间。然后该程序会把这个dll作为动态链接库调用,视为程序的一部分。

dll注入有很多种形式可以注入:apc注入、message注入、注册列表注入、远程线程注入、输入法注入、LSP劫持注入。

 

(一)apc注入:

在一个进程执行过程中、调用SleepEx或者WaitForSingleObjectEx函数时、系统会产生软中断。这时候线程在次被唤醒时、此线程会首先执行apc队列中被注册的函数、利用QueueUserAPC这个函数、并且去执行我们的dll加载代码 ,进而完成我们注入dll的目的。 (二)message注入: message注入其实就是windows消息钩子钩子注入、SetWindowsHook函数是windows消息处理机制的一个平台、应用程序可以指定监视指定窗口的某种消息。它可以拦截进程的消息到指定的dll中导出函数、这个特性我们就可以将dll注入到程序中。

 

(三)注册列表注入:

在进程中每一个进程加载user32.dll时、会受到DLL_PROCESS_ATTACH通知。在进行处理时、会取到注册列表键值HKEY_LOCAL_MACHINE\Software\Microsoft\windowsNT\CurrentVresion\Windows\AppInit_Dlls,并且会调用LoadLibrary去加载dll、若将参数值fdwReason设置为DLL_PROCESS_ATTACH时对自己会初始化。这样我们去加键值就会加载我们的dll、实现注入。

(四)远程线程注入 远程线程注入是window病毒用的广泛的一种、远程线程注入其实比较简单其实就是利用CreateRemoteThread函数创建远程线程调用LoadLibrary去加载我们我们的dll,实现注入。远程线程注入在之前的QQ尾巴病毒就是利用这个,还有多,如果有兴趣我们可以写一个类似的小程序。

 

(五)输入法注入:

输入法注入原理是利用系统切换输入法时、需要输入字符。系统会把这个输入法所需要的ime文件加载到进程中、而且利用ime文件只存放在C:盘window目录中的system32目录中的特殊dll、因此我们可以利用这个特性调用LoadLibrary加载自己的dll文件、实现注入。

 

(六)LSP劫持注入

其实这个是利用windows程序加载自己目录的dll特性,伪造系统的dll,然后在我们的dll内去调用系统原来的函数。进而实现劫持注入到程序,这样我们就可以为所欲为。

 

源码解析:

注入程序:

注入程序主要目的就是远程注入DLL到被注入进程中,被注入进程在这里可以是我们的游戏。

 

注入DLL:

注入DLL中,可以开发一个窗口资源。被注入到游戏中后,这个窗口资源可以通过比如说home键直接唤出窗口,该窗口被系统认定为被注入程序的子程序。

 

被注入程序:

被注入程序这里,其实就是我们的游戏,或者如果是小病毒,则是我们病毒的宿主。

 

启动窗口

 

 

唤出窗口

 

启动窗口主要代码:

注入程序触发段:

 

    case WM_COMMAND:
    if( !g_bSubclassed) {
        InjectDll( hStart );
        if( g_bSubclassed ) 
            ::SetDlgItemText( hDlg, IDC_BUTTON, "卸载" );
    }
    else {
            UnmapDll();
            if( !g_bSubclassed ) 
            ::SetDlgItemText( hDlg, IDC_BUTTON, "插入" );
    }
    break;

注入程序:

int InjectDll( HWND hWnd )
{	
	g_hWnd = hWnd;

	// Hook "*.exe"
	g_hHook = SetWindowsHookEx( WH_CALLWNDPROC,(HOOKPROC)HookProc,
								hDll, GetWindowThreadProcessId(hWnd,NULL) );
	if( g_hHook==NULL )
		return 0;
	
	// By the time SendMessage returns, 
	// the START button has already been subclassed
	SendMessage( hWnd,WM_HOOKEX,0,1 );

	return g_bSubclassed;
}

 

DLL唤出窗口主要代码:

读取金币方法:

/**
* 读取金币方法
*/
void ReadMoney(HWND hwnd)
{
			
	HWND wgHwnd =  ::FindWindow(NULL,TEXT("植物大战僵尸中文版"));

	if (wgHwnd ==NULL)
	{			
		return ;
	}
	DWORD procid;
	::GetWindowThreadProcessId(wgHwnd,&procid);//获得进程ID


	HANDLE prochandle=::OpenProcess(PROCESS_ALL_ACCESS,false,procid);//打开进程
					
	DWORD sunny; 
	
	DWORD baseAddr = SUNNY_NUMBER_ADDR;
	DWORD stackAddr;
	DWORD dataAdrr;

	阳光基址读取读基地址
	ReadProcessMemory (prochandle,(void *)baseAddr,&stackAddr,4,0);      	

	//阳光基址 + 一级偏移 = 一级基址
	stackAddr = stackAddr + 0x768 ;

	//读二级偏移基地址
	ReadProcessMemory(prochandle,(void *)stackAddr,&dataAdrr,4,0);		

	//二级偏移 + 二级偏移 = 阳光地址
	dataAdrr = dataAdrr + 0x5560 ;

	//读取阳光数据
	ReadProcessMemory(prochandle,(void *)dataAdrr,&sunny,4,0);	

	TCHAR szText1[MAX_PATH] = {0};
	sprintf(szText1,TEXT("%d"),sunny);
	SetDlgItemText(hwnd,IDC_EDIT1,szText1);
				
	::CloseHandle(prochandle);
}

修改金币方法:

/**
* 修改阳光
*/
void ChangeSunny(HWND hwnd)
{
	HWND wgHwnd =  ::FindWindow(NULL,TEXT("植物大战僵尸中文版"));
	if (wgHwnd ==NULL)
	{			
		return ;
	}

	DWORD procid;
	::GetWindowThreadProcessId(wgHwnd,&procid);//获得进程ID
	
	HANDLE prochandle = ::OpenProcess(PROCESS_ALL_ACCESS,false,procid);//打开进程
	
	DWORD sunny; 
	
	DWORD baseAddr = SUNNY_NUMBER_ADDR;
	DWORD stackAddr;
	DWORD dataAdrr;

	阳光基址读取读基地址
	ReadProcessMemory (prochandle,(void *)baseAddr,&stackAddr,4,0);      	

	//阳光基址 + 一级偏移 = 一级基址
	stackAddr = stackAddr + 0x768 ;


	//读二级偏移基地址
	ReadProcessMemory(prochandle,(void *)stackAddr,&dataAdrr,4,0);		


	//二级偏移 + 二级偏移 = 阳光地址
	dataAdrr = dataAdrr + 0x5560 ;

	//获取文本框输入
	TCHAR szText1[MAX_PATH] = {0};
	GetDlgItemText(hwnd,IDC_EDIT1,szText1,MAX_PATH);
	sunny = (DWORD)atoi(szText1);
	
	//写入数据
	WriteProcessMemory(prochandle, (void *)dataAdrr, &sunny, 4, 0);	

	CloseHandle(prochandle);
}

其余部分大家可以看github上源代码,有完成源代码。

 

 

结尾:

 

虽然我们学会了如何注入程序到dll,但是离真正的高级编程还远。注入dll其实是一种反查杀策略。就好比把dll看成我们是一伙的不排斥你。

后面章节我们会讲外挂的反游戏保护驱动。谢谢~

 

 

  • 14
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值