基地址和偏移地址的理解

基地址和偏移地址的理解

在之前的一篇博客介绍了怎么找阳光地址:CE和Ollydbg简单介绍,但是那个地址在重启游戏后会变化,这次会讲解为什么这个阳光的地址会变化,以及对于变化的地址怎么处理。

推荐博客:CE找基址原理

1.阳光的地址为什么会变化

首先我们需要知道,在代码编译成可执行文件(如exe),代码段和数据段(全局变量、静态变量等)的虚拟内存地址已经固定,重启后依然不变(重新编译才会改变)。有人可能会有疑问,我同事打开多个程序,那么地址不是重复使用了吗?重合的是虚拟地址,它不是内存上的物理地址,虚拟地址会经过操作系统(主要是mmu)映射到物理内存,所以不用担心这个问题。 验证代码如下:

#include

using namespace std;

int g_var;

int main() {

int var = 1;

g_var = 1;

return 0;

}

打断点然后转到反汇编查看: 可以看到全局变量它的地址是固定的,而局部变量是用寄存器来代替,是变化的。

假如我是植物大战僵尸的程序员,我可能会这样编写阳光相关的代码:

//阳光类

#include

using namespace std;

class Sun { //阳光类

public:

int tmp;

int tmp2; //阳光值前面可能有多个值

int sun_value = 100; //阳光值

int tmp3; //阳光值后面可能有多个值

};

class GameData { //数据类

public:

int tmp;

int tmp2; //前面可能有多个值

Sun* sun; //指向Sun类

int tmp3; //后面可能有多个值

};

GameData* g_game_data;

int main() {

g_game_data = new GameData(); //堆区创建游戏数据

g_game_data-> sun = new Sun(); //堆区创建阳光

return 0;

}

这样除了g_game_data地址是固定的(全局变量),其余都是变化的(堆区数据)。 综上,这个阳光地址就是变化的,只不过代码比上面复杂很多,有可能有多级指针(以上只有两个)。

2.怎么通过某个方式找到变化的阳光值

虽然阳光的地址是变化的,但是它可以由上一级地址来表示,而上级地址也可以由它的上级地址来表示,并且一定有一个地址是固定的(数据段中),这个地址就是常说的基地址。因此一个变化的地址一定可以由基址表示。

上面代码的基地址为&g_game_data ,可以用它来表示阳光的地址(基地址+地址偏移):

(*(*&g_game_data + 8) + 8

&g_game_data:全局变量的地址(固定),即基地址

*&g_game_data即g_game_data:GameData 对象地址

*(*&g_game_data + 8):Sun对象地址

(*(*&g_game_data + 8) + 8:sun_value 阳光地址

CE查找阳光的基地址和偏移地址

下面操作找基址,CE的基础使用可以见最上面的那片博客。先按照以下操作找出基地址和每次的偏移量,然后再解释每个值的含义。 第一次搜索: 这里出现了很多结果,需要缩小范围。改变阳光值然后再搜索。 第二次搜索出现一个地址0x1AD04218,这个地址存的就是阳光值(重启会改变):

右键选择什么访问了这个地址:

可以看到有两个结果,随便打开一个(都一样,它们都是使用相同的偏移量来访问的这个地址): 得到了一个地址0x1ACFECB8,0x1ACFECB8(类似Sun对象地址) + 0x5560(偏移量) == 0x1AD04218(动态阳光地址) 其中偏移大小的固定的(类结构决定,编译后就固定了),而这个地址是动态变化的,因为它通过寄存器来使用。顺着找到的这个地址,用这个地址去搜索它被什么访问了(这个地址可以右键复制):

然后观察结果地址,如果前两位地址有重复,极大概率就不是。这样可以挑选出两个满足条件的地址:

然后继续右键找出上面访问了这个地址,先以前面的这个举例,它被以下地址访问: 看到有很多的0x768偏移量,这说明大概率对了,继续看这个地址:

顺着这个地址操作: 绿色的就是基地址了(4个都可以,有可能有4个全局变量指针),选择第一个006A9EC0,它的第一个偏移量768,第二个偏移量5560,因此动态阳光地址表示为(*(*(006A9EC0) + 768 ) + 5560) == 动态阳光地址 可以用CE验证:

3.怎么理解基地址和偏移量

根据前面假设的代码,这几个可以对应:

006A9EC0 对应于 &g_game_data(基地址,全局指针变量) 02ACA248 对应于 GameData 对象地址 02ACA248+0x768 对应于sun成员变量地址 1ACFECB8 对应于 Sun 对象地址 1AD04218 对应于 动态阳光地址

作图如下:

总结

很多时候要查找的代码相隔很远,比如一次偏移就几百个字节,所以经常会遇到干扰信息,需要总结经验才能提高。最稳妥的方式还是使用OD去看汇编代码,通过调试代码才能准确判断。

相关文章

香港华特药房 香港华特药房官网商城
365bet手机端

香港华特药房 香港华特药房官网商城

⌚ 06-28 👁️‍🗨️ 9770
十大经典飞机游戏
365bet手机端

十大经典飞机游戏

⌚ 07-12 👁️‍🗨️ 4268