美文网首页
iOS逆向之函数本质

iOS逆向之函数本质

作者: 聚朋友iOS | 来源:发表于2021-03-30 11:45 被阅读0次


        栈:是一种具有特殊的访问方式的存储空间(后进先出, Last In Out Firt,LIFO)

    SP和FP寄存器   

            sp寄存器在任意时刻会保存我们栈顶的地址 

            fp寄存器也成为x29寄存器属于通用寄存器,但是在某些时刻我们利用它保存栈底的地址

            注意:ARM64开始,取消32位的 LDM,STM,PUSH,POP指令! 取而代之的是ldr\ldp str\stp

    ARM64里面 对栈的操作是16字节对齐的!!

    注意,注意,注意:以前的栈:是往里放一个数据,sp往上挪一格,出去一个往下挪一格;也就是push,pop。但是现在的ARM64中是先开辟一块空间(可能是空的),sp指向栈顶,然后再往里面放东西。

    iOS中栈的开口方向是往低地址,编译器通过编译代码来决定开辟栈空间的大小。局部变量,参数等放在占空间中。

    函数调用栈

    常见的函数调用开辟和恢复的栈空间(开辟栈空间是往低地址开辟)

    sub sp, sp, #0x40 ; 拉伸0x40(64字节)空间

    stp    x29, x30, [sp, #0x30]    ;x29\x30 寄存器入栈保护

    add    x29, sp, #0x30            ; x29指向栈帧的底部

    ...

    ldp    x29, x30, [sp, #0x30]    ;恢复x29/x30 寄存器的值

    add    sp, sp, #0x40            ; 栈平衡

    ret

    关于内存读写指令

        注意:读/写 数据都是往高地址读/写

    str(store register)指令

    将数据从寄存器中读出来,存到内存中。

    ldr(load register)指令

    将数据从内存中读出来,存到寄存器中

    此ldr 和 str 的变种 ldp 和 stp 可以操作2个寄存器。

    堆栈操作练习

    使用32个字节空间作为转程序的栈空间,然后利用栈将x0和x1的值进行交换

    sub    sp,sp, #0x20   ;拉升栈空间32个字节(0x20是16进制数)

    stp     x0,x1,[sp , #0x10]  ;sp往上加16个字节,存放x0 和x1 

    ldp     x1,,x0, [sp , #0x10] ;将sp 偏移16个字节的值取出来,放入x1 和 x0

    bl和ret指令

    bl标号   

        将下一条指令的地址存放入lr(x30)寄存器

        转到标号处执行指令

    上面图解释:

           调用函数A,断点进入,执行到bl指令那步,然后执行进入函数A中,此时的lr寄存器存的值 0x0000000104505f64    就是在bl执行前的下一个指令的地址。

          lr寄存器的作用:bl跳进A函数中,执行到ret时,会跳回lr的地址;简言之lr保存的是返回的地址,回家的路。

    ret

        默认使用lr(x30)寄存器的值,通过底层指令提示CPU此处作为下调指令地址!

        ARM64平台的特殊指令,它面向硬件做了优化处理的

    x30寄存器

    x30寄存器存放的是函数的返回地址,当ret指令执行时刻,会寻找x30寄存器保存的地址值


    相关文章

      网友评论

          本文标题:iOS逆向之函数本质

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