85.网游逆向分析与插件开发-物品使用-物品使用的逆向分析与C++代码的封装

news2024/12/30 3:08:11

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

上一个内容:项目需求与需求拆解-CSDN博客

码云地址(ui显示角色数据 分支):https://gitee.com/dye_your_fingers/sro_-ex.git

码云版本号:453dd83d54140d2e1ee65c915ed2cede543f7400

代码下载地址,在 SRO_EX 目录下,文件名为:SRO_Ex-物品使用的逆向分析与C++代码的封装.zip

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

提取码:q9n5

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

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

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

提取码:78h8

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

以 82.网游逆向分析与插件开发-背包的获取-装备栏数据与算法的C++还原-CSDN博客 它的代码为基础进行修改

选择从网络的地方去下手,因为网络这个东西是它肯定避不开的环节,这是一个非常好的下手点,网络游戏整个逆向,或者说但凡有统一,就是所有东西都会访问一个函数,这种反而会分析起来难度比其它的难度要低非常多。

然后梳理一下思路,首先使用物品这时发出ui的消息,这个时候它一定会换算成网络消息,然后网络消息会经过一个组合,然后经过一个加密,然后经过一个发送,这就是它的一个大概的情况,这整个流程里面,只有一个最好切入,就是发送这个地方最好切入,使用ui的地方消息太多了,处理起来肯定会很麻烦,然后组合什么的都是算法,这东西没有一个明确的点没有一个明确的特征所以找不着,然后到了发送的地方,就简单了,因为网络的发送就是围绕着send函数和wsasend函数或sendto等函数,所以可以对这几个函数下断点来回溯它整个过程,然后分析过程中有一个要点,就是分析的时候会发现一个问题,发现它用了send函数或wsasend函数,这个时候一路往回找,但是要在哪停呢?比如第一次找去找到跟ui相关的,跟ui相关的会看到跟消息有关的函数,然后接下来再往后,这个时候要随时观察函数的参数,只要在参数里发现可以辨别的东西,那这个东西就基本找到了,所以有几个东西是需要密切关注的,比如物品的指针,或者说数组它的序号等这些信息比较重要,所以要随时观察,什么时候出现了这些数据就很关键,就知道什么时候停了。

然后打开x96dbg下断点,首先是send函数

然后是sendto函数,sendto一般在聊天软件里用的比较多

然后WSASend函数,它可以实现iocp(iocp例子),它是异步的,在新的游戏里用的比较多

然后可以发现WSASend会触发断点,那基本上就可以确认是它了,然后它会不停的断下来,会有干扰

然后游戏不动它也会停下来,原因是,游戏为了保证安全它有心跳包,这个时候最好找到它的长度通过条件断点筛选掉,或者眼疾手快点,然后使用物品,使用一个药物,然后它的id是应该是5912或者5913,然后因为现在以及知道它背包的物品是一个指针的数组,所以如果服务器响应这个东西,就要告诉服务器要用哪个物品,所以应该会给服务器发送一个可以证明是哪一个物品的数据,如果是数组的话使用序号的可能性要大,然后下图红框位置的物品数组下标是22,然后也可能是5912或者5913,所以看到这几个数据要敏感

然后接下来眼疾手快一点使用物品,然后就断下来了

 然后断点住后,把断点取消掉,再往上跟否则它会乱

然后一直ctrl+f9,再按f8,大致的过一遍,看看到什么位置就过不去了,然后就会看到在下图红框位置就结束了,这说明在循环里,然后下图红框位置附近有Sleep函数,这个Sleep函数一般跟消息靠的比较近,现在就大概知道它是一个什么情况了,函数很长,然后接着往下看

