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

内容参考于:易道云信息技术研究院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);
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

量化交易学习3(量化择时策略)

1 什么是量化择时 量化择时策略&#xff0c;简单来说&#xff0c;就是采用数量化分析方法&#xff0c;利用单个或多个技术指标的组合&#xff0c;来对交易标的股票或股票指数进行低买高卖的操作&#xff0c;期望获得超越简单买入持有策略的收益风险表现。 量化择时策略的核心…

网络防御安全知识(第三版)

配置黑洞路由 --- 黑洞路由即空接口路由&#xff0c;在NAT地址池中的地址&#xff0c;建议配置达到这个地址指 向空接口的路由&#xff0c;不然&#xff0c;在特定环境下会出现环路。&#xff08;主要针对地址池中的地址和出接口地址 不再同一个网段中的场景。&#xff09; …

二手交易|校园二手交易小程序|基于微信小程序的闲置物品交易平台设计与实现(源码+数据库+文档)

校园二手交易小程序目录 目录 基于微信小程序的闲置物品交易平台设计与实现 一、前言 二、系统功能设计 三、系统实现 1、用户信息管理 2、商品信息管理 3、公告信息管理 4、论坛信息管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕…

档案数字化转型面临问题

档案数字化转型面临以下问题&#xff1a; 1. 技术问题&#xff1a;档案数字化需要借助先进的技术手段和设备&#xff0c;包括扫描仪、存储设备和数据管理软件等。这些技术的成本高、操作复杂&#xff0c;需要专业的人员进行操作和维护。 2. 安全问题&#xff1a;档案数字化后的…

重写Sylar基于协程的服务器(0、搭建开发环境以及项目框架 || 下载编译简化版Sylar)

重写Sylar基于协程的服务器&#xff08;0、搭建开发环境以及项目框架 || 下载编译简化版Sylar&#xff09; 重写Sylar基于协程的服务器系列&#xff1a; 重写Sylar基于协程的服务器&#xff08;0、搭建开发环境以及项目框架 || 下载编译简化版Sylar&#xff09; 前言 sylar是…

[C语言][C++][时间复杂度详解分析]二分查找——杨氏矩阵查找数字详解!!!

一&#xff0c;题目 遇到的一道算法题&#xff1a; 1&#xff0c;已知有一个数字矩阵&#xff08;row行&#xff0c;col列&#xff09;&#xff0c;矩阵的每行 从左到右 递增&#xff0c;每列 从上到下 递增。 2&#xff0c;现输入一个数字 num &#xff0c;判断数字矩阵中…

Python列表中的append功能及用法举例

Python列表中的append功能及用法举例 &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333;append()&#x1f333;&#x1f340;功能介绍&#x1f340;&#x1f340;语法&#x1f340;&#x1f340;示例&#x1f340;&#x1f340;注意事项&#x…

【Go-Zero】Windows启动rpc服务报错panic:context deadline exceeded解决方案

【Go-Zero】Windows启动rpc服务报错panic:context deadline exceeded解决方案 大家好 我是寸铁&#x1f44a; 总结了一篇Windows11下启动rpc服务报错panic解决方案的文章✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 问题来源 今天在编写完proto文件后&#xff0c;使用goctl生成…

jenkins pipeline配置maven可选参数

1、在Manage Jenkins下的Global Tool Configuration下对应的maven项添加我们要用得到的不同版本的maven安装项 2、pipeline文件内容具体如下 我们maven是单一的&#xff0c;所以我们都是配置单选参数 pipeline {agent anyparameters {gitParameter(name: BRANCH_TAG, type: …

【算法Hot100系列】合并区间

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

【Redis】关于它为什么快?使用场景?以及使用方式?为何引入多线程?

目录 1.既然redis那么快&#xff0c;为什么不用它做主数据库&#xff0c;只用它做缓存&#xff1f; 2.Redis 一般在什么场合下使用&#xff1f; 3.redis为什么这么快&#xff1f; 4.Redis为什么要引入了多线程&#xff1f; 1.既然redis那么快&#xff0c;为什么不用它做主数据…

