《iOS 逆向》004-指针以及指针的反汇编

  1. 指针 64位中 占8个(64Bit)字节
    1. 编译器决定了指针不能做乘法和除法
    2. 指针的运算结果,由它所指向的数据类型的宽度。决定!(即去掉一个星看这个数据类型)
    3. 数据类型可以强制转换的,结构体和基本类型不可转换。任何变量都可以使用&(取地址符)
int* a;
    a = (int *)100;
    a++; 
    printf("%d",a);
打印结果 104
  char* a;
    a = (char *)100;
    a++;
    
    printf("%d",a);
打印结果 101
    char** a;
    a = (char **)100;
    a++;
    
    printf("%d",a);
打印结果 108

指针加减法所得结果需要除以指向类型的宽度(int类型的宽度是4)

int * a;
    a = (int*)100;
    
    int * b;
    b = (int *)200;
    
    int x = a - b;
    printf("%d",x);
    打印结果 -25

指针的反汇编形式(图1 为汇编详解)

高级代码:


    int *a;
    int b = 13;
    a = &b;
    

汇编源码

      0x100c068c4 <+0>:  sub    sp, sp, #0x20             ; =0x20 
栈空间拉伸32个字节(即0x16b5f39a0-->0x16b5f3980)
    0x100c068c8 <+4>:  stp    x29, x30, [sp, #0x10]
x29,x30的值写入sp偏移0x10的栈空间
    0x100c068cc <+8>:  add    x29, sp, #0x10            ; =0x10 
x29指向此时的栈底即(0x16b5f3990)
    0x100c068d0 <+12>: add    x8, sp, #0x4              ; =0x4
    sp偏移0x4(0x16b5f3984)的地址给x8 
    0x100c068d4 <+16>: mov    w9, #0xd
      0xd立即数给w9
    0x100c068d8 <+20>: str    w9, [sp, #0x4]
    0xd立即数 写入栈空间(0x16b5f3984---0x16b5f3980)
    0x100c068dc <+24>: str    x8, [sp, #0x8]
x8的地址0x16b5f3984(立即数的地址)存入到栈空间中0x16b5f3988-0x16b5f3990
    0x100c068e0 <+28>: adrp   x0, 1

    0x100c068e4 <+32>: add    x0, x0, #0xf2c    
图1.jpeg

(内存的读写往高地址走)

C的数组(指针的基本运算)

 int arr[5] = {1,2,3,4,5};
    for (int i = 0; i < 5; i++) {
        //正常打印
        printf("%d",arr[i]);
    }
//arr这个变量指向的就是元素的首地址,相当于指针。
    int arr[5] = {1,2,3,4,5};
    for (int i = 0; i < 5; i++) {
        //指针加一相当于指针偏移int个字节。(arr + 1)是地址
        //取出地址所指向的数据* (arr + 1)
        printf("%d",*(arr + i));
    }

举一反三

    int * a =arr;
    for (int i = 0; i < 5; i++) {
        
        printf("%d",a++);
    }
    //指针的运算
    char ** p1;
    //p1所指向的数据类型是char* 的指针,(p1 + 2)偏移16个地址(0x10)
    //char * 所指向的数据类型是char , *(xxx + 2)偏移两个地址(0x2)
    char c = *(*(p1 + 2) + 2
//和上一句代码的汇编一样。
    char c1 = p1[2][2];
    0x1042c68f0 <+0>:  sub    sp, sp, #0x10             ; =0x10 
    0x1042c68f4 <+4>:  ldr    x8, [sp, #0x8]
->  0x1042c68f8 <+8>:  ldr    x8, [x8, #0x10]
    0x1042c68fc <+12>: ldrb   w9, [x8, #0x2]
    0x1042c6900 <+16>: strb   w9, [sp, #0x7]
    0x1042c6904 <+20>: add    sp, sp, #0x10             ; =0x10 
    0x1042c6908 <+24>: ret 

指针的基本用法

    //下面四句代码,两两的汇编代码是一样的(c&c1;d&d1)如图2
    char c = *p1;
    char c1 = p1[0];
    char d = *(p1 + 1);
    char  d1 = p1[1];
图2.png

二级指针的反汇编

 //多级指针
    char ** p1;
    char c = **p1;
    
    0x10065e8f0 <+0>:  sub    sp, sp, #0x10             ; =0x10 
->  0x10065e8f4 <+4>:  ldr    x8, [sp, #0x8]
    0x10065e8f8 <+8>:  ldr    x8, [x8]
    0x10065e8fc <+12>: ldrb   w9, [x8]
    0x10065e900 <+16>: strb   w9, [sp, #0x7]
    0x10065e904 <+20>: add    sp, sp, #0x10             ; =0x10 
    0x10065e908 <+24>: ret   

参考资料:

--> 一级指针二级指针详解

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容