【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改成2return 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改成2mov 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 <iostream>
#include <ctime>
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的思考