空指针
在win32中指针是随机值,但是在arm中指针是NULL。寄存器中值为0x0000000000000000。
下面看一组代码
void func (){
char *b;
char *a = *b;
}
效果如下图:
空指针取值解析
b是一个指针,然后a取b内存地址值赋值给a,然后报错因为空指针里面没有值。
一级指针运算
1.代码
void func (){
char *b;
char *a = b;
char *c = *(a+1);
}
2.运行汇编结果:
指针的偏移
3.解析
这边指针+1意思是偏移一个单位,而这边的单位是由数据类型决定,char为个字节,如果是int会偏移四个字节大家可以自己试一试。
二级指针运算
1.代码
void func (){
char **p1;
char *c = *p1;
char *d = *(p1+1);
}
2.运行结果:
指针的偏移
3.解析:
p1是一个指向指针地址的指针,所以其移动是指针的8个字节,这也印证了指针的运算是根据其所指向类型的宽度决定的。
不同的指针对应相同的汇编代码
1.代码
void func (){
char * p1;
char c = *p1;
char c1 = p1[0];
char d = *(p1+1);
char d1 = p1[1];
}
2.由上面的代码可以看出两两对应其运行结果是一致的,下面看汇编结果:
不同写法相同汇编
3.解析
由上面图片可以看出其虽然代码以不同的方式写的,但是汇编确实以相同方式体现的,这也使得逆向不可能完全还原高级代码。
二级指针反汇编
1、代码
void func (){
char **p1;
char c = **p1;
}
2.运行结果
二级指针反汇编
3.解析
可以看出汇编代码执行步骤
1.将从内存中读取p1的值给寄存器x8。
2.因为p1有一个则去其地址的值,将x8地址的值读取给x8;
3.二级指针最终是指向的char,所以再加是去上一级地址的值获得char类型,因为char类型比较小可以用低32寄存器就够了,最后保存在w9中。
注:这边汇编并没有出现双取值即[[x8]]的代码(也没有这种写法)而是一级一级取地址的h2。
拓展二级指针实例
1.下面代码分别偏移多少
void func (){
char ** p1;
char c = *(*(p1 + 1) + 2);
char d = p1[1][2];
}
2.解析
上面代码大家可以自己运行试试
1.c和d上面例子说了器汇编是一致的。
2.p1指向的是指针其偏移是8,p1指向的是char所以p1偏移是2,一共偏移10.
网友评论