• 10.网络游戏逆向分析与漏洞攻防-游戏网络架构逆向分析-接管游戏发送数据的操作


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

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

    上一个内容:接管游戏连接服务器的操作

     码云地址(master 分支):染指/titan

    码云版本号:00820853d5492fa7b6e32407d46b5f9c01930ec6

    代码下载地址,在 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的分享

    以 接管游戏连接服务器的操作 它的代码为基础进行修改

    首先通过 通过逆向分析确定游戏明文发送数据过程 分析得出数据发送的位置,然后它与connect用的是同一个对象,所以还是可以用虚函数表:如下图虚函数表3C位置里的函数里调用了send函数

    865063f0c09c4f49910a809212b968d8.png

    然后它的参数,第一个参数是发送的数据包,第二个数据是发送的数据包的长度,它的返回值是一个bool类型,如下图它的返回值是al,al寄存器是1字节

    b1b6cf5370e1477faf8832576cc9c18e.png

    然后通过下图两个红框位置的赋值操作,也能看出这是一个bool类型(true是1,false是0)

    a8de6a2ee6a24fa9b7c58615457d8d1f.png

    它的函数原型:

    bool GameWinSock::Send(char* buff, int len);

    模拟游戏发送数据:首先现在无法制作游戏的数据包,所以用游戏生成一个数据包,复制出来

    26ab349196c4430987ecf593cd4e542a.png

    通过按钮发送聊天数据:

    8b3f102cd3f24f7c95ca682ee7819a6c.png

    资源视图新加按钮:

    3892f88596e846c2b5782746f9a7c135.png

    CUIWnd_0.cpp文件的修改:新加新加按钮点击事件

    1. // CUIWnd_0.cpp: 实现文件
    2. //
    3. #include "pch.h"
    4. #include "htdMfcDll.h"
    5. #include "CUIWnd_0.h"
    6. #include "afxdialogex.h"
    7. #include "extern_all.h"
    8. // CUIWnd_0 对话框
    9. IMPLEMENT_DYNAMIC(CUIWnd_0, CDialogEx)
    10. CUIWnd_0::CUIWnd_0(CWnd* pParent /*=nullptr*/)
    11. : CDialogEx(IDD_PAGE_0, pParent)
    12. {
    13. }
    14. CUIWnd_0::~CUIWnd_0()
    15. {
    16. }
    17. void CUIWnd_0::DoDataExchange(CDataExchange* pDX)
    18. {
    19. CDialogEx::DoDataExchange(pDX);
    20. }
    21. BEGIN_MESSAGE_MAP(CUIWnd_0, CDialogEx)
    22. ON_BN_CLICKED(IDC_BUTTON1, &CUIWnd_0::OnBnClickedButton1)
    23. END_MESSAGE_MAP()
    24. // CUIWnd_0 消息处理程序
    25. void CUIWnd_0::OnBnClickedButton1()
    26. {
    27. char buff[] = {
    28. 0xA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    29. 0x00, 0x00, 0x00, 0x00, 0x00, 0x4, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 00 ,0x00,
    30. 0x00, 0x07, 0x0E, 0x00, 0x00, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x31, 0x00, 0x32 ,0x00,
    31. 0x33, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    32. };
    33. WinSock->OnSend(buff, sizeof(buff));
    34. }

    GameWinSock.cpp文件的修改:新加 OnSend函数、_OnSend函数指针变量

    1. #include "pch.h"
    2. #include "GameWinSock.h"
    3. #include "extern_all.h"
    4. GameWinSock::PROC GameWinSock::_OnConnect{};
    5. GameWinSock::PROC GameWinSock::_OnSend{};
    6. // 这个函数拦截了游戏的连接
    7. bool GameWinSock::OnConnect(char* ip, unsigned port)
    8. {
    9. // this是ecx,HOOK的点已经有ecx了
    10. WinSock = this;
    11. bool b = (this->*_OnConnect)(ip, port);
    12. // 下方注释的代码时为了防止多次注入,导致虚函数地址不恢复问题导致死循环,通过一次性HOOK也能解决
    13. /*unsigned* vtable = (unsigned*)this;
    14. vtable = (unsigned*)vtable[0];
    15. union {
    16. unsigned value;
    17. bool(GameWinSock::* _proc)(char*, unsigned);
    18. } vproc;
    19. vproc._proc = _OnConnect;
    20. DWORD oldPro, backProc;
    21. VirtualProtect(vtable, 0x10x00, PAGE_EXECUTE_READWRITE, &oldPro);
    22. vtable[0x34 / 4] = vproc.value;
    23. VirtualProtect(vtable, 0x10x00, oldPro, &backProc);*/
    24. return b;
    25. }
    26. bool GameWinSock::OnSend(char* buff, unsigned len)
    27. {
    28. /*
    29. 这里就可以监控游戏发送的数据了
    30. */
    31. return (this->*_OnSend)(buff, len);;
    32. }

    GameWinSock.h文件的修改:新加 OnSend函数、_OnSend函数指针变量

    1. #pragma once
    2. class GameWinSock
    3. {
    4. typedef bool(GameWinSock::* PROC)(char*, unsigned);
    5. public:
    6. static PROC _OnConnect;
    7. static PROC _OnSend;
    8. bool OnConnect(char* ip, unsigned port);
    9. bool OnSend(char* buff, unsigned len);
    10. };

    GameProc.cpp文件的修改:修改了 _OnConnect函数

    1. #include "pch.h"
    2. #include "GameProc.h"
    3. #include "extern_all.h"
    4. // typedef bool(GameWinSock::* U)(char*, unsigned);
    5. bool _OnConnect(HOOKREFS2) {
    6. /*
    7. 根据虚函数表做HOOK的操作
    8. 截取 ecx 获取 winsock 的值(指针)
    9. */
    10. unsigned* vtable = (unsigned*)_EDX;
    11. //WinSock = (GameWinSock *)_ECX;
    12. /*
    13. 联合体的特点是共用一个内存
    14. 由于 GameWinSock::OnConnect 的 OnConnect函数是 GameWinSock类的成员函数
    15. 直接 vtable[0x34 / 4] = (unsigned)&GameWinSock::OnConnect; 这样写语法不通过
    16. 所以使用联合体,让语法通过
    17. */
    18. union {
    19. unsigned value;
    20. bool(GameWinSock::* _proc)(char*, unsigned);
    21. } vproc;
    22. DWORD oldPro, backProc;
    23. VirtualProtect(vtable, 0x100, PAGE_EXECUTE_READWRITE, &oldPro);
    24. /*
    25. vproc._proc = &GameWinSock::OnConnect; 这一句是把我们自己写的调用connect函数的地址的出来
    26. */
    27. vproc._proc = &GameWinSock::OnConnect;
    28. /*
    29. InitClassProc函数里做的是给指针赋值的操作
    30. InitClassProc(&GameWinSock::_OnConnect, vtable[0x34/4]);这一句的意思是把
    31. GameWinSock类里的_OnConnect变量的值赋值成vtable[0x34/4],这个 vtable[0x34/4] 是虚表里的函数
    32. vtable[0x34/4]是游戏中调用connect函数的函数地址,经过之前的分析调用connect是先调用了虚表中的
    33. 一个函数,然后从这个函数中调用了connect函数
    34. */
    35. InitClassProc(&GameWinSock::_OnConnect, vtable[0x34/4]);
    36. vtable[0x34 / 4] = vproc.value;
    37. vproc._proc = &GameWinSock::OnSend;
    38. InitClassProc(&GameWinSock::_OnSend, vtable[0x3C / 4]);
    39. vtable[0x3C / 4] = vproc.value;
    40. VirtualProtect(vtable, 0x100, oldPro, &backProc);
    41. return true;
    42. }
    43. GameProc::GameProc()
    44. {
    45. hooker = new htd::hook::htdHook2();
    46. Init();
    47. InitInterface();
    48. }
    49. void GameProc::LoadBase()
    50. {
    51. LoadLibraryA("fxnet2.dll");
    52. }
    53. void GameProc::Init()
    54. {
    55. }
    56. void GameProc::InitInterface()
    57. {
    58. LoadBase();
    59. MessageBoxA(0, "1", "1", MB_OK);
    60. // 只会HOOK一次,一次性的HOOK
    61. hooker->SetHook((LPVOID)0x10617046, 0x1, _OnConnect, 0, true);
    62. }

    1e44a03634714d4b854117a48b882d17.png


     

     

     

     

  • 相关阅读:
    SpringBoot集成Jpa对数据进行排序、分页、条件查询和过滤
    conda虚拟环境配置
    FPGA领域入门佳作,简明深入,夯实基础《FPGA原理和结构》(可下载)
    实战演练-2021年电赛国一之三端口DC-DC变换器
    EMQ(MQTT)安装部署简介
    研究生复试核心竞争力:编程(加分项)
    C高级day3(shell指令)
    typeScript,typeScript语法,typeScript类型、ts变量声明,ts接口interface
    Flink系列之Flink 流式编程模式总结
    99%必用git指令
  • 原文地址:https://blog.csdn.net/qq_36301061/article/details/136330404