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

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

上一个内容:物品使用的逆向分析与C++代码的封装-CSDN博客

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

码云版本号:7563f86877c7b6033de49ed035e095a726f9d8fb

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

以  物品使用的逆向分析与C++代码的封装-CSDN博客 它的代码为基础进行修改

首先还是通过上一个内容中写的,在WSASend函数上下断点,一路ctrl+f9,再按f8,找分界点。

最终可以发现,下图位置是最后的分界点,jmp之后会到,移动的话会进入移动的处理函数,使用物品的话进入使用物品的函数,丢弃物品就会去丢弃物品的函数,这里是一个关键点,0x914E98

然后在往上一层由于看不到入参,就又反了一层,然后就来到下图位置 0x8526A6,这里的入参都是写死的,然后又esi是变化的,通过断点可以看出,它是物品的索引,当前丢弃的是弓箭,工具正好处在数组下标2位置

然后为了找ecx的值从哪来的,一路往上反,然后查看ecx的值第一次出现在那,然后就重复ctrl+f9再按f8然后给上一行下断点测试,最终来到下图位置0x70D8B0

ecx它的值会在esi+7C4位置获取,然后通过esi+7C4的写入再跟

然后设置内存写入断点

然后断点放行会发现esi+7C4位置的值会变,所以必须要追一追了,因为找esi没有用了,因为esi+7C4是用来记录一个临时性的东西

 然后来到下图位置,它肯定还有一个写入的地方

第二个写入位置,它的值来自于eax,eax又来自于参数

然后按ctrl+f9再按f8,来到它的上一层,然后看出它是来自于esp+14所以它一定是来自于上一层了,esp寄存器与栈有关,栈一般用来存放入参,或者局部变量

然后到这游戏掉线了重新登录,内存地址都变了,下方的图不要盯着与上方的内存地址不一样,只需要盯着分析方法。

重新登录之后来到0x852127,然后丢弃物品触发0x852127位置的断点,然后按ctrl+f9再按f8,来当上一层,然后这里它的参数来自于edi

通过x96dbg的高亮查看edi是来自于ecx,所以在此来到上一层

然后就来到了下图红框位置

然后ecx的值来自于esi,esi的值来自于一个函数返回值,下图红框里的函数

然后0xC7E420函数里是一个全局变量,所以找到了基址

由于之前掉线了,导致内存地址不一样,所以这里要测试 0x1256c38 的值对不对,然后在内存里显示它

然后发现 0x1256c38 它的值会根据鼠标移动而变化,应该是跟ui有关,不同的窗口由不同的值,把鼠标移动到丢弃物品窗口上,它俩的值是一样的

所以它不稳定,然后它就并不是我们要找的,然后对 0x1256c38 下写入断点

然后返回游戏就直接卡到下图位置了,然后它的数据又是从上一层得到的,所以还要继续往上

这里的参数是通过函数返回值得到的,然后这个位置它会不停的断下来

它 0xC8DE5E位置调用的函数 的入参好像是鼠标的坐标

它的返回值也是与0x1256C38的值一样

然后把它的入参改成999999

返回值就是0,也就是没找到窗口,它的返回值应该是跟ui绑定的一个东西

它的整个逻辑,首先就是它会弹出一个确认窗口,如下图,它弹这个对话框的时候,为了保证后续的操作,所以必须要,传递一个指针给窗口(ui),传的过程,我们现在所处的位置是弹出窗口不按是它也会触发,所以现在是处于弹出窗口的过程,也就是它把指针给ui的过程,真正给的过程我们是跟踪不到,因为这个东西一定在游戏整个ui初始化的时候来跟踪的,所以现在这个地方它得的时候它也没办法得到,它也没有一个固定的方法得到,它只能通过坐标和ui的一个比对来得到这个东西

然后进入0xC7C220函数分析,第一眼看到下图红框位置,它是mov esi, dword ptr ds:[esi+4] cmpesi,deword ptr ds:[edi+4] jne 0xc7c244,这三行代码的意思是,一个链表,esi是链表首地址然后偏移4位置是下一个链表位置,然后edi+4是最后一个链表的位置,所以如果 cmp不相等jne就会执行,就会往上走,很明显是一个链表操作

