【Cheat Engine】官方教程步骤8:多级指针 超详解!

🏛️ 365bet在线体育投注网 ⏳ 2025-08-17 21:55:24 👤 admin 👁️ 2000 💎 721
【Cheat Engine】官方教程步骤8:多级指针 超详解!

目录

1.步骤8的题目

2.指针回顾

复习

四级指针C语言代码

反汇编代码

单步执行分析

画出整个地址图

4.教程解析

5.按CE步骤8教程的设计思路来写模拟多级指针的代码

代码

设计原因

某盘下载链接(压缩包无密码)

代码可视化图片

6.多级指针的应用

7.推荐阅读

1.步骤8的题目

2.指针回顾

复习

19.【C语言】指针(重难点)(A)-CSDN博客

37.【C语言】指针(重难点)(B)-CSDN博客

38.【C语言】指针(重难点)(C)-CSDN博客

39.【C语言】指针(重难点)(D)-CSDN博客

40.【C语言】指针(重难点)(E)-CSDN博客

43.【C语言】指针(重难点)(F)-CSDN博客

44.【C语言】指针(重难点)(G)-CSDN博客

45.【C语言】指针(重难点)(H)-CSDN博客

46.【C语言】指针(重难点)(I)-CSDN博客

47.【C语言】指针(重难点)(J)-CSDN博客

四级指针C语言代码

CE官方教程中用四级指针来训练,那么就以四级指针来分析

int main()

{

int val = 1;

int* p1 = &val;

int** p2 = &p1;

int*** p3 = &p2;

int**** p4 = &p3;

****p4 = 2;//val改成2

return 0;

}

VS2022的属性页改两个地方,之后下断点至return 0,转到反汇编

反汇编代码

int main()

{

push ebp

mov ebp,esp

sub esp,54h

push ebx

push esi

push edi

mov ecx,offset _105D5803_FileName@cpp (06C000h)

call @__CheckForDebuggerJustMyCode@4 (06130Ch)

nop

int val = 1;

mov dword ptr [val],1

int* p1 = &val;

lea eax,[val]

mov dword ptr [p1],eax

int** p2 = &p1;

lea eax,[p1]

mov dword ptr [p2],eax

int*** p3 = &p2;

lea eax,[p2]

mov dword ptr [p3],eax

int**** p4 = &p3;

lea eax,[p3]

mov dword ptr [p4],eax

****p4 = 2;//val改成2

mov eax,dword ptr [p4]

mov ecx,dword ptr [eax]

mov edx,dword ptr [ecx]

mov eax,dword ptr [edx]

mov dword ptr [eax],2

return 0;

xor eax,eax

}

pop edi

pop esi

pop ebx

mov esp,ebp

pop ebp

ret

直接看重点,如何通过p1~p4指针来修改val

mov eax,dword ptr [p4] mov ecx,dword ptr [eax] mov edx,dword ptr [ecx] mov eax,dword ptr [edx] mov dword ptr [eax],2

将上面5条指令按汇编语法压缩成一条指令(虽然实际上不能这样写)

mov dword ptr [dword ptr [dword ptr [dword ptr [dword ptr [p4] ] ] ] ],2

如果不选择代码字节

mov eax,dword ptr [ebp-14h] mov ecx,dword ptr [eax] mov edx,dword ptr [ecx] mov eax,dword ptr [edx] mov dword ptr [eax],2

将上面5条指令按汇编语法压缩成一条指令(虽然实际上不能这样写)

mov dword ptr [dword ptr [dword ptr [dword ptr [dword ptr [ebp-14h] ] ] ] ],2

在逆向破解时可能情况更复杂,会有多个偏移,例如

mov dword ptr [dword ptr [dword ptr [dword ptr [dword ptr [ebp -14h] +0c ] +3 ] +1f ] +1 ],2

单步执行分析

下断点至****p4 = 2;单步分析

先跳到ebp-14h地址处

在寄存器窗口中观察eax寄存器的变化

跳到eax指向的地址

单步执行,观察ecx寄存器变化

跳到ecx指向的地址

单步执行,观察edx寄存器变化

跳到edx指向的地址

单步执行,观察eax寄存器变化

跳到eax指向的地址,发现就是val变量存储的地址

单步执行后,val已经被修改为2了

画出整个地址图

而逆向的过程即从一级指针找到四级指针

4.教程解析

打开CE教程:

输入密码:525927,点确定

载入进程:

按照教程给出的数值搜索:

点击首次扫描:

看到3个有关地址,只有一个是正确的,在教程中单击"改变数值"后再次筛选

只有一个发生变动,

右击,选择"找出是什么访问了这个地址"

单击"Yes"

在教程中单击"改变数值",看看调试器有什么反馈:

发现有一个指令操作了这个值,右击点"详细信息"

mov [esi+18],eax中将eax的值放入esi+18指向的值,那么指针一定和esi有关

(注意记录此时的偏移+18,之后会用到)

复制ESI的值后关闭调试器,勾选HEX,搜索ESI的值

发现只有一个结果,右击"找出是什么访问了这个地址"(注意不是改写,因为没有在教程中单击"改变指针",因此指针并没有变,只不过被访问到了)

再次改变数值,,看看调试器有什么反馈:

选第二个看看:

ESI的值:019A9B10早就在之前搜索过,显然不是正确的地址,排除

选第一个看看:

([esi]等价为[esi+0],注意记录此时的偏移+0,之后会用到)

关闭调试器,搜索ESI的值:

右击,选择"找出是什么访问了这个地址"

再次改变数值,,看看调试器有什么反馈:

选第一个查看详细信息:

选第二个查看详细信息:

(注意记录此时的偏移+14,之后会用到)

发现CE猜测指针的数值都是一样的,关闭调试器,搜索这个数值:

右击,选择"找出是什么访问了这个地址"

再次改变数值,,看看调试器有什么反馈:

选第一个查看详细信息:

选第二个查看详细信息:

(注意记录此时的偏移+0C,之后会用到)

发现CE猜测指针的数值都是一样的,关闭调试器,搜索这个数值:

发现地址已经变成绿色的了,说明019A1298是基地址,每次程序启动这个地址的值都不会改变,

之前记录的偏移依次为:+18 +0 +14 +0C

则用指针访问这个值的方法是: [[[[019A1298 +0C ] +14] +0] +18]

右击,选择"将这个地址添加到地址列表"

在地址列表中双击这个地址来打开更改地址窗口

不要勾选"十六进制",勾选"指针",依次填入偏移量,单击"确定"

教程中单击"改变指针",试着将基址中的值更改为5000,并锁定它

发现下一步按钮变成可点击状态,任务完成

5.按CE步骤8教程的设计思路来写模拟多级指针的代码

理解了上述过程,可以写出如下代码来理解CE教程中设计的多级指针:

代码

#include

#include

using namespace std;

class Myclass4

{

public:

int _val;

bool b = true;

};

class Myclass3

{

public:

int _val=3;

Myclass4* obj3;

};

class Myclass2

{

public:

int _val=0xFF;

char c = 'x';

Myclass3* obj2;

};

class Myclass1

{

public:

char _val='c';

Myclass2* obj1;

short s = 123;

};

int main()

{

cout << "初始化多级指针......" << endl;

static Myclass1* g_obj;

g_obj = new Myclass1;

g_obj->obj1 = new Myclass2;

g_obj->obj1->obj2 = new Myclass3;

g_obj->obj1->obj2->obj3 = new Myclass4;

srand((unsigned int)time(0));

loop:

cout << "按1设置随机值,按其他键退出" << endl;

char c;

cin >> c;

if (c == '1')

{

g_obj->obj1->obj2->obj3->_val = rand() % 101;

cout << "val的值设置为:" << g_obj->obj1->obj2->obj3 ->_val << endl;

goto loop;

}

return 0;

}

设计原因

1. static Myclass1* g_obj;为静态指针,以此来演示基址

2.Myclass1到Myclass2添加了一些成员变量,以此来演示使用指针+偏移的形式访问

3.Myclass1中有Myclass2的指针,Myclass2中有Myclass3的指针,......以此来模拟多级指针

4. g_obj->obj1->obj2->obj3->_val为随机值,可手动变化,这样可使用CE多次搜索

经过尝试,发现如下规律:

保存为CT,下次程序启动时还能找到该值

演示视频:

多级指针详解的演示视频

多级指针详解的演示视频

某盘下载链接(压缩包无密码)

链接: https://pan.baidu.com/s/1rbwUsgMzSF4-2m5X-C9rDQ?pwd=53g7 提取码: 53g7

代码可视化图片

来自:Python Tutor code visualizer: Visualize code in Python, JavaScript, C, C++, and Java

6.多级指针的应用

例如访问二维数组的元素,链表的遍历等,工程中Nginx源码的四级指针等

7.推荐阅读

34.【C语言之外】聊聊CE扫雷(XP版)作弊

41.【C语言之外】聊聊Cheat Engine官方教程步骤6的思考

相关掠夺

365bet在线体育投注网
报税哪个财务软件好一点

报税哪个财务软件好一点

🗓️ 08-17 👁️ 1091
365bet在线体育投注网
酷狗的游戏去哪里

酷狗的游戏去哪里

🗓️ 07-30 👁️ 4118
28365365体育
电子狗的价格分为哪几个档次

电子狗的价格分为哪几个档次

🗓️ 08-09 👁️ 5319