这么长的函数该怎样处理?首先要分清楚它的一个结构,就是游戏它有各种操作,比如a操作使用物品,b操作走路,c操作心跳包,d操作使用技能,它们都会走到网络的部分发送数据,刚刚经历的一系列函数,假设a是使用物品,那么它有一部分是属于a使用物品的,它的前面还有ui管理或者消息管理的一部分,如果要精确的找到a的过程,才能去分析它,刚刚的一系列操作该怎样排除ui或者send呢?倒着分析的逻辑的话是不需要排除ui的,只需要排除网络的部分,不可能在WSASend函数分析使用物品的逻辑,所以该怎样排除WSASend函数?然后ABCD这四个操作它基本上是共用或者部分共用这个send函数,就是共用网络发送的部分,网络发送的函数它一定是由N个函数构成,也就是说在ABCD所有的操作它到最后都会跑到send函数里,如果现在处在A的操作里面就会只有A操作能触发,就比如走路它就一定不触发A操作,使用使能也不会触发A操作,只有使用物品触发A操作,所以通过这一点就可以很容易的定位到A操作,所以接下来重新回到WSASend函数里,ctrl+f9再按f8每按一次都在上一行代码(调用函数的位置)打断点,然后走路或者执行一个非使用物品的操作,看看是否还会触发断点,如果触发就接着在断点位置使用一次物品,然后继续往上跟(ctrl+f9再按f8这个操作),然后一路这样打断点做非使用物品的操作,最终来到下图位置0x860A43,它并不会被其它操作影响,只会在使用物品的时候断下来

但是这个函数并不怎样理想,它的参数看不懂,ecx的数据也看不懂,这没关系,因为游戏它组织数据的时候一定也是循序渐进的,所以就继续往前找,一定能找到一个能看懂的地方,这个时候才好切入

然后ctrl+f9再按f8来到上一层,关键点 0x74688F

然后它的参数0x85F640函数的入参,它有三个入参,通过0x85F640函数的返回也就是ret位置看出的它是ret c,所以是三个参数,然后通过下图可以看出其中一个参数是索引,使用的物品正好是22

然后使用第一个物品,eax的值是0,所以它是索引,然后0x85F640函数就是使用物品的函数,它是0x1256E3C类里的成员函数,这个0x1256E3C之前已经用C++封装过了,也就是SRO_Control类的成员函数

效果图:可以正常使用物品了

总结:

在盲分析的情况下,可以发现是非常需要依赖参数的,能看懂参数会省很大的劲,可以尝试在0x74688F位置往上跟一层,看看它的入参,看看它的触发机制,还有下图所示的物品栏,是不是也能通过 0x74688F 位置分析到

新加按钮:

GameBase.cpp文件的修改,修改了 Init函数

#include "pch.h"
#include "GameBase.h"

GameBase* _pgamebase;

void GameBase::Init()
{
	unsigned* addrRead = (unsigned*)0x1256E3C;

	SRO_Res = (PRes)0x1036518;
	SRO_Control = (PControl)addrRead[0];
	addrRead = (unsigned*)0x1037D3C;
	SRO_Player = (PAIM)addrRead[0];
	
	InitClassProc(&Res::_ReadTitle, 0x9A46C0);
	InitClassProc(&Res::_ReadItemTitle, 0x9A4640);
	InitClassProc(&Control::_NormalNotice, 0x848580);
	InitClassProc(&Control::_NetNotice, 0x844E40);
	InitClassProc(&Control::_ChatNotice, 0x844E80);
	InitClassProc(&Control::_GetPPack, 0x866140);
	InitClassProc(&Control::_UseItem, 0x85F640);
	InitClassProc(&ITEM::_GetItemRes, 0x995800);
	InitClassProc(&Pack::_GetPackPack, 0x7722C0);
	InitClassProc(&Pack::_GetEquipPack, 0x772300);

}

void GameBase::InitClassProc(LPVOID proc_addr, unsigned value)
{
	unsigned* uWrite = (unsigned*)proc_addr;
	uWrite[0] = value;
}

GameBase::GameBase()
{
	_pgamebase = this;
	// Init();// 初始化机制,完成游戏与我们dll的对接
}

Control.h文件的修改,新加 PROC_D_D_D函数指针类型、_UseItem函数指针变量、UseItem函数声明

