11.网络游戏逆向分析与漏洞攻防-游戏网络架构逆向分析-接管游戏接收网络数据包的操作

本文主要是介绍11.网络游戏逆向分析与漏洞攻防-游戏网络架构逆向分析-接管游戏接收网络数据包的操作,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

上一个内容:接管游戏发送数据的操作

 码云地址(master 分支):https://gitee.com/dye_your_fingers/titan

码云版本号:8256eb53e8c16281bc1a29cb8d26d352bb5bbf4c

代码下载地址,在 titan 目录下,文件名为:titan-接管游戏接收网络数据包的操作.zip

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

提取码:q9n5

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

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

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

提取码:78h8

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

以 接管游戏发送数据的操作 它的代码为基础进行修改

通过 通过逆向分析确定游戏明文接收数据过程 分析得到 0x10617FD7 位置是调用recv函数之后接收到数据处理一个数据包的函数位置,它调用的函数不是虚函数表里的函数了,而是一个普通的函数,如下图红框位置,它调用的是0x10618480(0x10618480是函数地址)函数

aa9b15c9a9a347c5bdd24117716f7a75.png

然后这个函数不知道是由于编译器优化还是什么原因,它是用eax传递的连接对象,但它本质上还是thiscall(一个类调用它的成员函数就是thiscall,Visual Studio里c++里的this就是取ecx寄存器里的值),所以调用的时候要特殊处理(因为类调用成员函数用的是ecx)

072748b870114adca51f05c71b4dce1b.png

用游戏生成一个接收到的数据包,这里的数据包时聊天数据的数据包,用于模拟服务器欺骗客户端

16d9b05d98244763b5abd75f8c69aa75.png

游戏种发送的聊天数据:

6da6c4d401cd400199898d3fa52ddf47.png

修改一下数据包:原本时0x31现在改成0x32

7df99310660945e19ec0efa10632f863.png

效果图:成功欺骗了客户端,让客户端接收了伪造的数据

6f2903d78fe84cefb23a48518b2580fc.png

GameProc.cpp文件的修改:修改了 InitInterface函数,新加 _OnRecv函数

#include "pch.h"
#include "GameProc.h"
#include "extern_all.h"// typedef bool(GameWinSock::* U)(char*, unsigned);bool _OnRecv(HOOKREFS2) {unsigned* _esp = (unsigned*)_ESP;_EAX = WinSock->RecvPoint;WinSock->OnRecving((char*)_esp[2], _esp[1]);return true;
}bool _OnConnect(HOOKREFS2) {/*根据虚函数表做HOOK的操作截取 ecx 获取 winsock 的值(指针)*/unsigned* vtable = (unsigned*)_EDX;//WinSock = (GameWinSock *)_ECX;/*联合体的特点是共用一个内存由于 GameWinSock::OnConnect 的 OnConnect函数是 GameWinSock类的成员函数直接 vtable[0x34 / 4] = (unsigned)&GameWinSock::OnConnect; 这样写语法不通过所以使用联合体,让语法通过*/union {unsigned value;bool(GameWinSock::* _proc)(char*, unsigned);} vproc;DWORD oldPro, backProc;VirtualProtect(vtable, 0x100, PAGE_EXECUTE_READWRITE, &oldPro);/*vproc._proc = &GameWinSock::OnConnect;  这一句是把我们自己写的调用connect函数的地址的出来*/ vproc._proc = &GameWinSock::OnConnect; /*InitClassProc函数里做的是给指针赋值的操作InitClassProc(&GameWinSock::_OnConnect, vtable[0x34/4]);这一句的意思是把GameWinSock类里的_OnConnect变量的值赋值成vtable[0x34/4],这个 vtable[0x34/4] 是虚表里的函数vtable[0x34/4]是游戏中调用connect函数的函数地址,经过之前的分析调用connect是先调用了虚表中的一个函数,然后从这个函数中调用了connect函数*/InitClassProc(&GameWinSock::_OnConnect, vtable[0x34/4]);vtable[0x34 / 4] = vproc.value;vproc._proc = &GameWinSock::OnSend;InitClassProc(&GameWinSock::_OnSend, vtable[0x3C / 4]);vtable[0x3C / 4] = vproc.value;VirtualProtect(vtable, 0x100, oldPro, &backProc);return true;
}GameProc::GameProc()
{hooker = new htd::hook::htdHook2();Init();InitInterface();
}void GameProc::LoadBase()
{LoadLibraryA("fxnet2.dll");
}void GameProc::Init()
{
}void GameProc::InitInterface()
{LoadBase();// MessageBoxA(0, "1", "1", MB_OK);// 只会HOOK一次,一次性的HOOKhooker->SetHook((LPVOID)0x10617046, 0x1, _OnConnect, 0, true);/*第一个参数是HOOK的位置第二个参数是HOOK的位置的汇编代码的长度(用于保证执行的汇编代码完整)第三个参数是HOOK之后当游戏执行到第一个参数的位置的时候跳转的位置*/hooker->SetHook((LPVOID)0x10618480, 0x1, _OnRecv);/*在这里绑定游戏处理数据包函数(0x10618480函数)然后0x10618480函数在上面一行代码已经进行了HOOK所以在调用_OnRecv函数指针时,它就会进入我们HOOK*/InitClassProc(&GameWinSock::_OnRecv, 0x10618480);
}