电路笔记 :MOS场效应晶体管+红外遥控+AMS1117 电源模块

三极管&#xff08;BJT&#xff0c;Bipolar Junction Transistor&#xff09;和 MOSFET&#xff08;Metal-Oxide-Semiconductor Field-Effect Transistor&#xff09;是两种不同类型的晶体管&#xff0c;它们在工作原理、性能特性和应用方面有一些重要的区别。 结构和工作原理…

基于.NET+FreeSql实现的仿掘金专栏前后端分离的CMS

前言 今天分享一款基于.NETFreeSql实现的仿掘金专栏前后端分离、支持Docker部署、集成了OAtuh2授权登录、QQ、Github、Gitee快速登录、简单实用的CMS&#xff1a;lin-cms-dotnetcore。 什么是 Lin CMS&#xff1f; 林间有风团官方团队Gitee地址&#xff1a;https://gitee.com/…

数据库管理-第139期 做大还是做小-Oracle名称哪些事(20240125)

数据库管理139期 2024-01-25 第139期 做大还是做小-Oracle名称哪些事&#xff08;20240125&#xff09;1 问题2 排查3 扩展总结 第139期 做大还是做小-Oracle名称哪些事&#xff08;20240125&#xff09; 作者&#xff1a;胖头鱼的鱼缸&#xff08;尹海文&#xff09; Oracle A…

【硬件产品经理】避免硬件产品失败 | 技术维度

目录 简介 技术维度一&#xff1a;低估产品开发 技术维度二&#xff1a;低估规模生产的复杂性 技术维度三&#xff1a;测试不足 技术维度四&#xff1a;产品太复杂 技术维度五&#xff1a;对客户承诺太高 推荐内容 简介 这节内容主要从技术维度来谈谈避免硬件产品失败这…

指针的深入了解5

1.二维数组传参本质 在此之前我们学习了一维数组传参&#xff0c;传的是它的首元素地址。那么二维数组也是这样的吗&#xff1f; 我们来看一串代码&#xff1a; void print(int(*pt)[5]) {for (int i 0; i < 3; i){for (int j 0; j < 5; j){printf("%d ",…

bert提取词向量比较两文本相似度

使用 bert-base-chinese 预训练模型做词嵌入&#xff08;文本转向量&#xff09; 模型下载&#xff1a;bert预训练模型下载-CSDN博客 参考文章&#xff1a;使用bert提取词向量 下面这段代码是一个传入句子转为词向量的函数 from transformers import BertTokenizer, BertMod…

2024年了,是谁还在学C++11?(没错,是我)

今天要聊的这本书&#xff0c; 是真正畅行全球20年的C入门必读经典&#xff0c;各版本全球总销量超1300万册&#xff01; 它惠及了数百万高校师生&#xff0c;启蒙了5代国产程序员&#xff0c; 令全球数千万C开发者全部为之疯狂的大&#xff01;师&#xff01;名&#xff01…

实现Crm系统的灵活配置,满足不同行业客户需求

目录 一&#xff1a;数据模型配置 二&#xff1a;流程配置 三&#xff1a;扩展性配置 实现CRM系统的可配置性需要关注以下几个方面&#xff1a; 一&#xff1a;数据模型配置 为了满足企业的个性化需求&#xff0c;CRM系统需要提供灵活的数据模型配置。用户可以根据自己的业…

秋招面试—计算机网络安全

2021 计算机网络安全 1.Get 和 Post 的区别 get 用于获取数据&#xff0c;post用于提交数据&#xff1b; get 的缓存保存在浏览器和web服务器日志中&#xff1b; get 使用明文传输&#xff0c;post请求保存在请求体中&#xff1b; get 长度限制在2048以内 2.常见的HTTP请…