04-安全攻防之bl和ret指令

bl指令

bl指令也成为跳转指令,执行这个指令之前会做两个操作:

  • 将下一条指令的地址放入lr(x30)寄存器
  • 转到标号处执行指令

ret指令

默认使用lr(x30)寄存器的值,通过底层指令提示CPU此处作为下条指令地址! 也就是说,当执行ret指令时,CPU会执行lr(x30)这个寄存器存的内存地址指向的命令。

x30寄存器

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

注意:在函数嵌套调用的时候.需要将x30入栈! 否则会造成死循环。

关于内存读写指令

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

  • str(store register)指令

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

  • ldr(load register)指令

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

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

在这里插入图片描述

bl 和ret的实践

新建一个工程,创建一个汇编的文件,如下图:
在这里插入图片描述
随便取名为:asm.s, 在该文件中,添加如下的代码:

.text
.global _A, _B

_A:
    mov x0, #0xaaaa
    bl _B
    mov x0, #0xcccc
    ret

_B:
    mov x0, #0xbbbb
    ret

在main函数中,定义一个A的函数,并调用,如下图:
在这里插入图片描述
执行代码,打开断点时用汇编显示的设置,显示如下:
在这里插入图片描述
如上图所示,查看pc寄存器的值,是0x10452a1c0,正好是断点的位置;
bl表示即将跳转到0x104529d0c 这个内存地址所存储的函数;
注意:bl 下面的那一行的地址是 0x10452a1c4。
接下来,按住controller 键 + 点击断点的下一步,进入bl 要跳转的函数:
在这里插入图片描述
查看进入函数后,lr寄存器的值已经修改成“0x10452a1c4”,也就是进入A函数之前的下一句地址。
在这里插入图片描述
在控制台中,执行”ni“即下一步的指令,
在这里插入图片描述
这边又有一个bl的指令,那么bl执行之前,又会把下一条指令的地址,存放到lr寄存器上,再进入bl要跳转的函数。contrller+下一步,进入函数,查看:
在这里插入图片描述
此时,lr寄存器的值,已经被修改了。
继续执行,遇到ret 指令,该指令会取出lr寄存器的地址,然后跳转到该地址下。此时,lr寄存器的地址是0x104529d14, 即A函数跳转B函数后的下一条指令,如下图:
在这里插入图片描述
所以,执行完B函数后,会返回到A函数中;
继续单步执行,又会遇到ret,那么又会继续取出lr寄存器的地址值,执行。但是此时,lr寄存器的值为0x104529d14。所以,就会陷入死循环。
因此,如果只是按照上面的那段汇编代码的话,执行main函数的时候,只会打印”1111“,然后陷入死循环。
在这里插入图片描述

那么如何优化呢?这边就需要用到栈。即,在跳转B函数之前,先保存一份lr寄存器的值,再跳转。
优化的代码如下:

.text
.global _A, _B

_A:
    mov x0, #0xaaaa
    str x30, [sp, #-0x10]!
    bl _B
    mov x0, #0xcccc
    ldr x30, [sp], #0x10
    ret

_B:
    mov x0, #0xbbbb
    ret

其中, str x30, [sp, #-0x10]!相当于如下的代码:

    sub sp, sp, #0x10  //把sp的值,减去 10, 在将值放到sp中
    str x30, [sp]      //把x30的值,存放到sp的位置中

ldr x30, [sp], #0x10相当于如下的代码:

ldr x30, [sp]
add sp, sp, #0x10

整体的意思是:

在跳转b函数之前,将lr的地址保存到sp中,
跳转函数之后,lr的值修改成跳回函数A的地址
执行完B的代码,返回到A后,此时若执行完A的代码时,
将保存在sp的lr的值取出来,然后跳回到这个lr的地址的函数。
这样,在跳转函数A之前保存的lr的值,就不会被改变了。

执行的效果如下:
在这里插入图片描述
上图是,进入函数A之后,lr寄存器保存的值;
在这里插入图片描述
上图是,进入函数B后,lr寄存器保存的值;
单步执行,遇到ret,取出lr寄存器的值,跳转:
在这里插入图片描述
当执行完ldr这条指令后,之前保存到sp的值又存储到了lr寄存器上。
在这里插入图片描述
而这个值正好是,跳转到A函数后的下一条指令:
在这里插入图片描述
这样就可以避免死循环了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值