游戏逆向之静态基址和动态基址
静态基址#
静态基址是指程序中实现定义好的数据(全局数据或局部数据),这种地址在程序每一次加载时都是唯一的不会变化(不考虑ALSR,如果存在ALSR则静态地址相对于程序基地址的偏移不会变)。
动态基址#
动态基址是指程序中通过new或者malloc从堆中申请返回的地址,这种地址在程序每一次加载时都可能会变化。
通过动态基址寻找静态基址#
静态基址一般通过多级指针指向动态基址,我们先找到动态基址后回溯得到多级指针,最后得到静态基址。
通过CE搜索功能回溯#
接着我们找到哪个地方访问的这个地址,发现add eax,[edx+00005560]这条指令访问了这个地址,而edx的值为0x1A761CD8
接着搜0x1a761cd8的值,并查看谁访问的他。发现cmp dword ptr [eax+00000768],00指令访问了这个地址,eax值为0x02859C70
接着搜0x02859C70的值,并查看谁访问的他。发现静态地址0x006A9EC0的值为0x02859c70。
最后总结得出:0x1A767238 = [0x006A9EC0 + 0x768] + 0x5560,即阳光静态基址为0x006A9EC0,一级偏移为0x768,二级偏移为0x5560。
通过汇编代码回溯#
我们寻找第一个卡槽植物的CD时间的动态基址。
我们搜索谁访问的这个地址,发现指令add dword ptr [edi+24],01访问了这个地址,edi等于0x1778CA98。
接着搜0x1778CA98的值发现搜索不到,我们查看add dword ptr [edi+24],01地址处对应的反汇编代码, 发现edi值来源于eax,而eax的值来源上层函数。
我们返回上层函数发现,eax值等于 edi + eax + 28。我们发现此处为一个循环,edi每次增加50,而当eax等于0x1778ca98时,edi等于0。因为eax = edi + eax + 0x28,所以原来的eax = 0x1778ca98 - 0x28 = 0x1778ca70。
那么为什么我们在CE中没有搜索到0x1778CA98的值呢,因为我们在CE中搜索时鼠标的焦点在CE中游戏被暂停了,而当游戏被暂停后下图中更新植物CD时间的函数代码就不会执行了,导致无法搜索到谁访问的地址。
接着搜0x1778ca70的值,并查看谁访问的他。发现指令mov eax,[ebx+00000144]指令访问了这个地址,ebx = 0x1A761CD8.
接着搜0x1A761CD8的值,并查看谁访问的他。发现指令cmp dword ptr [eax+00000768],00指令访问了这个地址,eax = 0x02859c70.
接着搜0x02859c70的值,并查看谁访问的他。发现静态地址0x006A9EC0的值为0x02859c70。
最后总结得出:0x1778CA98 = [[0x006A9EC0 + 0x768] + 0x144] + 0x28,而0x1778CA98 + 0x24处为第一个卡槽植物的CD时间。
并且由上述分析循环处代码可得,卡槽植物对象数组基地址为 [[0x006A9EC0 + 0x768] + 0x144] + 0x28 + 50 * i;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义