29.第二阶段x64游戏实战-技能冷却
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!
本次游戏没法给
内容参考于:微尘网络安全
上一个内容:28.第二阶段x64游戏实战-代码实现遍历技能
找技能冷却要通过一个技能cd长点的,太长了改变起来很麻烦,太短的就不好找,所以要不长不短30秒左右的就可以
怎么找,首先技能CD它会有一个倒计时,这个倒计时就是一个入手点,比如使用了一个技能,肯定会把技能cd的时间写到倒计时的内存地址,这时就发生了数据增加,然后等待倒计时就发生了数据减少,就可以利用这一点使用CE搜索
如下图使用未知初始值进行扫描,这里使用的是4字节,如果4字节搜不到技能cd就变其它的比如单浮点
首次扫描完之后,如下图选择增加的数值,然后回到游戏,使用一个30秒左右的技能,然后再点击再次扫描
然后技能cd每减5秒或几秒,使用减少的数值再次扫描,当技能cd变成0后,再次释放技能使用增加的数值进行扫描
最终就剩下这一个了,它的数据跟随释放技能而变化
然后打开x64dbg追基址 0x2861B2DBEA4,使用硬件写入断点
然后释放技能就在下图位置触发了硬件写入断点
然后删除断点,然后按F9,让游戏运行起来
开始分析代码,下图r8是技能CD的地址,然后找r8哪来的
通过释放同一个技能触发下图的断点,发现rdx的值不会变
释放另一个技能rdx的值变了,这里猜测rdx是类似技能id的东西,这里要找技能对象
在技能对象加0x4C(0x48+0x4=0x4C)位置找到了0x6B
现在rdx的问题解决了,还剩下rsi,如下图rsi的值来自于rcx,rcx的值来自于上一层
设置断点
触发断点并取消断点
然后按CTRL+F9再按F8,来到下图位置,这里再按F9让代码运行起来
这里就找到了基址,这个基址是背包的基址,0x00007FF6FC8F97E0 - 0x00007FF6FBFB0000 = 0x9497E0
现在的公式:[[0x00007FF6FC8F97E0]+0x181C0]+技能id*3*4
GameData.cpp文件的修改:
VDataStu GameData::Updata_Skill()
{this->m_Skill.Clear();/*** 0x00007FF634BE0000+0x9490E8获取技能名字的公式[[[[[[[[[0x00007FF634BE0000+0x9490E8]+0x98]+1B0]+0x18]+0x2AB0]+0x8]+0x10]+0x28+0x8]+0x10]获取技能名字的公式[[[[[[[[[0x7FF7625290E8]+0x98]+1B0]+0x18]+0x2AB0]+0x8]+0x10]+0x28+0x8]+0x10]ReadDword64(ReadDword64(ReadDword64(ReadDword64(g_GameBase + 角色基地址) + 0x98) + 0x1b0) + 0x18)相当于[[[[0x7FF7625290E8]+0x98]+1B0]+0x18]*/QWORD addr = ReadDword64(ReadDword64(ReadDword64(ReadDword64(g_GameBase + 角色基地址) + 0x98) + 0x1b0) + 0x18);// [[[[[0x7FF7625290E8]+0x98]+1B0]+0x18]+0x2AB0]QWORD B_number = ReadDword64(addr + 0x2aB0);// [[[[[[0x7FF7625290E8]+0x98]+1B0]+0x18]+0x2AB0]+0x8]// [[[[[[0x00007FF634BE0000+0x9490E8]+0x98]+1B0]+0x18]+0x2AB0]+0x8]QWORD pPoint = ReadDword64(B_number + 8);// 这里的0x30是 0x28+0x8=0x30TraverseSkill(pPoint, 0x30);for (size_t i = 0; i < m_Skill.m_data.size(); i++){m_Skill.m_data[i].m_Objadr = ReadDword64(m_Skill.m_data[i].m_Objadr);m_Skill.m_data[i].m_Name = ReadStrA((char*)ReadDword64(m_Skill.m_data[i].m_Objadr + 0x10));m_Skill.m_data[i].m_ID = ReadDword(m_Skill.m_data[i].m_Objadr);// [[0x00007FF6FC8F97E0]+0x181C0]+技能id * 3 * 4m_Skill.m_data[i].Countdown = ReadDword(ReadDword64(ReadDword64(g_GameBase + 背包基地址) + 0x181c0) + ReadDword(m_Skill.m_data[i].m_Objadr + 0x4c) * 3 * 4);}return this->m_Skill;
}