[汇编]汇编学习笔记(7):代码注入

        之前练习写了个拳皇13修改器,发现需要对远程进程操作,一直需要ReadProcessMemory,发现代码量会变得很多,最近又学到一个代码注入,发现比之前的的要方便很多。关键API是CreateRemoteThread,这个网上有很多介绍,这边就不仔细介绍了。

        有2个地方需要注意:平台和发布模式。必须是Release模式下,平台要跟需要注入的程序有关,比如:黑暗之魂重制版是64位的,网易有道词典是32位的。

        还有个地方需要注意,FindWindow是可以根据类名或者标题名找到窗口句柄的,但是有的应用程序标题会用到特殊符号,比如黑暗之魂重制版,标题名为“DARK SOULS™: REMASTERED”,根据标题名是查找不到窗口句柄的(拳皇13那种直接标题名的就不用这么麻烦),这个时候就需要用到Microsoft Spy++来查找类名来解决这个问题。

直接Show code,代码注释比较多,详细就不介绍了:

Remote.h:

#pragma once

#include <Windows.h>

typedef int(_stdcall* MessageBoxProc)(HWND hwnd, char* strText, char* strCaption, UINT uType);

struct SRemoteParam
{
	byte cmd;
	MessageBoxProc pMsgBoxFunc;
	char strMsgContent[100];
};

DWORD WINAPI RemoteThreadProc(LPARAM lParam)
{
	SRemoteParam* pRemoteParam = (SRemoteParam*)lParam;
	if (1 == pRemoteParam->cmd)
		pRemoteParam->pMsgBoxFunc(NULL, pRemoteParam->strMsgContent, pRemoteParam->strMsgContent, MB_OK);

	return 0;
}

/**
 * 用来计算DWORD WINAPI RemoteThreadProc(LPARAM lParam)函数所占内存大小
 */
void AfterRemoteThreadProc()
{

}

CAppHandle.h:

#pragma once

#include <string>
#include <Windows.h>

class CAppHandle
{
public:
        ...
	/**
	 * 代码注入
	 * -> IN: SIZE_T nRemoteProcSize	- 函数所占内存大小
	 *		  void* pRemoteProc			- 函数地址
	 *		  SIZE_T nRemoteParamSize	- 变量所占内存大小
	 *		  void* pRemoteParam		- 变量地址
	 */
	void SendSpy(
		SIZE_T nRemoteProcSize, 
		void* pRemoteProc, 
		SIZE_T nRemoteParamSize = 0, 
		void* pRemoteParam = nullptr);

private:
	...
	void FindHandle();

private:
	std::string m_strClassName;		// 窗口类名
	std::string m_strWindowName;	// 窗口标题名
	HANDLE m_handleApp;

	char* m_pRemoteProc;			// 注入远程进程函数
	char* m_pRemoteParam;			// 注入远程进程变量
};

CAppHandle.cpp:

/**
* 代码注入
* -> IN: SIZE_T nRemoteProcSize		- 函数所占内存大小
*		 void* pRemoteProc			- 函数地址
*		 SIZE_T nRemoteParamSize	- 变量所占内存大小
*		 void* pRemoteParam			- 变量地址
*/
void CAppHandle::SendSpy(
	SIZE_T nRemoteProcSize, 
	void* pRemoteProc, 
	SIZE_T nRemoteParamSize, 
	void* pRemoteParam)
{
	{// 注入远程进程的函数
		// 在远程进程中分配函数内存
		m_pRemoteProc = (char*)VirtualAllocEx(m_handleApp, 0, nRemoteProcSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
		if (nullptr == m_pRemoteProc) return;

		// 在远程进程中注入函数
		WriteProcessMemory(m_handleApp, m_pRemoteProc, pRemoteProc, nRemoteProcSize, nullptr);
	}

	if (nRemoteParamSize != 0 && pRemoteParam != nullptr)// 注入远程进程的函数变量
	{
		// 在远程进程中分配变量内存
		m_pRemoteParam = (char*)VirtualAllocEx(m_handleApp, 0, nRemoteParamSize, MEM_COMMIT, PAGE_READWRITE);
		if (nullptr == m_pRemoteParam) return;

		// 在远程进程中注入变量
		WriteProcessMemory(m_handleApp, m_pRemoteParam, pRemoteParam, nRemoteParamSize, nullptr);
	}

	// 启动远程线程
	HANDLE hThread = CreateRemoteThread(m_handleApp, 
		nullptr, 
		0, 
		(LPTHREAD_START_ROUTINE)m_pRemoteProc, 
		m_pRemoteParam, 
		0, 
		nullptr);
	if (hThread != NULL)
	{
		// 等待线程结束
		WaitForSingleObject(hThread, INFINITE);
		// 获得返回值
		DWORD dwReturn;
		GetExitCodeThread(hThread, &dwReturn);
		CloseHandle(hThread);
	}

	if (m_pRemoteProc != nullptr)
	{
		VirtualFreeEx(m_handleApp, m_pRemoteProc, 0, MEM_RELEASE);
		m_pRemoteProc = nullptr;
	}
	if (m_pRemoteParam != nullptr)
	{
		VirtualFreeEx(m_handleApp, m_pRemoteParam, 0, MEM_RELEASE);
		m_pRemoteParam = nullptr;
	}
}

void CAppHandle::FindHandle()
{
	ReleaseHandle();

	HWND hwndWindow = NULL;
	if (!m_strClassName.empty())
		hwndWindow = FindWindow(m_strClassName.c_str(), nullptr);
	else
		hwndWindow = FindWindow(nullptr, m_strWindowName.c_str());
	if (NULL == hwndWindow) return;

	DWORD dwPID = 0;
	GetWindowThreadProcessId(hwndWindow, &dwPID);
	if (NULL == dwPID) return;

	m_handleApp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
}

Main.cpp:

#include <iostream>
#include "CAppHandle.h"
#include "Remote.h"

int main()
{
	std::cout << "Hello, world!" << std::endl;
	CAppHandle* pAppHandle = new CAppHandle("DARK SOULS", "网易有道词典");
	if (!pAppHandle) return -1;

	int nRempteProcSize = (byte*)AfterRemoteThreadProc - (byte*)RemoteThreadProc;
	int nRemoteParamSize = sizeof(SRemoteParam);
	SRemoteParam param;
	param.cmd = 1;
	param.pMsgBoxFunc = (MessageBoxProc)MessageBoxA;
	sprintf_s(param.strMsgContent, 100, "Hello, wolrd");

	while (true)
	{
		if (pAppHandle->IsAppRunning())
		{
			std::cout << "SnedSpy: " << std::endl;
			pAppHandle->SendSpy(nRempteProcSize, RemoteThreadProc, nRemoteParamSize, &param);
		}
	}

	delete pAppHandle;
	pAppHandle = nullptr;

	return 0;
}

效果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值