现在很多视频都是只是讲如何找基址,而没有说为什么要这样找,所以我来说一下自己的见解。
本小菜第一次发帖,欢迎指正,勿喷
首先讲讲视频里找基址的套路:
1. 找出某个属性的地址
2. 查看是什么地址访问或写入该地址
3. 找到类似mov [eax+110],ebx这样的指令,然后继续搜索eax的值
4. 又找到类似mov ecx,[esi+120]这样的指令,然后步骤1的属性地址可表示为[esi+120]+110,继续搜索esi的值
5. 直到最后找到类似mov [0x00410086],119,这个地址就能表示为[[[[0x00410086]+…]+…]+120]+110
其中这样找的理由就是一般在游戏里某个属性位于某个结构或者类里。
比如这里有n个怪,我找到了其中一个怪的血量,然后怪物的结构定义为:
class monster
{
private:
….
int hp;//怪物血量 +10
int mp; //+14
….
} ;
然后这个血量的地址在汇编里就表示为esi+10,而esi就是这个怪物的对象。
但是一个怪物对象不可能只是单单在这里,不好管理,需要有内存存储,所以第三步搜索eax的值就是寻找哪个内存存储这个地址。
这里我假设有n个怪物,游戏可能会把这n个怪物对象地址放在一个数组里,然后这个esi就表示为mov esi,[ebx+4*eax] 现在血量地址可表示为[ebx+4*eax]+10. ebx为数组首地址,eax为数组下标。
假设游戏里还有很多数组为了方便管理定义一个全局类,实例化一个全局对象,里面保存很多全局配置和一些数组的地址等,定义如下:
class global
{
private:
….
int width;//+4
int height;//+8
….
int * monsterlist;//怪物数组+4EC
int *playerlist;//+4F0
….
} ;
global *G=new global();//这时候定义了一个全局对象,全局变量或者静态变量一般就为[0x00410086]这样的形式
最后血量的地址就表示为 [[0x00410086] +4*eax]+10
PS:
1.为什么有时候得到[eax+10]搜索找不到eax的值,因为有时候eax的来源是
monster monsterlist[100];//sizeof(monster)=0x100,lea eax,[ebx+100*ecx],ebx为数组首地址,ecx为下标,所以根本没有内存存储这个地址
2.有时候最终地址就是局部变量怎么办?用HOOK得到地址
[培训]科锐逆向工程师培训第53期2025年7月8日开班!