基址是什么? 从C++内存模型上来讲, 基址就是一个全局变量, 也就是第一次申明的类的地址。比如有一个类
1 class test
2 {
3 test();
4 ~ test();
5
6 private :
7 char * name_;
8 int hp_;
9 int mp_;
10 role * role_;
11 }
C++的内存模型是这样的。在new test()的时候, 其对象的地址为 this(比如:0x0040320),那成员变量 name的地址为this(因为没有虚函数列表),hp_的地址为this+0x4, mp_的地址为this+0x8, role_的地址就为this+oxC;有比如有如下代码:
1 struct role
2 {
3 string name;
4 int hp;
5 int mp;
6 };
7
8 class game
9 {
10 public :
11
12 game()
13 {
14 role_ = new role;
15 role_ -> hp = 100 ;
16 role_ -> mp = 50 ;
17 role_ -> name = " hello " ;
18 }
19 ~ game()
20 {
21 if (role_)
22 {
23 delete role_;
24 role_ = 0 ;
25 }
26 }
27
28 void start();
29
30 private :
31 role * role_;
32
33 };
34
35 int _tmain( int argc, _TCHAR * argv[])
36 {
37
38 game * myGame = new game();
39
40
41 cout << " hello world " << endl;
42 return 0 ;
43 }
逆向分析都是从数据开始的, 所以我们要找基址的时候就从人物的血、蓝入手,分析出基址。这里以某游戏为列子。
1. 用CE 查找数据。
2. 然后用OD 看谁写入了这个地址。
3. 下硬件断点,看谁往这块内存写东西了。发现是这里:
10A8E9DB 4A DEC EDX 10A8E9DC 23C2 AND EAX,EDX 10A8E9DE 8941 0C MOV DWORD PTR DS:[ECX+C],EAX 10A8E9E1 83C4 14 ADD ESP,14 10A8E9E4 C2 0400 RETN 4
看到代码: MOV DWORD PTR DS:[ECX+C],EAX , 就是往[ecx+c]地址写入血值。
4. 继续看ecx 的值是哪里来的的。此时ecx= 0x091ed200, 用ce 搜索这个值。
5. 取出一个值(0x0aa3e9a8), 看谁访问了这块地址。
这里就可以看出基址为[110F7B58],当前血的地址为[[110F7B58]+0x7F0]+0x0C