背包数据的获取

需求:
在自动化助手的UI界面中,能够实时的显示玩家背包中的数据,以及重要的属性信息,比如数量,名称等

1、分析物品数据属性,还原C++类

2、分析物品基址或者基址获取方法

物品数据的初步分析:

搜索背包的物品数据 初步猜测是数组 相邻的差值都一样

发现改变背包的物品位置,数据也被copy了,直接搜字符串

发现这个地址离太远了,不可能和别的构成数组 ,说明物品是没名字的,而是有物品种类

再由这个数据有一个算法来指向名字

鼠标放上去显示名字 肯定是先有id 然后通过算法 那个算法参数是id 来指向这个名字的位置

所以直接下断,鼠标移向背包装备 触发断点

  发现是有eax读出来的

一直往上走 发现ebx像 物品指针

 直接加上偏移 发现是物品数量

这就是物品指针了。

物品指针-》995800 得到新的指针  +60

关键点:

 获取背包结构:

比较指针

 EBX没变就去找ECX 

一直往上发现ECX一直没变

说明这个体系比较复杂

EAX是46  应该是从这儿来的 

下断发现不是从这来的..

再往前就追到一个和界面有关的地方,鼠标移动就断下。。

追到这就不追了 涉及到UI 就很底层了  这么底层的地方找太难了。

我们得找个和UI没关系的地方

因为物品是独立的 ,写入的操作就也比较独立,访问的话又会涉及到UI的问题,写入就可能可以把UI这块避过去

 

 跟进去往前跳

 这个看起来还好,一上来就看见一个数组结构

ebx是物品指针  通过edi控制这个指针  edi可能是序号或者大小

item[x]    item*[x] 只有这两种可能  点第一个edi是0  第二个edi是1  ...

那么就可以确定这是一个指针数组  那么edi代表物品在背包里的序号,访问估计也就是一个循环0---95了

 超过就异常 包裹大小也就是 /4 得到

也清晰的记录了背包有多少格

背包基址的分析:

esi来自于上级菜单,往上找~

来自于EBX 

这个函数估计就是更新属性的东西

 来自esp+20

 指针从这得来的

再试试金币是不是在包裹里:

很明显在同一个结构体里 :钱也在背包里

物品类的C++还原:

#pragma once
#include"SRO_String.h"
//物品
typedef class ITEM
{
	typedef LPVOID(ITEM::* PROC)();
public:
	static  PROC _GetItemRes;

protected:
	int unknowB1[13];
public:
	int Type;//类型
protected:
	int unknowB4[21];//
public:
	int elv;//装备强化程度
protected:
	int unknowB28[2];
public:
	int MaxDurability;//最大耐久度
	int Count;// 数量
protected:
	int unknowB7[16];
public:
	int MaxPhyAttack;//最大物理攻击力
	int MinPhyAtack;//最小物理攻击力
	int MaxMagAttack;//最大魔法攻击力
	int MinMagAttack;//最小魔法攻击力
protected:
	int unknownnB25[12];
public:
	int Durability;//耐久度
protected:
	int unknownB13[43];
public:
	int plv;//宠物等级
protected:
	int unknownB31[129];
public:
	LPVOID GetItemRes();
	PSROSTRING	GetName();
}*PITEM;
ITEM::PROC ITEM::_GetItemRes{};
LPVOID ITEM::GetItemRes()
{
    LPVOID resPtr = (this->*_GetItemRes)();
    resPtr =(LPVOID)((DWORD)resPtr+0x60);
    return resPtr;
}

PSROSTRING ITEM::GetName()
{
    return _pgamebase->SRO_Res->ReadItemTitle(GetItemRes());
    
}

背包类的C++还原:

#pragma once
#include"ITEM.h"
typedef class BackPack
{
	int unknowmB1[232];
public:
	PITEM* ItemStart;//物品起始地址
	PITEM* ItemEnd;//物品结束地址
protected:
	int unknownB7[22];
public:
	int  PackCount();
	PITEM GetItem(int index);
}*PBackPack
#include "pch.h"
#include "BackPack.h"

int BackPack::PackCount()
{
    int allsize = (DWORD)ItemEnd - (DWORD)ItemStart;
    if (allsize < 0)return 0;
    allsize = allsize / 4;
    return allsize;
}

PITEM BackPack::GetItem(int index)
{
    int max = PackCount();
    if (index < max)
    {
        PITEM pitem = ItemStart[index];
        return pitem;
    }
    return NULL;
}

追加 初始化操作:

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(&ITEM::_GetItemRes, 0x995800);
	InitClassProc(&Pack::_GetPackPack, 0x7722C0);
}

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

GameBase::GameBase()
{
	_pgamebase = this;
	//Init();//初始化基址 完成系统对接
}

装备栏数据结构的分析:
 

直接搜物品数量找 

直接看改写

 发现edx是装备编号. 那么1E0就是装备大小了 这是个数组

 edx是序号 22d0是固定的 看看esi

发现是要找1C301D94的由来

进入函数

 得到基址

装备栏数据与算法C++还原

#pragma once
#include"ITEM.h"
//装备栏

enum class EquipType
{
	har = 0,
	Jacket = 1,
	Shoulder=2,
	Hand = 3,
	Trousers=4,
	Shoe=5,
	Weapon=6,
	WeaponEx=7,
	Ol=8,
	Earring=9,
	NeckLace=10,
	RingLeft=11,
	RingRight=12
};
typedef class EquipPack
{
public:
	PITEM Getitem(EquipType index);
}*PEquipPack;

测试:

void CUIWnd_1::OnBnClickedButton1()
{
	auto _PackBack = _pgamebase->SRO_Control->GetPPack()->GetPackBack();
	lstPack.ResetContent();
	CString tmp;
	for (int i = 0; i < _PackBack->PackCount(); i++)
	{
		auto item = _PackBack->GetItem(i);
		if (item != NULL&&item->Type)
		{
			tmp.Format(L"[%s][数量:%d][耐久:%d/%d]", item->GetNameByWCHAR(), item->Count,
				item->Durability,item->MaxDurability);
			lstPack.AddString(tmp);
		}
	}
}


void CUIWnd_1::OnBnClickedButton2()
{
	auto _PackBack = _pgamebase->SRO_Control->GetPPack()->GetEquipPack();
	lstPack.ResetContent();
	CString tmp;
	for (int i = 0; i < 13; i++)
	{
		auto item = _PackBack->Getitem((EquipType)i);
		if (item != NULL && item->Type>0)
		{
			tmp.Format(L"[%s][数量:%d][耐久:%d/%d]", item->GetNameByWCHAR(), item->Count,
				item->Durability, item->MaxDurability);
			lstPack.AddString(tmp);
		}
	}
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

#A#

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值