#pragma once
#include "SRO_String.h"
#include "Pack.h"
typedef class Control
{
	typedef PPack (Control::* PROC)();
	typedef void (Control::* PROC_PSROSTR)(PSROSTRING);
	typedef void (Control::* PROC_D_PWSTR_D_D)(int, wchar_t*, int, int);
	typedef void (Control::* PROC_D_D_D)(int, int, int);
public:
	static PROC _GetPPack;
	static PROC_PSROSTR _NormalNotice;
	static PROC_PSROSTR _NetNotice;
	static PROC_D_PWSTR_D_D _ChatNotice;
	static PROC_D_D_D _UseItem;
public:
	void NormalNotice(PSROSTRING _txt);
	void NetNotice(PSROSTRING _txt);
	void ChatNotice(wchar_t* _txt, int color=0xFFFFAEC3, int type1=0x3, int type2=0x1);
	void UseItem(int index, int p1 = -1, int p2 = -1);
	PPack GetPPack();
}*PControl;

Control.cpp文件的修改,新加 UseItem函数、_UseItem变量初始化

#include "pch.h"
#include "Control.h"

Control::PROC Control::_GetPPack{};
Control::PROC_PSROSTR Control::_NormalNotice{};
Control::PROC_PSROSTR Control::_NetNotice{};
Control::PROC_D_PWSTR_D_D Control::_ChatNotice{};
Control::PROC_D_D_D Control::_UseItem{};

void Control::NormalNotice(PSROSTRING _txt)
{
	(this->*_NormalNotice)(_txt);
}

void Control::NetNotice(PSROSTRING _txt)
{
	(this->*_NetNotice)(_txt);
}

/**
	type1 默认0x3
	type2 默认0x1
*/
void Control::ChatNotice(wchar_t* _txt, int color, int type1, int type2)
{
	(this->*_ChatNotice)(type1, _txt, color, type2);
}

void Control::UseItem(int index, int p1, int p2)
{
	(this->*_UseItem)(index, p1, p2);
}

PPack Control::GetPPack()
{
	return (this->*_GetPPack)();
}

CUIWnd_1.cpp文件的修改,新加OnBnClickedButton3函数,OnBnClickedButton3函数是Button3按钮的点击事件处理函数

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

#include "pch.h"
#include "htdMfcDll.h"
#include "CUIWnd_1.h"
#include "afxdialogex.h"
#include "extern_all.h"


// CUIWnd_1 对话框

IMPLEMENT_DYNAMIC(CUIWnd_1, CDialogEx)

CUIWnd_1::CUIWnd_1(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_PAGE_1, pParent)
{

}

CUIWnd_1::~CUIWnd_1()
{
}

void CUIWnd_1::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST1, lstPack);
}


BEGIN_MESSAGE_MAP(CUIWnd_1, CDialogEx)
	ON_BN_CLICKED(IDC_BUTTON1, &CUIWnd_1::OnBnClickedButton1)
	ON_BN_CLICKED(IDC_BUTTON2, &CUIWnd_1::OnBnClickedButton2)
	ON_BN_CLICKED(IDC_BUTTON3, &CUIWnd_1::OnBnClickedButton3)
END_MESSAGE_MAP()


// CUIWnd_1 消息处理程序


void CUIWnd_1::OnBnClickedButton1()
{
	// int count = _pgamebase->SRO_Control->GetPPack()->GetPackBack()->PackCount();
	CString tmp;
	// tmp.Format(L"%d", count);
	// AfxMessageBox(tmp);
	PBackPack _PackBack = _pgamebase->SRO_Control->GetPPack()->GetPackBack();

	lstPack.ResetContent();
	for (int i = 0; i < _PackBack->PackCount(); i++)
	{

		PITEM item = _PackBack->GetItem(i);
		if ((item != NULL) && (item->Type)) {
			tmp.Format(L"[%s][数量:%d][耐久:%d/%d]\n", item->GetNameByWide(), item->Count, item->Durabillty, item->MaxDurabillty);
			lstPack.AddString(tmp);
		}
	}

}