上图是没找到的跳出方式,下图是找到了跳出的方式,它是通过调用一个函数,通过判断这个函数的返回值是不是0来决定的,如果不是0就跳转,是0就进入下一轮循环

然后下图红框的三行代码,它循环的过程会把esi+4位置拿出来,通过eax重新赋值,赋予的值是从edi里得到的,所以edi是下一个链表位置,这里三行代码就更加确定了这里是链表操作了,到这也就没法追了,因为到这就是遍历ui获取绑定的指针了,绑定过程要去ui初始化里找,但是现在我们要找物品的丢弃,ui初始化是另外一个东西,然后我们的丢弃功能怎么办?

现在要重新思考一下这个问题,目前想用下图 0x8526A6 位置调用的函数,找了一圈分析下来以后,这个函数是使用起来最方便的函数,但是很遗憾,这个函数我们没办法提供它的 ecx,这个使用有个解决方案,就是通过Cheat Engine搜索这个数据,看看能否通过Cheat Engine来把这个问题解决了,这个就有点没有技术含量了,附有技术含量的,数据它是存在关联的,然后不只数据存在关联,函数它也是存在关联的,假设如果这个函数我们来做的话,这个函数会属于谁?要么是物品要么是物品管理的一个结构,所以可以测试它是不是有关,之前找到的物品管理的几个类里的,上一个内容里的ecx是来自于 0x1256E3C,它俩本质上是属于同一种操作,所以可以看一下它

然后就发现 0x1256E3C 的位置的值就是我们要找的ecx,这个 0x1256E3C 是一个很稳定的值,这是第一个解决办法,这个办法需要分清楚这俩函数的作用体系,如果不是0x1256E3C,那也一定是0x1036518或0x1037D3C里的(0x1037D3C是SRO_Player我们的结构,0x1036518是我们的SRO_Res结构),如果都不属于,可以使用 Cheat Engine 搜索去解决这个问题,如果都不行,那就要用封包了(封包后面写),封包解决就非常简单了,如果就是非要跟它干那就只能去ui初始化的时候,因为前面非常清晰的看到它整个逻辑,当丢一个物品的时候会把它写入到一个结构体(应该是某个ui操作的结构体里),这个数据得到的时候是依据坐标来得到的,最后很明显是遍历一遍一遍的找,链表只能去生成链表的地方去找,不管它是不是ui,这个链表的生成一定不是丢物品的过程,所以只能想办法去找到它整个链表生成或者初始化的过程,这里是通过一个比较简单方法,通过数据关联性来解决的,可以发现逆向依赖于关联的能力,不依赖于硬干的能力

效果图:通过自动化助手可以正常丢弃物品

CUIWnd_1.cpp文件的修改:修改了 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->DropItem(3);
}

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(&Control::_DropItem, 0x864220);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.cpp文件的修改:新加 DropItem函数、_DropItem初始化

