滴水逆向 02-27 指针2
类型转换
并不是所有的数据类型之间都可以相互转换,比如结构体与基本类型
带 * 的类型可以强制转,比如:
1 | void Test() { |
&符号的使用
& 是地址符,类型是其后面的类型加一个 “*”,任何变量都可以使用 & 来获取地址,但不能用在常量上
1 | char a = 10; |

带 * 类型变量前加 *
- 带 * 类型的变量,可以通过在其变量前加 * 来获取其指向内存中存储的值
- 在带 * 类型的变量前面加 *,类型是其原来的类型减去一个 *
使用 * 来获取 px 指向内存中存储的值:

观察反汇编:
1 | int x, y; |

用指针操作数组
-
&arr[0] 代表取数组中第一个元素的地址,可以省略为数组名
1
2
3
4char arr[10];
char* p = &arr[0]; //取数组第一个元素的地址
char* p2 = arr; //简写 -
*(p+i) = p[i]
为神马 *(p+i) 就是 p[i]?因为通过char* p = &arr[0]知道 p 中存储的是数组的首地址,那么首地址加上 i 再在外面括个 * 就是去访问首地址 + i 的地方
课后作业
-
列出每一行的反汇编代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26char a = 10;
mov byte ptr [ebp-4], 0xA
short b = 20;
mov word ptr [ebp-8], 0x14
int c = 30;
mov dword ptr [ebp-0Ch], 0x1E
char* pa = &a;
lea eax, [ebp-4]
mov dword ptr [ebp-10h], eax
short* pb = &b;
lea ecx, [ebp-8]
mov dword ptr [ebp-14h], ecx
int* pc = &c;
lea edx, [ebp-0Ch]
mov dword ptr [ebp-18h], edx
char** ppa = &pa;
lea eax, [ebp-10h]
mov dword ptr [ebp-1Ch], eax
short** ppb = &pb;
lea ecx, [ebp-14h]
mov dword ptr [ebp-20h], ecx
int** ppc = &pc;
lea edx, [ebp-18h]
mov dword ptr [ebp-24h], edx -
列出每一行的反汇编
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33int p = 10;
mov dword ptr [ebp-4], 0xA
//定义时虽然没有对应的汇编代码,但是已经分配好了位置
int******* p7; //ebp-8
int****** p6; //ebp-0ch
int***** p5; //ebp-10h
int**** p4; //ebp-14h
int*** p3; //ebp-18h
int** p2; //ebp-1ch
int* p1; //ebp-20h
p1 = &p;
lea eax, [ebp-4]
mov dword ptr [ebp-20h], eax
p2 = &p1;
lea ecx, [ebp-20h]
mov dword ptr [ebp-1ch], ecx
p3 = &p2;
lea edx, [ebp-1ch]
mov dword ptr [ebp-18h], edx
p4 = &p3;
lea eax, [ebp-18h]
mov dword ptr [ebp-14h], eax
p5 = &p4;
lea ecx, [ebp-14h]
mov dword ptr [ebp-10h], ecx
p6 = &p5;
lea edx, [ebp-10h]
mov dword ptr [ebp-0ch], edx
p7 = &p6;
lea eax, [ebp-0ch]
mov dword ptr [ebp-8], eax -
删掉了
-
完成代码,实现数组值的互换
要注意输出时用的是 p1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16void Function() {
int arr[5] = {1, 2, 3, 4, 5};
//此处添加代码,使用指针,将数组值倒置
int* p = arr;
for (int i = 0; i < 2; i++) {
int tmp = *(p+i);
*(p+i) = *(p+4-i);
*(p+4-i) = tmp;
}
//打印数组值的代码已经写完,不需要修改
for (int k = 0; k < 5; k++) {
printf("%d\n", *(p+k));
}
}