背包数据的获取
需求:
在自動化助手的UI界面中,能夠?qū)崟r(shí)的顯示玩家背包中的數(shù)據(jù),以及重要的屬性信息,比如數(shù)量,名稱等
1、分析物品數(shù)據(jù)屬性,還原C++類
2、分析物品基址或者基址獲取方法
物品數(shù)據(jù)的初步分析:
搜索背包的物品數(shù)據(jù) 初步猜測是數(shù)組 相鄰的差值都一樣
發(fā)現(xiàn)改變背包的物品位置,數(shù)據(jù)也被copy了,直接搜字符串
發(fā)現(xiàn)這個(gè)地址離太遠(yuǎn)了,不可能和別的構(gòu)成數(shù)組 ,說明物品是沒名字的,而是有物品種類
再由這個(gè)數(shù)據(jù)有一個(gè)算法來指向名字
鼠標(biāo)放上去顯示名字 肯定是先有id 然后通過算法 那個(gè)算法參數(shù)是id 來指向這個(gè)名字的位置
所以直接下斷,鼠標(biāo)移向背包裝備 觸發(fā)斷點(diǎn)
??發(fā)現(xiàn)是有eax讀出來的
一直往上走 發(fā)現(xiàn)ebx像 物品指針
?直接加上偏移 發(fā)現(xiàn)是物品數(shù)量
這就是物品指針了。
物品指針-》995800 得到新的指針? +60
關(guān)鍵點(diǎn):
?獲取背包結(jié)構(gòu):
比較指針
?EBX沒變就去找ECX?
一直往上發(fā)現(xiàn)ECX一直沒變
說明這個(gè)體系比較復(fù)雜
EAX是46? 應(yīng)該是從這兒來的?
下斷發(fā)現(xiàn)不是從這來的..
再往前就追到一個(gè)和界面有關(guān)的地方,鼠標(biāo)移動就斷下。。
追到這就不追了 涉及到UI 就很底層了? 這么底層的地方找太難了。
我們得找個(gè)和UI沒關(guān)系的地方
因?yàn)槲锲肥仟?dú)立的 ,寫入的操作就也比較獨(dú)立,訪問的話又會涉及到UI的問題,寫入就可能可以把UI這塊避過去
?
?跟進(jìn)去往前跳
?這個(gè)看起來還好,一上來就看見一個(gè)數(shù)組結(jié)構(gòu)
ebx是物品指針? 通過edi控制這個(gè)指針? edi可能是序號或者大小
item[x]? ? item*[x] 只有這兩種可能? 點(diǎn)第一個(gè)edi是0? 第二個(gè)edi是1? ...
那么就可以確定這是一個(gè)指針數(shù)組? 那么edi代表物品在背包里的序號,訪問估計(jì)也就是一個(gè)循環(huán)0---95了
?超過就異常 包裹大小也就是 /4 得到
也清晰的記錄了背包有多少格
背包基址的分析:
esi來自于上級菜單,往上找~
來自于EBX?
這個(gè)函數(shù)估計(jì)就是更新屬性的東西
?來自esp+20
?指針從這得來的
再試試金幣是不是在包裹里:
很明顯在同一個(gè)結(jié)構(gòu)體里?:錢也在背包里
物品類的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;//裝備強(qiáng)化程度 protected:int unknowB28[2]; public:int MaxDurability;//最大耐久度int Count;// 數(shù)量 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;//物品結(jié)束地址 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() {//主要負(fù)責(zé)游戲?qū)宇惖某跏蓟痷nsigned* 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();//初始化基址 完成系統(tǒng)對接 }裝備欄數(shù)據(jù)結(jié)構(gòu)的分析:
?
直接搜物品數(shù)量找?
直接看改寫
?發(fā)現(xiàn)edx是裝備編號. 那么1E0就是裝備大小了 這是個(gè)數(shù)組
?edx是序號 22d0是固定的 看看esi
發(fā)現(xiàn)是要找1C301D94的由來
進(jìn)入函數(shù)
?得到基址
裝備欄數(shù)據(jù)與算法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][數(shù)量:%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][數(shù)量:%d][耐久:%d/%d]", item->GetNameByWCHAR(), item->Count,item->Durability, item->MaxDurability);lstPack.AddString(tmp);}} }?
總結(jié)
- 上一篇: Feedforward ANC 主动降噪
- 下一篇: 大数据平台Ambari2.7.4+HDP