#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{};
Control::PROC_D_D_D_D_D_D Control::_DropItem{};void Control::NormalNotice(PSROSTRING _txt)
{(this->*_NormalNotice)(_txt);
}void Control::NetNotice(PSROSTRING _txt)
{(this->*_NetNotice)(_txt);
}/**type1 默认0x3type2 默认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);
}void Control::DropItem(int index, int p1, int p2, int p3, int p4, int p5)
{(this->*_DropItem)(p1, index, p2, p3, p4, p5);
}PPack Control::GetPPack()
{return (this->*_GetPPack)();
}

Control.h文件的修改:新加 PROC_D_D_D_D_D_D类型的函数指针、_DropItem函数指针变量、DropItem函数声明

#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);typedef void (Control::* PROC_D_D_D_D_D_D)(int, int, int, 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;static PROC_D_D_D_D_D_D _DropItem;
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);void DropItem(int index, int p1 = 0x46, int p2 = 0, int p3 = 0, int p4 = 1, int p5 = 0);PPack GetPPack();
}*PControl;

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

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

相关文章

NFTScan 与 Merlin Protocol 共同推出 BRC20 Indexer Oracle,于今日正式上线!

近日&#xff0c;NFT 数据基础设施 NFTScan 与 Merlin Protocol 进行战略合作&#xff0c;联合推出了比特币网络原生资产 Indexer Oracle 服务&#xff0c;现在该服务已在 NFTScan 开发者平台上线&#xff0c;任何开发者都可以注册使用&#xff01; Merlin Protocol 是一个专用…

linux 磁盘标签类型MBR转换为GPT

[rootlocalhost /]# fdisk -l 磁盘 /dev/sda&#xff1a;299.4 GB, 299439751168 字节&#xff0c;584843264 个扇区 Units 扇区 of 1 * 512 512 bytes 扇区大小(逻辑/物理)&#xff1a;512 字节 / 512 字节 I/O 大小(最小/最佳)&#xff1a;512 字节 / 512 字节 磁盘标签类…

解读 HTTP 和 HTTPS:有何异同?

超文本传输安全协议&#xff08;HTTPS&#xff09;是建立在超文本传输协议&#xff08;HTTP&#xff09;之上的一种安全网络传输协议。在计算机网络上传输时&#xff0c;HTTPS 通过传输层安全性&#xff08;TLS&#xff09;或它的前身安全套接字层&#xff08;SSL&#xff09;为…

谷歌上架防关联VPS开到和原来一样的IP造成关联?应该怎么选?

随着Google paly的发展&#xff0c;竞争越来越激烈&#xff0c;开发者们也面临的越来越多的挑战。其中&#xff0c;如何降低关联风险是开发者们重点关注的问题。 为了防止开发者账号的滥用或欺诈&#xff0c;谷歌会通过判断账号之间是否存在关联&#xff0c;并对违规账号进行处…

【Vue】二、Vue 组件展示控制的优雅解决方案

vue项目中展示的组件&#xff0c;我平常都是通过v-show进行展示控制&#xff0c;类似这样 通常情况下&#xff0c;一个正常展示组件的流程&#xff0c;是通过前端用户点击触发函数&#xff0c;在函数中对data数据进行操作&#xff0c;从而展示不同的页面 showWork: false, sho…

首次接触共享办公室,有哪些问题需要注意?

随着互联网和创业的发展&#xff0c;越来越多的企业和个人选择共享办公空间作为他们的办公场所。共享办公空间是一种提供灵活的办公模式和配套的设施和服务的空间&#xff0c;可以帮助企业和个人节省成本和空间&#xff0c;提高效率和创新&#xff0c;拓展人脉和资源。但是&…

【C++】STL之空间配置器(了解)

一、什么是空间配置器 空间配置器 &#xff0c;顾名思义就是为各个容器高效的管理空间&#xff08;空间的申请与回收&#xff09;的&#xff0c;在默默地工作。虽然在常规使用 STL 时&#xff0c;可能用不到它&#xff0c;但站在学习研究的角度&#xff0c;学习它的实现原理对…

注册亚马逊店铺用动态IP可以吗?

注册亚马逊店铺可以用动态IP&#xff0c;只要是独立且干净的网线就没问题&#xff0c;亚马逊规则要求一个IP地址只能出现一个亚马逊店铺&#xff0c;若使用不当会导致关联账户。 固定ip可以给我们的账户带来更多的安全&#xff0c;要知道关联问题是亚马逊上的一个大问题&#…

PHP/原生类/Java/Python反序列化总结

PHP反序列化 #方法&属性-调用详解&变量数据详解 对象变量属性&#xff1a; public(公共的):在本类内部、外部类、子类都可以访问 protect(受保护的):只有本类或子类或父类中可以访问 private(私人的):只有本类内部可以使用 序列化数据显示&#xff1a; private 属性序…

python爬虫之豆瓣首页图片爬取

网址&#xff1a;https://movie.douban.com/ import requests from lxml import etree import re url https://movie.douban.com headers {User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.289 Safari/5…

如何快速知道app当前页面是哪一个Activity(2.0升级版)

点我跳转 如何快速知道app当前页面是哪一个Activity 1.0版本 这个版本是用adb 命令实现的&#xff0c;想看的可以看看&#xff0c;学习一下adb 命令。 今天做了一个非常简易的app来直接监控当前页面Activity&#xff0c;效果直接炸裂&#xff0c;效果图如下&#xff1a; 有需要…

详解SpringCloud微服务技术栈:深入ElasticSearch(2)——自动补全、拼音搜索

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位大四、研0学生&#xff0c;正在努力准备大四暑假的实习 &#x1f30c;上期文章&#xff1a;详解SpringCloud微服务技术栈&#xff1a;深入ElasticSearch&#xff08;1&#xff09;——数据聚合 &#x1f4da;订阅专栏&…

Windows断开映射磁盘提示“此网络连接不存在”,并且该磁盘直在资源管理器中

1、打开注册表编辑器 快捷键winR 打开“运行”&#xff0c; 输入 regedit 2、 删除下列注册表中和无法移除的磁盘相关的选项 \HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2\ 3、打开“任务管理器”&#xff0c;重新启动“Windows资源…

Spring Boot第一天

SpringBoot概述 Spring Boot是Spring提供的一个子项目&#xff0c;用于快速构建Spring应用程序 传统方式构建Spring应用程序 导入依赖繁琐 项目配置繁琐 为了简化如此繁琐的配置流程&#xff0c;SpringBoot这一子项目提供了如下特性 SpringBoot特性 起步依赖 本质上就是一个…

代码随想录算法训练营第十六天 | 完全二叉树

目录 完全二叉树 LeetCode 222. 完全二叉树的节点个数 完全二叉树 作者&#xff1a;labuladong 如何求一棵完全二叉树的节点个数呢&#xff1f; // 输入一棵完全二叉树&#xff0c;返回节点总数 int countNodes(TreeNode root);如果是一个普通二叉树&#xff0c;显然只要向…

Camunda中强大的监听服务

文章目录 简介创建工程JavaDelegateTaskListenerExecutionListener部署发起流程CustomExecutionListener开始节点CustomExecutionListenerCustomJavaDelegateCustomExecutionListenerCustomTaskListener用户节点 ExpressionDelegate Expression流程图 简介 Camunda预览了很多接…

MTK8365安卓核心板_联发科MT8365(Genio 350)核心板规格参数

MTK8365安卓核心板是一款高性能的嵌入式处理器产品&#xff0c;基于联发科领先的SoC架构和先进的12纳米工艺。它集成了四核ARM Cortex-A53处理器&#xff0c;每个核心频率高达2.0 GHz&#xff0c;搭载强大的多标准视频加速器&#xff0c;支持高达1080p 60fps的视频解码。此外&a…

【MBtiles数据格式说明】GeoServer改造Springboot番外系列一

一、MBTiles数据格式 MBTiles格式是指由MapBox制定的一种将瓦片地图数据存储到SQLite数据库中并可快速使用、管理和分享的规范&#xff0c;是一种用于即时使用和高效传输的规范。MBTiles既可以用作栅格输入数据存储&#xff0c;也可以用作WMSGetMap输出格式。规范有1.0&#xf…

rp-bf:一款Windows下辅助进行ROP gadgets搜索的Rust库

关于rp-bf rp-bf是一款Windows下辅助进行ROP gadgets搜索的Rust库&#xff0c;该工具可以通过模拟Windows用户模式下的崩溃转储来爆破枚举ROP gadgets。 在很多系统安全测试场景中&#xff0c;研究人员成功劫持控制流后&#xff0c;通常需要将堆栈数据转移到他们所能够控制的…

第一批 Apple Vision Pro 开箱和佩戴体验新鲜出炉!!!

注: 本文转自微信公众号 BravoAI (专注AI资讯和技术分享), 原文网址:第一批 Apple Vision Pro 开箱和佩戴体验新鲜出炉!!!, 扫码关注公众号 编者按: 整个AR/VR行业都在等AVP, 期待它能带来ChatGPT般的冲击 AVP(Apple Vision Pro) 是苹果公司研发的第一款"空间计算 (Spa…