101.网游逆向分析与插件开发-网络通信封包解析-解读聊天数据包并且利用Net发送

本文主要是介绍101.网游逆向分析与插件开发-网络通信封包解析-解读聊天数据包并且利用Net发送,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

内容参考于:易道云信息技术研究院VIP课

上一个内容:C++还原网络通信系统发送功能

下一个内容:解读喊话道具数据包并且利用Net发送

码云地址(游戏窗口化助手 分支):https://gitee.com/dye_your_fingers/sro_-ex.git

码云版本号:c78a135393b36cc4a6a6956b1309472951eb2acd

代码下载地址,在 SRO_EX 目录下,文件名为:SRO_Ex-解读聊天数据包并且利用Net发送.zip

链接:https://pan.baidu.com/s/1W-JpUcGOWbSJmMdmtMzYZg

提取码:q9n5

--来自百度网盘超级会员V4的分享

HOOK引擎,文件名为:黑兔sdk.zip

链接:https://pan.baidu.com/s/1IB-Zs6hi3yU8LC2f-8hIEw

提取码:78h8

--来自百度网盘超级会员V4的分享

以 C++还原网络通信系统发送功能 它的代码为基础进行修改

效果图:点击设置按钮消息发送成功

首先来到

然后断下来

下图红框位置,是把数据包拼入类的地方

然后分析数据包:现在的长度是E,数据是01 01 00 09 00 31 32 33 34 35 36 37 38 39 

然后再发送一个

这时它的长度是B,数据是 01 02 00 06 00 31 32 33 34 35 36

然后再发一个消息

这时的长度是F,数据是 01 03 00 0A 00 39 38 37 36 35 34 33 32 31 30

开始分析:

第一个字节的数据是01,它是固定的

第二个字节的数据每次都自增1,它不是一个固定的东西,不知道是什么

第四个字节09、06、0A也都在变,所以接下来就要破解第四个字节的数据跟数据有怎样的关系

第四个数据也很容易看出,第一个数据里的第四个字节的数据是09,然后我们的数据是9个字节,第二个数据里的第四个字节的数据是06,然后我们的数据是6个字节,第三个数据里的第四个字节的数据是0A,然后我们的数据是10个字节,所以第四个字节的数据是我们聊天发送的内容的长度

它的一个结构体

char 01 不变的

short un

short lenth

char* data 聊天数据

重新登陆游戏之后说话

下方是游戏重新登录之后的第二次说话,然后把这次说话的第二个字节原本是01改成了00(第一次说话时是00),这时发现,它说话成功了,但是没有任何内容

然后第四次说话

然后把原本的03改成了01

这时发现,我们说话的内容变了,原本是66666,现在变成了2222.。。。也就是我们的第二句话,这时很奇怪,我们并没有把第二句话发送给服务器,服务器也不可能保存我们说的话

它的作用,这就是韩国的这个游戏它设计的比较经典的地方,就是我们在下图红框位置说话,会对所有人广播

断线的时候说话,在下图红框位置是不显示内容的,只有在线的时候才会显示内容,也就是说在线的时候服务器是有响应的,所以当说完一句话之后服务器会给一个响应,会告诉你你说了一句什么样的话,周围的人也会看到你说了一句什么话,那么服务器再给予你说的什么话的内容的时候,这个游戏它的设计是,它给你发送消息前给每个消息编一个号,将来发送完消息之后,它告诉你第几号消息发送成功了,第几号消息发送成功,它就会把这个消息显示出来,这样的话它就不用把你说的这个话再广播给你了,这样就节约了网络,虽然节约了一点点,但也能看出它的一个设计

然后再登录一个账号,然后说话,这时说的是123

然后把数据改成456,这时网络发送的是456,不是123

然后查看两个账户的内容,另一个账号显示的是456,发送消息的账号显示的是123,这样证明了上方的想法,它会根据序号,读取本地之前发送的时候的存储的记录,然后显示说的话

然后现在就知道了,聊天数据包的结构,但是现在还有个问题,就是频道是哪个,然后在另一个频道说话

这时的数据包,数据包长度是8,数据是 05 05 00 3 00 31 31 31,与之前不同的是第一个字节的数据变成了05,所以第一个字节代表了频道

然后更新结构体:

它的一个结构体

char 01 频道 01 是公共频道 02 是单独聊天 04 是组队频道 05 是帮会频道

short un

short lenth

char* data 聊天数据

然后跟某个人单独聊天的数据结构,首先发送消息断点住

然后它的数据,长度是10,数据是 02 09 00 06 00 4D 61 73 74 65 72 03 00 31 32 33

 单独聊天的结构分析

第四个字节这时代表的是聊天目标角色名的长度

倒数第五个字节代表了聊天内容的长度

可以看出单独聊天与公共聊天是两种完全不同的数据结构,这个需要单独处理

然后测试C++代码,执行C++代码游戏闪退了,查看C++代码的方式,在代码中加一句MessageBox,然后通过x96dbg,在MessageBox函数头打断点,然后执行它的ret,就回到了我们写的C++代码里,这时就能分析我们的C++代码了

