39.第二阶段x86游戏实战2-HOOK实现主线程调用
游戏逆向 游戏安全 游戏攻防 c++ 反游戏外挂 保姆级攻略 Windows 汇编
·
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!
本次游戏没法给
内容参考于:微尘网络安全
工具下载:
链接: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,操作更方便哦
更多推荐
所有评论(0)