GameWinSock.h文件的修改:新加 _OnRecv函数指针变量,OnRecving函数、OnRecv函数、vatble变量、un变量、RecvPoint变量

#pragma once
class GameWinSock
{typedef bool(GameWinSock::* PROC)(char*, unsigned);
public:unsigned* vatble;// 虚函数表unsigned un[17];unsigned RecvPoint; // 游戏recv之后调用处理一个数据包函数时的eax,这里偏移是0x48
public:static PROC _OnConnect;static PROC _OnSend;static PROC _OnRecv;bool OnConnect(char* ip, unsigned port);bool OnSend(char* buff, unsigned len);bool OnRecving(char* buff, unsigned len);bool OnRecv(char* buff, unsigned len);
};

GameWinSock.cpp文件的修改:新加 _OnRecv函数指针变量,OnRecving函数、OnRecv函数、vatble变量、un变量、RecvPoint变量

#include "pch.h"
#include "GameWinSock.h"
#include "extern_all.h"GameWinSock::PROC GameWinSock::_OnConnect{};
GameWinSock::PROC GameWinSock::_OnSend{};
GameWinSock::PROC GameWinSock::_OnRecv{};
// 这个函数拦截了游戏的连接
bool GameWinSock::OnConnect(char* ip, unsigned port)
{// this是ecx,HOOK的点已经有ecx了WinSock = this;bool b = (this->*_OnConnect)(ip, port);// 下方注释的代码时为了防止多次注入,导致虚函数地址不恢复问题导致死循环,通过一次性HOOK也能解决/*unsigned* vtable = (unsigned*)this;vtable = (unsigned*)vtable[0];union {unsigned value;bool(GameWinSock::* _proc)(char*, unsigned);} vproc;vproc._proc = _OnConnect;DWORD oldPro, backProc;VirtualProtect(vtable, 0x10x00, PAGE_EXECUTE_READWRITE, &oldPro);vtable[0x34 / 4] = vproc.value;VirtualProtect(vtable, 0x10x00, oldPro, &backProc);*/return b;
}bool GameWinSock::OnSend(char* buff, unsigned len)
{/*这里就可以监控游戏发送的数据了*/return (this->*_OnSend)(buff, len);
}bool GameWinSock::OnRecving(char* buff, unsigned len)
{// MessageBoxA(0, "11111111111111", "0", MB_OK);/*监控游戏接收的数据包*/return true;
}bool GameWinSock::OnRecv(char* buff, unsigned len)
{//AfxMessageBox(L"%s", buff);return (this->*_OnRecv)(buff, len);
}

CUIWnd_0.cpp文件的修改:修改了 OnBnClickedButton1函数(按钮点击事件处理函数)