void CUIWnd_1::OnBnClickedButton2()
{
	// int count = _pgamebase->SRO_Control->GetPPack()->GetPackBack()->PackCount();
	CString tmp;
	// tmp.Format(L"%d", count);
	// AfxMessageBox(tmp);
	PEquipPack _PackBack = _pgamebase->SRO_Control->GetPPack()->GetEquipBack();

	lstPack.ResetContent();
	for (int i = 0; i < 13; i++)
	{

		PITEM item = _PackBack->GetItem((EquipType)i);
		if ((item != NULL) && (item->Type > 0)) {
			tmp.Format(L"[%s][数量:%d][耐久:%d/%d]\n", item->GetNameByWide(), item->Count, item->Durabillty, item->MaxDurabillty);
			lstPack.AddString(tmp);
		}
	}
}


void CUIWnd_1::OnBnClickedButton3()
{
	_pgamebase->SRO_Control->UseItem(12);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1420254.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

wpf 数据转换(Bytes 转 KB MB GB)

效果 后端 using ProCleanTool.Model; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Data;namespace P…

RabbitMQ基本使用,docker安装RabbitMQ,SpringBoot整合RabbitMQ

1.拉取镜像 docker pull rabbitmq:3.9.15-management2.运行容器 docker run -d --hostname rabbit1 --name myrabbit1 -p 15672:15672 -p 5672:5672 -e RABBITMQ_ERLANG_COOKIErabbitcookie rabbitmq:3.9.15-management3.访问地址 安装ip加端口号 http://192.168.123.3:156…

ToF传感器在移动机器人中的作用

原创 | 文 BFT机器人 在日新月异的机器人技术领域&#xff0c;技术的无缝整合正引领着人类与机器交互方式的革新潮流。ToF传感器作为变革性创新的一个例子&#xff0c;对移动机器人更好地感知周围环境起到了决定性的作用。 ToF传感器与激光雷达技术在创建深度图方面有着异曲同…

关于虚拟机ubuntu系统无法上网问题

一、虚拟机的连接方式 1、查看自己虚拟机的网络连接方式 选择虚拟机->右键设置->网络适配器 2、拓展——虚拟机的三种网络模式 2.1 首先安装虚拟机后&#xff0c;可以看到主机网络适配器多2张网卡 2.2 在VMware虚拟机中查看网络设置 点击菜单栏编辑 -> 虚拟网络…

C#,数据检索算法之三元搜索(Ternary Search)的源代码

数据检索算法是指从数据集合&#xff08;数组、表、哈希表等&#xff09;中检索指定的数据项。 数据检索算法是所有算法的基础算法之一。 本文发布 三元搜索&#xff08;Ternary Search&#xff09;的源代码。 1 文本格式 using System; namespace Legalsoft.Truffer.Algo…

Linux下安装edge

edge具有及其强大的功能&#xff0c;受到很多人的喜爱&#xff0c;它也开发Linux版本&#xff0c;下面是安装方法&#xff1a; 1.去edge官网下载Linux(.deb)文件。 https://www.microsoft.com/zh-cn/edge/download?formMA13FJ 2.下载之后输入以下指令&#xff08;后面是安装…

华为radius认证

组网需求 如图1所示&#xff0c;用户同处于huawei域&#xff0c;Router作为目的网络接入服务器。用户需要通过服务器的远端认证才能通过Router访问目的网络。在Router上的远端认证方式如下&#xff1a; Router对接入用户先用RADIUS服务器进行认证&#xff0c;如果认证没有响应…

c#窗体捕捉方向键

方法1 实现方法参考代码&#xff1a; private void Form1_Load(object sender, EventArgs e){this.KeyPreview true;}protected override bool ProcessDialogKey(Keys keyData){if (keyData Keys.Left || keyData Keys.Right || keyData Keys.Up || keyData Keys.Down){s…

SpringBoot+SqlServer查询接口

SpringBootSqlServer查询接口 文章目录 SpringBootSqlServer查询接口1. pom环境配置2. common工具包3. 实体类接口映射4. Service层Controller层 需求&#xff1a;根据站号查询前一个小时的所有数据&#xff0c;将数据返回格式为Map<String,List<Map<String,String>…

Java基于SpringBoot+Vue的网上超市管理系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

Linux的bash命令语法

可用点 #!/bin/bash # 文件要以上面开始,.sh结尾的文件不需要# 赋权文件可执行权限 chmod x <fileName># 获取java jar包启动的进程id ps -ef | grep *.jar | grep -v grep | awk {print $2}shell变量 变量命令规则&#xff1a; 只能包含字母、数字、下划线&#xff1…

jsjiami.v6加解密教学

1. 优点 a. 安全性提升 JavaScript 加密可以有效保护源代码&#xff0c;减少恶意用户的攻击风险。 b. 代码混淆 通过混淆技术&#xff0c;可以使代码变得难以阅读和理解&#xff0c;增加破解的难度。 c. 知识产权保护 对于商业项目&#xff0c;JavaScript 加密有助于保护…

GLOBALCHIP GC3909Pin to Pin兼容A3909/allegro电机驱动芯片产品参数分析,应用于摇头机,舞台灯,打印机,白色家电等

GLOBALCHIP GC3909 12V H 桥驱动器芯片替代A3909/Allegro产品概述: GC3909是一款双通道12V直流电机驱动芯片&#xff0c;为摄像机、消费类产品、玩具和其他低压或者电池供电的运动控制类应用提供了集成的电机驱动解决方案。芯片一般用来驱动两个直流电机或者驱动一个步进电机。…

RX-8571SA/NB/LC实时时钟模块规格书

. 内置 32.768 kHz 晶体单元(频率精度调整完毕) .接口类型&#xff1a;I2C-Bus 接口 (400 kHz) .工作电压范围&#xff1a;1.6 V ~ 5.5 V .计时&#xff08;保持&#xff09; 电压范围&#xff1a;1.3 V ~ 5.5 V .低待机电流&#xff1a;220 nA (Typ.) / 3 V .32.768 k…

pod部署prometheus

1、部署node-exporter 2、收集节点信息 curl -Ls http://20.0.0.17:9100/metrics | grep node_cpu_seconds curl -Ls http://20.0.0.37:9100/metrics | grep node_cpu_seconds curl -Ls http://20.0.0.47:9100/metrics | grep node_cpu_seconds 3、创建账号&#xff0c;管理…

【基础算法】1、快速排序快速选择

快速排序思想&#xff1a; 1、找一个分界点。 2、在分界点两边开始调整范围。 3、递归两边&#xff0c;重复。 例题&#xff1a; 给定你一个长度为 n的整数数列。 请你使用快速排序对这个数列按照从小到大进行排序。 并将排好序的数列按顺序输出。 输入格式 输入共两行&#xf…

【软考问题】-- 5 - 知识精讲 - 项目进度管理

一、基本问题 项目进度管理&#xff08;按时完成&#xff09; 1&#xff1a;紧前关系绘图法&#xff1f; 定义&#xff1a;它是创建进度模型的一种技术。别称&#xff1a; PDM、前导图法、单代号网络图&#xff08;只有节点需要编号&#xff09;、活动节点图&#xff08;AON&a…

自动化测试系列 —— UI自动化测试!

UI 测试是一种测试类型&#xff0c;也称为用户界面测试&#xff0c;通过该测试&#xff0c;我们检查应用程序的界面是否工作正常或是否存在任何妨碍用户行为且不符合书面规格的 BUG。了解用户将如何在用户和网站之间进行交互以执行 UI 测试至关重要&#xff0c;通过执行 UI 测试…

git push后,如何撤销git log上的错误注释

修改了本地的代码&#xff0c;执行了下面的操作&#xff0c;提交之后&#xff0c;怎么样修改 git add ********(文件名)//git add 添加修改文件名之后 git commit //git commit 在当前分支提交&#xff0c;编写提交注释 git push //git push 提交修…

基于视觉的移载协作机器人机床上下料末端纠偏算法

摘 要 针对复合机器人在机床上下料中的定位方法,本文主要关注识别机床卡盘和末端作业面的定位。首先分 析了复合机器人在机床上下料过程中的工作原理及其基本结构,包括 AGV (自动导引车)和协作机器人 的功能及特点。然后,详细阐述了如何使用视觉系统和纠偏算法来…