iOS 逆向开发06:指针相关的汇编

iOS 逆向开发 文章汇总

目录

  • 一、指针基础
    1.1 指针的大小、1.2 指针的运算
  • 二、指针的汇编
    2.1普通指针、2.2 数组指针、2.3 指针取值、2.4 多级指针


一、指针基础

1.1 指针的大小

void func() {
    int *a;
    printf("%lu",sizeof(a));
}

int main(int argc, char * argv[]) {
    func();
   
    return 0;
}
003--指针`func:
    0x1046a1ffc <+0>:  sub    sp, sp, #0x20             ; =0x20 
    0x1046a2000 <+4>:  stp    x29, x30, [sp, #0x10]
    0x1046a2004 <+8>:  add    x29, sp, #0x10            ; =0x10 

    0x1046a2008 <+12>: adrp   x0, 1
    0x1046a200c <+16>: add    x0, x0, #0xe15            ; 将printf的参数%lu(常量区)取出来作为第一个参数
    0x1046a2010 <+20>: mov    x8, sp
->  0x1046a2014 <+24>: mov    x9, #0x8
    0x1046a2018 <+28>: str    x9, [x8]                  ; 直接将指针的大小#0x8保存到栈顶作为第二个参数传递
    0x1046a201c <+32>: bl     0x1046a239c               ; symbol stub for: printf

    0x1046a2020 <+36>: ldp    x29, x30, [sp, #0x10]
    0x1046a2024 <+40>: add    sp, sp, #0x20             ; =0x20 
    0x1046a2028 <+44>: ret 

从汇编中可以看到指针的宽度是8个字节, sizeof的本质就是一个操作符:sizeof(int)=4


1.2 指针的运算

思考以下fucn函数的输出
指针的加法:

void func() {
    int *a;
    a = (int *)100;
    printf("%d",a);
}

void func() {
    int *a;
    a = (int *)100;
    a++;
    printf("%d",a);
}

void func() {
    char *a;
    a = (char *)100;
    a++;
    printf("%d",a);
}

void func() {
    int **a;
    a = (int **)100;
    a++;
    printf("%d",a);
}

void func() {
    int **a;
    a = (int **)100;
    a = a + 1;
    printf("%d",a);
}

指针的减法:

void func() {
    int *a;
    a = (int *)100;
    int *b;
    b = (int *)200;
    
    int x = a - b;
    printf("%d",x);
}




答案:

加法:100、104、101、108、108
减法:-25:指针的运算单位是指向的数据类型的宽度!!

指针的自增自减和执行的数据类型的宽度有关!
类型可以强制转换,但是结构体和基本数据类型不能强制转换。任何变量都可以使用&获取地址


二、指针的汇编

2.1普通指针

void func() {
    int *a;
    int b = 10;
    
    a = &b;
    printf("hello");
}

003--指针`func:
->  0x1044b1ff8 <+0>:  sub    sp, sp, #0x20             ; =0x20 
    0x1044b1ffc <+4>:  stp    x29, x30, [sp, #0x10]
    0x1044b2000 <+8>:  add    x29, sp, #0x10            ; =0x10 

    0x1044b2004 <+12>: add    x8, sp, #0x4              ; x8指向sp+ #0x4地址
    0x1044b2008 <+16>: mov    w9, #0xa                  ; w9 = 10
    0x1044b200c <+20>: str    w9, [sp, #0x4]            ; 将10存储到sp+#0x4地址
    0x1044b2010 <+24>: str    x8, [sp, #0x8]            ; 将x8指向sp+#0x4地址保存到sp+#0x8地址
    0x1044b2014 <+28>: adrp   x0, 1
    0x1044b2018 <+32>: add    x0, x0, #0xe15            ; 取出“hello”字符串常量 
    0x1044b201c <+36>: bl     0x1044b239c               ; symbol stub for: printf

    0x1044b2020 <+40>: ldp    x29, x30, [sp, #0x10]
    0x1044b2024 <+44>: add    sp, sp, #0x20             ; =0x20 
    0x1044b2028 <+48>: ret 


2.2 数组指针:

void func() {
    int arr[5] = {1,2,3,4,5};
    
    for (int i = 0; i < 5; i++) {
        printf("%d",arr[i]);
        printf("%d",*(arr + 1));
        // int *a == &arr[0] == arr
    }
    
    printf("\nhello");
}


2.3 指针取值:

void func() {
    int *p1;//指针 --> (X8)0x0
    char c1 = *p1;//从p1地址取值
}

003--指针`func:
    0x104f2602c <+0>:  sub    sp, sp, #0x10             ; 拉伸栈空间
    0x104f26030 <+4>:  ldr    x8, [sp, #0x8]            ; x8表示p1指针的默认值0x0
->  0x104f26034 <+8>:  ldr    w9, [x8]                  ; 从0x0地址取值--->Crash
    0x104f26038 <+12>: strb   w9, [sp, #0x7]
    0x104f2603c <+16>: add    sp, sp, #0x10             ; =0x10 
    0x104f26040 <+20>: ret    


void func() {
    int *p1;//指针 --> (X8)0x0
    char c1 = *p1;//[x8]
    char d = *(p1 + 1);//[x8,#0x4]------>重点是加4
}

003--指针`func:
->  0x1021fe020 <+0>:  sub    sp, sp, #0x10            ; 拉伸栈空间 
    0x1021fe024 <+4>:  ldr    x8, [sp, #0x8]           ; x8表示p1指针的默认值0x0
    0x1021fe028 <+8>:  ldr    w9, [x8]                 ; 从0x0地址取值--->Crash
    0x1021fe02c <+12>: strb   w9, [sp, #0x7]           ; 存储c1变量到w9

    0x1021fe030 <+16>: ldr    x8, [sp, #0x8]           ; x8表示p1指针的默认值0x0
    0x1021fe034 <+20>: ldr    w9, [x8, #0x4]           ; 计算*(p1 + 1)
    0x1021fe038 <+24>: strb   w9, [sp, #0x6]           ; 存储d变量到w9
    0x1021fe03c <+28>: add    sp, sp, #0x10            ; =0x10 
    0x1021fe040 <+32>: ret  


2.4 多级指针:

void func() {
    char **p1;
    char c = **p1;
}

003--指针`func:
->  0x1042b2028 <+0>:  sub    sp, sp, #0x10             ; =0x10 
    0x1042b202c <+4>:  ldr    x8, [sp, #0x8]
    0x1042b2030 <+8>:  ldr    x8, [x8]
    0x1042b2034 <+12>: ldrb   w9, [x8]                  ;两次指针地址取值
    0x1042b2038 <+16>: strb   w9, [sp, #0x7]
    0x1042b203c <+20>: add    sp, sp, #0x10             ; =0x10 
    0x1042b2040 <+24>: ret 
void func() {
    char **p1;
    char c = *(*(p1 + 2) + 2);
}

003--指针`func:
->  0x100b96028 <+0>:  sub    sp, sp, #0x10             ; =0x10 
    0x100b9602c <+4>:  ldr    x8, [sp, #0x8]

    0x100b96030 <+8>:  ldr    x8, [x8, #0x10]           ; 第一次+0x10
    0x100b96034 <+12>: ldrb   w9, [x8, #0x2]            ; 第二次+0x2

    0x100b96038 <+16>: strb   w9, [sp, #0x7]
    0x100b9603c <+20>: add    sp, sp, #0x10             ; =0x10 
    0x100b96040 <+24>: ret    

你可能感兴趣的:(iOS 逆向开发06:指针相关的汇编)