免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!

本次游戏没法给

内容参考于:微尘网络安全

工具下载:

链接:https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd=6tw3

提取码:6tw3

复制这段内容后打开百度网盘手机App,操作更方便哦

上一个内容:38.第二阶段x86游戏实战2-HOOK窗口消息机制

上一个内容里写了HOOK主线程,本次就让我们的call到主线程里进行执行

主线程调用流程

首先如下图红框通过SendMessage函数把一个消息发送到Windows的消息队列中,它会发送三个用来做判断的数据,窗口句柄、消息idA、消息idB(一般这个消息idB和消息idA配合使用,一般消息idA表示系列函数,消息idB表示系列函数中哪一个函数)

然后通过SetWindowsHookEx函数给游戏主线程做HOOK,HOOK之后只要有消息就会调用 Call_主线程回调函数 函数

然后 Call_主线程回调函数 里判断是不是有消息号

CM.cpp文件的修改:修改了 OnBnClickedButton2函数(这是寻路按钮的点击事件处理函数)寻路修改为通过Windows消息队列调用

// CM.cpp: 实现文件
//

#include "pch.h"
#include "tl.h"
#include "CM.h"
#include "afxdialogex.h"


// CM 对话框

IMPLEMENT_DYNAMIC(CM, CDialogEx)


CM::CM(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_DIALOG1, pParent)
	, edi_x(_T(""))
{

}

CM::~CM()
{
}

void CM::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_EDIT1, edi_x);
	DDX_Text(pDX, IDC_EDIT2, edi_y);
}


BEGIN_MESSAGE_MAP(CM, CDialogEx)
	ON_BN_CLICKED(IDC_BUTTON1, &CM::OnBnClickedButton1)
	ON_BN_CLICKED(IDC_BUTTON2, &CM::OnBnClickedButton2)
	ON_BN_CLICKED(IDC_BUTTON3, &CM::OnBnClickedButton3)
	ON_BN_CLICKED(IDC_BUTTON4, &CM::OnBnClickedButton4)
	ON_BN_CLICKED(IDC_BUTTON5, &CM::OnBnClickedButton5)
	ON_BN_CLICKED(IDC_BUTTON6, &CM::OnBnClickedButton6)
END_MESSAGE_MAP()


// CM 消息处理程序


void CM::OnBnClickedButton1()
{
	R_人物属性 a;
	a.初始化();
	Call_输出调试信息("人物信息:人物状态%d",a.状态);
}


void CM::OnBnClickedButton2()
{
	UpdateData(TRUE);
	CString str1 = edi_x;
	CString str2 = edi_y;
	// strtol((const char*)CW2A(str1.GetBuffer(0)), NULL, 10);把字符串转成int数字类型
	int x = strtol((const char*)CW2A(str1.GetBuffer(0)), NULL, 10);
	int y = strtol((const char*)CW2A(str2.GetBuffer(0)), NULL, 10);
	Msg_xl(x, y);
}


void CM::OnBnClickedButton3()
{
	R_遍历背包 a;
	a.遍历背包();// 遍历背包
	CString str;
	str.Format(L"a数量 %d", a.d数量);
	AfxMessageBox(str);

	for (int i = 0; i < a.d数量; i++)
	{
		Call_输出调试信息("tl怀旧   背包信息 dwObject -------------%X----------------\r\n", a.列表[i].dwObject);
		Call_输出调试信息("tl怀旧   背包信息 名字:%s\r\n", a.列表[i].pName.c_str());
		Call_输出调试信息("tl怀旧   背包信息 使用等级:%d\r\n", a.列表[i].p使用等级);
		Call_输出调试信息("tl怀旧   背包信息 简介:%s\r\n", a.列表[i].简介.c_str());
		Call_输出调试信息("tl怀旧   背包信息 数量:%d\r\n", a.列表[i].p数量);


	}

}


void CM::OnBnClickedButton4()
{
	// TODO: 在此添加控件通知处理程序代码
	R_周围遍历 a;

	a.遍历最近怪物();// 让怪物重新排列
	for (int i = 0; i < a.d数量; i++)
	{
		Call_输出调试信息("人物信息:---------------------%s-----%x---------------------", a.列表[i].pName, a.列表[i].dwObject);
		Call_输出调试信息("人物信息:人物id:%x", a.列表[i].id);
		Call_输出调试信息("人物信息:人物X:%f 人物Y:%f", a.列表[i].fX, a.列表[i].fY);
		Call_输出调试信息("人物信息:人物类型:%x  人物距离:%f", a.列表[i].PType, a.列表[i].距离);


	}
}


