[原创] linux 内核安全增强(一)— stack canary-二进制漏洞-看雪-安全社区|安全招聘|kanxue.com
版权声明:本文为CSDN博主「ashimida@」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/lidan113lidan/article/details/120318707更多内容可关注微信公众号 一、背景知识 —— aarch64的函数栈1. 栈生长方向与push/pop操作 栈是一种运算受限的线性表, 入栈的一端为栈顶,另一端则为栈底, 其生长方向和操作顺序理论上没有限定. 而在aarch64平台上:栈是向低地址方向增长的(STACK_GROWS_DOWNWARD)栈的PUSH/POP通常要先移动SP:PUSH操作为PRE_DEC,即 PUSH操作为 sp = sp -4; store;POP操作为 POST_INC,即POP操作为 read; sp=sp+4;2. 返回地址的存储 x86平台是call指令时自动push函数返回地址到栈; ret指令自动pop函数返回地址出栈; 这两步操作都是在callee执行前硬件自动完成的. 而在arm/aarch64平台发生函数调用时(blx),硬件负责将函数的返回地址设置到通用寄存器LR(/X30)中, callee中的代码负责将LR保存到栈中(需保存的寄存器参考AAPCS标准) 3. 函数栈分配 在不考虑动态分配的情况下, 函数中使用的栈大小在编译阶段就已经确定了(见备注1), 一个aarch64中的典型的程序栈如下所示: 和x86/arm平台的不同在于:
x86和arm平台的函数返回地址通常都存于callee栈的栈底:x86平台是硬件完成的push/pop操作,故返回地址先入栈arm平台callee函数的首指令通常是先push通用寄存器, 函数返回前最后语句pop通用寄存器如:000005fc <test>:
5fc: b590 push {r4, r7, lr} /* 先push通用寄存器和函数返回地址 */
5fe: b089 sub sp, #36 ; 0x24 /* 再为局部变量预留存储空间 */
600: af00 add r7, sp, #0
602: 6078 str r0, [r7, #4]
......
634: 3724 adds r7, #36 ; 0x24
636: 46bd mov sp, r7
638: bd90 pop {r4, r7, pc} 在此两个平台中若发生了栈溢出则直接可以覆盖到当前函数的返回地址.而aarch64通常是先预留栈再保存函数返回地址,如:0000000000400654 <test>:
/* 预留栈
栏目分类
- BOA中文网
- Father Of Meme: Origin中文网
你的位置:BOA中文网 > Father Of Meme: Origin中文网 >