执行MessageBox函数的ret,就会来到下方我们的C++代码里,这样就可以对比我们的C++还原代码与游戏中的代码有什么不同了

然后修改C++代码(看后面的代码)之后,发现游戏不崩溃了,但是掉线了,这说明我们发送的数据有问题,严重不符合规定让服务器给我们断线了

extern_all.cpp文件的修改,修改了 InitClassProc函数

#include "pch.h"
#include "extern_all.h"void InitClassProc(LPVOID proc_addr, unsigned value)
{unsigned* uWrite = (unsigned*)proc_addr;uWrite[0] = value;
}void InitClassProc(LPVOID proc_addr, unsigned* vtable, unsigned index) {unsigned* addr = (unsigned*)vtable;InitClassProc(proc_addr, addr[index]);
}

CHelperUI.cpp文件的修改,修改了 OnBnClickedOk函数

// CHelperUI.cpp: 实现文件
//#include "pch.h"
#include "CHelperUI.h"
#include "afxdialogex.h"
#include "extern_all.h"LRESULT _stdcall CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) {if (nCode == 0) {// 这里接收到的不只有游戏窗口的消息,还有我们的窗口消息// 所以要排除掉我们的窗口PCWPSTRUCT tmp = (PCWPSTRUCT)lParam;// 判断当前触发消息的窗口句柄是不是我们的游戏窗口句柄if (tmp->hwnd == _ui_helper->hwndGame) {// 拦截移动窗口消息if (tmp->message == WM_MOVE) {// 移动我们的窗口_ui_helper->MoveHelper();}if (tmp->message == WM_CLOSE) {// 游戏窗口右上角的X关闭按钮屏蔽掉了,这里我们给它处理一下// 让它点击之后可以隐藏游戏窗口并且显示我们的窗口/**_ui_helper->HideGame(); 里执行的代码如下面的两行this->ShowWindow(TRUE);::ShowWindow(hwndGame, GameShow = false);*/_ui_helper->HideGame();}}}return CallNextHookEx(_ui_helper->hookGameWnd, nCode, wParam, lParam);
}void _stdcall TimeProcHelper(HWND, UINT, UINT_PTR, DWORD) {if (_ui_helper)_ui_helper->ShowData();
}//获取程序当前所在显示器的分辨率大小,可以动态的获取程序所在显示器的分辨率
SIZE GetScreenResolution(HWND hWnd) {SIZE size{};if (!hWnd)return size;//MONITOR_DEFAULTTONEAREST 返回值是最接近该点的屏幕句柄//MONITOR_DEFAULTTOPRIMARY 返回值是主屏幕的句柄//如果其中一个屏幕包含该点,则返回值是该屏幕的HMONITOR句柄。如果没有一个屏幕包含该点,则返回值取决于dwFlags的值HMONITOR hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);MONITORINFOEX miex;miex.cbSize = sizeof(miex);if (!GetMonitorInfo(hMonitor, &miex))return size;DEVMODE dm;dm.dmSize = sizeof(dm);dm.dmDriverExtra = 0;//ENUM_CURRENT_SETTINGS 检索显示设备的当前设置//ENUM_REGISTRY_SETTINGS 检索当前存储在注册表中的显示设备的设置if (!EnumDisplaySettings(miex.szDevice, ENUM_CURRENT_SETTINGS, &dm))return size;size.cx = dm.dmPelsWidth;size.cy = dm.dmPelsHeight;return size;
}IMPLEMENT_DYNAMIC(CHelperUI, CDialogEx)CHelperUI::CHelperUI(CWnd* pParent /*=nullptr*/): CDialogEx(IDD_HELPER, pParent)
{}CHelperUI::~CHelperUI()
{
}BOOL CHelperUI::OnInitDialog()
{CDialogEx::OnInitDialog();this->SetBackgroundColor(RGB(255, 255, 255));HPBar.SetBkColor(RGB(0 ,0, 0));MPBar.SetBkColor(RGB(0 ,0, 0));RageBar.SetBkColor(RGB(0 ,0, 0));ExBar.SetBkColor(RGB(0 ,0, 0));HPBar.SetBarColor(RGB(255 ,0, 0));MPBar.SetBarColor(RGB(0x0, 0x0, 0x99));RageBar.SetBarColor(RGB(0x66, 0x0, 0x66));ExBar.SetBarColor(RGB(0x00, 0xFF, 0xCC));HPBar.SetRange(0, 999);MPBar.SetRange(0, 1000);RageBar.SetRange(0, 5);ExBar.SetRange(0, 1000);//HPBar.SetPos(50);//MPBar.SetPos(50);//RageBar.SetPos(50);//ExBar.SetPos(50);::SetTimer(this->m_hWnd, 0x100002, 100, TimeProcHelper);return TRUE;
}void CHelperUI::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);DDX_Control(pDX, IDC_PRO_HP, HPBar);DDX_Control(pDX, IDC_PRO_MP, MPBar);DDX_Control(pDX, IDC_PRO_RAGE, RageBar);DDX_Control(pDX, IDC_PRO_RAGE2, ExBar);
}BEGIN_MESSAGE_MAP(CHelperUI, CDialogEx)ON_BN_CLICKED(IDOK, &CHelperUI::OnBnClickedOk)ON_BN_CLICKED(IDOK2, &CHelperUI::OnBnClickedOk2)ON_WM_CLOSE()
END_MESSAGE_MAP()// CHelperUI 消息处理程序struct ChatData {char un; // 内存对齐char id;// 频道short index; // 说话内容的序号short lenth; // 说话内容的长度char text[0x50]; // 说话的内容
};void CHelperUI::OnBnClickedOk()
{char talk[]{ "欢迎来到地球!" };char buff[0xFF]{};int len;auto netdata = _pgamebase->SRO_Net->CreateNetData(0x7025, 0x0);ChatData chat;chat.id = 1;chat.index = 0;chat.lenth = sizeof(talk) -1 ;memcpy(chat.text, talk, chat.lenth);len = chat.lenth + 5;netdata->MakeData(&chat.id, len);_pgamebase->SRO_Net->SendData(&netdata);// CDialogEx::OnOK();//CString tmp;//tmp.Format(L"%d", _pgamebase->SRO_Player->MapId);//AfxMessageBox(tmp);////CString city;//city.Format(L"%s", _pgamebase->SRO_Res->ReadTitle(tmp.GetBuffer())->wcstr());//AfxMessageBox(city);// _ui->UIShow();
}void CHelperUI::Init()
{if (hwndGame) return;wchar_t buff[0xFF]{};// 获取主窗口句柄HWND _hwnd = ::GetActiveWindow();// 获取窗口标题::GetWindowText(_hwnd, buff, 0xFF);CString _title = buff;if (_title == L"SRO_CLIENT") {hwndGame = _hwnd;CRect rect_me;// 获取当前窗口句柄GetWindowRect(&rect_me);helper_Width = rect_me.Width();SetWindowsHook(WH_CALLWNDPROC, CallWndProc);}
}void CHelperUI::MoveHelper()
{if (hwndGame) {CRect rect;// 获取游戏窗口(主窗口)样式::GetWindowRect(hwndGame, &rect);int helper_left = rect.left + rect.Width();SIZE windowSize = GetScreenResolution(this->m_hWnd);if ((helper_left + helper_Width) > windowSize.cx) {helper_left -= helper_Width;}// 设置窗口大小::MoveWindow(this->m_hWnd, helper_left, rect.top, helper_Width, rect.Height(), TRUE);}
}void CHelperUI::ShowData()
{CString tmp;CString city;auto _player = _pgamebase->SRO_Player;if (_player) {tmp.Format(L"%s Lv %d", _player->Name.wcstrByName(), _player->Lv);this->SetWindowText(tmp);float hpStep = _player->HP * 1000;hpStep = hpStep / _player->MaxHP;HPBar.SetPos(hpStep);float mpStep = _player->MP * 1000;mpStep = mpStep / _player->MaxMP;MPBar.SetPos(mpStep);RageBar.SetPos(_player->Rage);unsigned max_exp = _pgamebase->SRO_Core->GetLvMaxExp(_player->Lv)->Exp;float expSetp = _player->Exp * 1000;expSetp = expSetp / max_exp;ExBar.SetPos(expSetp);tmp.Format(L"%.1f %.1f %.1f", _player->x, _player->h, _player->y);GetDlgItem(IDC_STATIC_CORD)->SetWindowText(tmp);tmp.Format(L"%d", _pgamebase->SRO_Player->MapId);city.Format(L"%s", _pgamebase->SRO_Res->ReadTitle(tmp.GetBuffer())->wcstr());GetDlgItem(IDC_STATIC_MAP)->SetWindowText(city);}
}void CHelperUI::Show()
{MoveHelper();this->ShowWindow(TRUE);
}void CHelperUI::OnBnClickedOk2()
{if (hwndGame) {::ShowWindow(hwndGame, GameShow = !GameShow);}
}void CHelperUI::OnClose()
{if (hwndGame) {::ShowWindow(hwndGame, GameShow = true);this->ShowWindow(FALSE);}
}void CHelperUI::HideGame()
{this->ShowWindow(TRUE);::ShowWindow(hwndGame, GameShow = false);
}

这篇关于101.网游逆向分析与插件开发-网络通信封包解析-解读聊天数据包并且利用Net发送的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/846917

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

MCU7.keil中build产生的hex文件解读

1.hex文件大致解读 闲来无事,查看了MCU6.用keil新建项目的hex文件 用FlexHex打开 给我的第一印象是:经过软件的解释之后,发现这些数据排列地十分整齐 :02000F0080FE71:03000000020003F8:0C000300787FE4F6D8FD75810702000F3D:00000001FF 把解释后的数据当作十六进制来观察 1.每一行数据