void CM::OnBnClickedButton5()
{
	// TODO: 在此添加控件通知处理程序代码
	R_遍历技能 a;
	a.AsmGetMonsterData();// 遍历技能

	for (int i = 0; i < a.d数量; i++)
	{

		Call_输出调试信息("tl怀旧   技能信息 名字:---------------%s-----------------------\r\n", a.列表[i].pName.c_str());
		Call_输出调试信息("tl怀旧   技能信息 ID:%d\r\n", a.列表[i].pID);
			Call_输出调试信息("tl怀旧   技能信息 是否冷却:%s\r\n", a.列表[i].冷却.c_str());
			Call_输出调试信息("tl怀旧   技能信息 冷却ID:%x\r\n", a.列表[i].冷却ID);
		Call_输出调试信息("tl怀旧   技能信息 对象地址:%x\r\n", a.列表[i].dwObject);

	}
}


void CM::OnBnClickedButton6()
{
	Call_Hook主线程();
}

新加Hook.h文件,把HOOK相关的代码全放到了这里面

#pragma once
#include "pch.h"

DWORD Call_Hook主线程();
HWND Call_获取窗口句柄();
void Msg_xl(DWORD X, DWORD Y);
//DWORD Call_卸载Hook主线程();

#define ID_寻路 0x902

struct T寻路参数
{
	DWORD X;
	DWORD Y;
};

新加Hook.cpp文件

#include "pch.h"

HHOOK g_Hook返回;
const DWORD g_My消息ID = RegisterWindowMessageA("MyMsyCode");// 注册一个消息号
HWND Call_获取窗口句柄()
{
	// 获取游戏存放的窗口句柄,通过CE搜索spy++的句柄找到的
	HWND hGame = (HWND)((DWORD)GetModuleHandleA("CEGUIBase.dll") + 0x251030);
	hGame = *(HWND*)hGame;
	return hGame;
}

void Msg_xl(DWORD X, DWORD Y)
{
	T寻路参数 寻路;
	寻路.X = X;
	寻路.Y = Y;
	::SendMessageA(Call_获取窗口句柄(), g_My消息ID, ID_寻路, (LPARAM)&寻路);
}

//主线程回调函数
LRESULT CALLBACK Call_主线程回调函数(int nCode, WPARAM wParam, LPARAM lparam)
{
	/*
		::SendMessageA(Call_获取窗口句柄(), g_My消息ID, ID_寻路, (LPARAM)&寻路);

		CWPSTRUCT类型的参数分别对应SendMessageA函数的入参,如下
			LPARAM  lParam =  (LPARAM)&寻路
			WPARAM  wParam = ID_寻路
			UINT    message = g_My
			HWND    hwnd = Call_获取窗口句柄()
	*/
	CWPSTRUCT *lpArg = (CWPSTRUCT*)lparam;//结构  hwnd message wParam lParam
	if (nCode == HC_ACTION)//自己进程的消息
	{
		if (lpArg->hwnd == Call_获取窗口句柄() && lpArg->message == g_My消息ID)//我们自己的消息  
		{
			string luaText;

			switch (lpArg->wParam)
			{
				T寻路参数*寻路;
			case ID_寻路:
				寻路 = (T寻路参数*)lpArg->lParam;
				Call_xunlu(寻路->X, 寻路->Y);
				return 1;
				break;
			}
		}
	}
	return CallNextHookEx(g_Hook返回, nCode, wParam, lparam);
}

DWORD Call_Hook主线程()
{
	HWND hGame = Call_获取窗口句柄();
	// 通过句柄获取窗口的线程id
	DWORD ndThreadId = GetWindowThreadProcessId(hGame, NULL);
	if (ndThreadId != 0)
	{
		// 注册窗口HOOK,SetWindowsHookEx是微软提供
		g_Hook返回 = SetWindowsHookEx(WH_CALLWNDPROC, Call_主线程回调函数, NULL, ndThreadId);
	}
	return 1;
}

上方的代码不全,只有手写的代码

完整代码:

链接:https://pan.baidu.com/s/1W-JpUcGOWbSJmMdmtMzYZg?pwd=q9n5

提取码:q9n5

复制这段内容后打开百度网盘手机App,操作更方便哦


img

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