内容参考于:易道云信息技术研究院VIP课
上一个内容:物品丢弃的逆向分析与C++代码的封装-CSDN博客
码云地址(ui显示角色数据 分支):https://gitee.com/dye_your_fingers/sro_-ex.git
码云版本号:5222a6b1e5e96d149823c6887da04e4972dd8a21
代码下载地址,在 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博客 它的代码为基础进行修改
首先来到 0x914E98 位置,0x914E98是功能的分界点
然后交换物品断下来
上图的jmp执行之后,再按ctrl+f9再按f8,就会来到下图位置,下图位置的参数看不懂
所以直接再次ctrl+f9再按f8来到下图位置
然后0x864220这个函数我们在上一个内容中封装过了,用于丢弃物品,现在这个0x864220函数还有交换物品的功能
然后现在要把背包里的第四个物品放到第一个位置,也就是下标3位置的物品放到下标0位置,然后看看它的参数是怎样的
然后它的参数是 46、3、46、0、-1、0,由此可见其中的两个46是背包的id、然后3是发起交换的物品,然后从左边数第一个0是被交换物品,也就是3位置的物品去0位置,0位置的物品去3位置
然后与装备栏的物品交换也可以触发这时参数是 47、6、46、12、1、0,这意思是id47背包里6位置的物品放到id46的背包里的12位置
然后同背包物品交换的参数来自于下图红框位置
装备栏到背包的参数是从下图断点来的
然后背包物品到装备栏不会执行到0x785064位置,但是它也会调用 0x864220 函数
然后它也可以实现堆叠
然后它的-1参数的意思是拆分,看下图,把-1改成0x500
修改为0x500
拆分了物品正好是0x500个,如果全部挪过去就用-1
测试跨物品栏
修改为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::_MangeItem, 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文件的修改:修改了函数名与变量名与函数参数名,详情看码云对比
#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::_MangeItem{};
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);
}
void Control::MangeItem(int fromPackId, int fromPackIndex, int toPackId, int toPackIndex, int count, int un)
{
(this->*_MangeItem)(fromPackId, fromPackIndex, toPackId, toPackIndex, count, un);
}
PPack Control::GetPPack()
{
return (this->*_GetPPack)();
}
Control.h文件的修改:修改了函数名与变量名与函数参数名,详情看码云对比
#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 _MangeItem;
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 MangeItem(int fromPackId, int fromPackIndex, int toPackId, int toPackIndex, int count = 1, int un = 0);
PPack GetPPack();
}*PControl;
CUIWnd_1.cpp文件的修改:修改了 OnBnClickedButton3函数
// 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->MangeItem(0x46, 0x7, 0x0, 0x0);// 丢物品
// _pgamebase->SRO_Control->MangeItem(0x46, 0x1, 0x47, 0x6);// 穿装备
// _pgamebase->SRO_Control->MangeItem(0x46, 0x4, 0x47, 0x6);// 换装备
// _pgamebase->SRO_Control->MangeItem(0x46, 0x10, 0x46, 0x16, -1);// 移动物品
_pgamebase->SRO_Control->MangeItem(0x46, 0x5, 0x46, 0x17, 2000);// 拆分物品
}