美文网首页
iOS逆向-04:if 、循环、switch

iOS逆向-04:if 、循环、switch

作者: 恍然如梦_b700 | 来源:发表于2021-05-02 22:36 被阅读0次
    int g = 12;
    
    int func(int a,int b){
        printf("boy");
        int c = a + g + b;
        return c;
    }
    
    int main(int argc, char * argv[]) {
       
        func(10, 20);
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
    
    image.png

    adrp

    adrp(Address Page)
    内存地址按页寻址

    取常量

    adrp x0, 1
    这句代码的操作如下:
    将1的值左移12位得到0x1000
    将0x1048ae12c的低12位清零得到0x1048ae000
    将0x1000和0x1048ae000相加得到0x1048af000
    add x0, x0, #0xf89
    0x1048af000 + 0xf89 = 0x1048aff89
    此时x0的值为0x1048aff89,这个地址里面存的也就是"boy"

    一个页的大小是4096,而0xFFF为4095,加上1就是0x1000(即4096),所以是1左移12位即可得到一个页的首地址(注:macOS的pageSize是 4k(0x1000),而iPhone的pageSize是16k(0x4000),但是16仍是4的倍数,adrp兼容者mac和iPhone,所以此时定位的仍然是一页数据)

    全局变量也是一样

    image.png

    Hopper反汇编

    image.png image.png
    image.png

    全局变量g = 0xc 也就是12
    也可以通过mach-o来查看


    image.png image.png

    还原代码

    int gl = 12;
    
    int funcC(int a, int b) {
    //    0000000100006118         sub        sp, sp, #0x20                               ; CODE XREF=_main+32
    //    000000010000611c         stp        x29, x30, [sp, #0x10]
    //    0000000100006120         add        x29, sp, #0x10
        
    //    0000000100006124         stur       w0, [x29, #-0x4]
    //    0000000100006128         str        w1, [sp, #0x8]
    //    000000010000612c         adrp       x0, #0x100007000                            ; argument #1 for method imp___stubs__printf
    
    //    0000000100006130         add        x0, x0, #0xf89                              ; "boy"
    //    0000000100006134         bl         imp___stubs__printf
        
        printf("boy");
    //    0000000100006138         ldur       w8, [x29, #-0x4]
        int w8 = a;
    //    000000010000613c         adrp       x9, #0x10000d000
    //    0000000100006140         add        x9, x9, #0x570                              ; _g
        int x9 = gl;
    //    0000000100006144         ldr        w10, x9
    //    0000000100006148         add        w8, w8, w10
        int w10 = x9;
        w8 = w8 + w10;
    //    000000010000614c         ldr        w10, [sp, #0x8]
        w10 = b;
    //    0000000100006150         add        w8, w8, w10
        w8 += w10;
    //    0000000100006154         str        w8, [sp, #0x4]
    //    0000000100006158         ldr        w8, [sp, #0x4]
        
    //    000000010000615c         mov        x0, x8
        int w0 = w8;
    //    0000000100006160         ldp        x29, x30, [sp, #0x10]
    //    0000000100006164         add        sp, sp, #0x20
        return w0;
    }
    

    继续精简还原

    从下往上还原

    int funcC(int a, int b) {
        printf("boy");
        int w8 = a;
        int x9 = gl;
        int w10 = x9;
        w8 = w8 + w10;
    //    w10 = b;
    //    w8 += w10;
    //    int w0 = w8;
    //   return w0;
        return w8+b;//上面几句还原
    }
    
    

    依次类推得到最终结果

    int gl = 12;
    int funcC(int a, int b) {
        printf("boy");
        return a+gl+b;
    }
    
    

    if 语句

    我们看看下面代码的汇编

    int g = 12;
    void func(int a,int b){
        if (a > b) {
            g = a;
        }else{
            g = b;
        }
    }
    
    image.png

    通过上面可以看出if else 判断就是 通过cmp + 标号实现的,大于小于都是通过cmp相减。

    cmp(Compare)比较指令

       CMP 把一个寄存器的内容和另一个寄存器的内容或立即数进行比较。但不存储结果,只是正确的更改标志。
       一般CMP做完判断后会进行跳转,后面通常会跟上B指令!

    • BL 标号:跳转到标号处执行
    • B.GT 标号:比较结果是大于(greater than),执行标号,否则不跳转
    • B.GE 标号:比较结果是大于等于(greater than or equal to),执行标号,否则不跳转
    • B.EQ 标号:比较结果是等于,执行标号,否则不跳转
    • B.HI 标号:比较结果是无符号大于,执行标号,否则不跳转
    • B.LT 标号:比较结果是小于,执行标号,否则不跳转
    • B.LE 标号:比较结果是小于等于,执行标号,否则不跳转
    • B.NE 标号:比较结果是不等于,执行标号,否则不跳转
    • B.LS 标号:比较结果是无符号小于等于,执行标号,否则不跳转
    • B.LO 标号:比较结果是无符号小于,执行标号,否则不跳转
    • B.HI 标号:比较结果是无符号大于,执行标号,否则不跳转
    • B.HS 标号:比较结果是无符号大于等于,执行标号,否则不跳转

    循环

    for (int i = 0; i < 100; i++) {
            nSum = nSum + 1;
        }
    
    image.png

    Switch

    1、假设switch语句的分支比较少的时候(例如3,少于4的时候没有意义)没有必要使用此结构,相当于if。
    2、各个分支常量的差值较大的时候,编译器会在效率还是内存进行取舍,这个时候编译器还是会编译成类似于if,else的结构。
    3、在分支比较多的时候:在编译的时候会生成一个表(跳转表每个地址四个字节)。

    1 .当有三个case时,可以看到汇编和if else if 是一样的


    image.png image.png

    相关文章

      网友评论

          本文标题:iOS逆向-04:if 、循环、switch

          本文链接:https://www.haomeiwen.com/subject/cpbtdltx.html