// CUIWnd_0.cpp: 实现文件
//#include "pch.h"
#include "htdMfcDll.h"
#include "CUIWnd_0.h"
#include "afxdialogex.h"
#include "extern_all.h"// CUIWnd_0 对话框IMPLEMENT_DYNAMIC(CUIWnd_0, CDialogEx)CUIWnd_0::CUIWnd_0(CWnd* pParent /*=nullptr*/): CDialogEx(IDD_PAGE_0, pParent)
{}CUIWnd_0::~CUIWnd_0()
{
}void CUIWnd_0::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);
}BEGIN_MESSAGE_MAP(CUIWnd_0, CDialogEx)ON_BN_CLICKED(IDC_BUTTON1, &CUIWnd_0::OnBnClickedButton1)
END_MESSAGE_MAP()// CUIWnd_0 消息处理程序void CUIWnd_0::OnBnClickedButton1()
{/*char buff[] = {0xA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x4, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 00 ,0x00,0x00, 0x07, 0x0E, 0x00, 0x00, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x31, 0x00, 0x32 ,0x00,0x33, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};WinSock->OnSend(buff, sizeof(buff));*/char buff[] = {0x27, 0x46, 0x92, 0x02, 0x00, 0x00, 0x89, 0x02, 0x00, 0x00, 0x06, 0x00, 0x06, 0x05, 0x00, 0x00, 0x00, 0x63, 0x68, 0x61, 0x74, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x07, 0x0A, 0x00, 0x00, 0x00, 0x34, 0x00, 0x33, 0x00, 0x39, 0x00, 0x39, 0x00, 0x00, 0x00, 0x07, 0x5A, 0x02, 0x00, 0x00, 0x31, 0x00, 0x32, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33,0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36,0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x37, 0x00, 0x38, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00};WinSock->OnRecv(buff, sizeof(buff));
}

 


 

b99b117c4f6d6b5a9a6f4b91092f8bf8.jpeg


 

 

这篇关于11.网络游戏逆向分析与漏洞攻防-游戏网络架构逆向分析-接管游戏接收网络数据包的操作的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Knife4j+Axios+Redis前后端分离架构下的 API 管理与会话方案(最新推荐)

《Knife4j+Axios+Redis前后端分离架构下的API管理与会话方案(最新推荐)》本文主要介绍了Swagger与Knife4j的配置要点、前后端对接方法以及分布式Session实现原理,... 目录一、Swagger 与 Knife4j 的深度理解及配置要点Knife4j 配置关键要点1.Spri

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Linux中压缩、网络传输与系统监控工具的使用完整指南

《Linux中压缩、网络传输与系统监控工具的使用完整指南》在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛,下面小编就来和大家详细介绍一下它... 目录引言一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作2.

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

mysql表操作与查询功能详解

《mysql表操作与查询功能详解》本文系统讲解MySQL表操作与查询,涵盖创建、修改、复制表语法,基本查询结构及WHERE、GROUPBY等子句,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随... 目录01.表的操作1.1表操作概览1.2创建表1.3修改表1.4复制表02.基本查询操作2.1 SE

mysql中的服务器架构详解

《mysql中的服务器架构详解》:本文主要介绍mysql中的服务器架构,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、mysql服务器架构解释3、总结1、背景简单理解一下mysqphpl的服务器架构。2、mysjsql服务器架构解释mysql的架

MySQL中的表连接原理分析

《MySQL中的表连接原理分析》:本文主要介绍MySQL中的表连接原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、表连接原理【1】驱动表和被驱动表【2】内连接【3】外连接【4编程】嵌套循环连接【5】join buffer4、总结1、背景

c++中的set容器介绍及操作大全

《c++中的set容器介绍及操作大全》:本文主要介绍c++中的set容器介绍及操作大全,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录​​一、核心特性​​️ ​​二、基本操作​​​​1. 初始化与赋值​​​​2. 增删查操作​​​​3. 遍历方

MySQL追踪数据库表更新操作来源的全面指南

《MySQL追踪数据库表更新操作来源的全面指南》本文将以一个具体问题为例,如何监测哪个IP来源对数据库表statistics_test进行了UPDATE操作,文内探讨了多种方法,并提供了详细的代码... 目录引言1. 为什么需要监控数据库更新操作2. 方法1:启用数据库审计日志(1)mysql/mariad

springboot如何通过http动态操作xxl-job任务

《springboot如何通过http动态操作xxl-job任务》:本文主要介绍springboot如何通过http动态操作xxl-job任务的问题,具有很好的参考价值,希望对大家有所帮助,如有错... 目录springboot通过http动态操作xxl-job任务一、maven依赖二、配置文件三、xxl-