• 游戏逆向之静态基址和动态基址


    静态基址

    静态基址是指程序中实现定义好的数据(全局数据或局部数据),这种地址在程序每一次加载时都是唯一的不会变化(不考虑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;

  • 相关阅读:
    [Javascript] Object.freeze: using Object.freeze in function params to enforce immutabtility
    [Typescript] Index access types
    [Typescript] Making TypeScript Stick 6 infer, build a ConstructorArg Type
    [Typescript] Filtering properties out
    [TypeScript] Mapped Type
    [Typescript] TS Monorepo setup
    [Typescript] Extract & Exclude
    CSP2020洛谷模拟赛
    2020 CSPJ 初赛排列组合试题解析
    2020 CSPJ 入门组初赛试题和答案
  • 原文地址:https://www.cnblogs.com/revercc/p/16036732.html
Copyright © 2020-2023  润新知