06 溢出攻击原理之汇编分析

如c程序的代码:

test.c:
  1
  2 #include <stdio.h>
  3 
  4 int main(void)
  5 {
  6     int buf[10];
  7 
  8     printf("end\n"); //用于让编译器对lr寄存器压栈
  9     return 0;
 10 }

反汇编后得到的代码:

000083cc <main>:
    83cc:       e92d4800        push    {fp, lr}
    83d0:       e28db004        add     fp, sp, #4
    83d4:       e24dd028        sub     sp, sp, #40     // int buf[10]的空间
    83d8:       e59f0010        ldr     r0, [pc, #16]   ; 83f0 <main+0x24>
    83dc:       ebffffb7        bl      82c0 <_init+0x20>
    83e0:       e3a03000        mov     r3, #0
    83e4:       e1a00003        mov     r0, r3
    83e8:       e24bd004        sub     sp, fp, #4
    83ec:       e8bd8800        pop     {fp, pc}
main函数执行时栈里的内容:
  [lr寄存器原内容]
  [fp寄存器原内容]
  [ buf[9]     ]  // &buf[9], 栈的地址从高往低,数组元素的地址是从低往高.
    ...
  [ buf[0]     ]  // &buf[0]
通过数组超界访问,可以改变栈里存放的lr寄存器原内容,可以改为想执行的代码的地址.
实验代码:
      1 
      2 #include <stdio.h>
      3 
      4 void func()
      5 {
      6     printf("in func ...\n");
      7 }
      8 int main(void)
      9 {
     10     int buf[10];
     11     int i = 11;
     12 
     13     buf[i] = (int)func;
     14     buf[i+1] = (int)func;  //这里不是执行,只是把func函数的地址存放在栈里的lr寄存器原内容的位置
     15 
     16     printf("end\n"); //用于让编译器对lr寄存器压栈
     17     return 0; //当函数执行结束,pop {fp, pc}; 从栈里的lr寄存器内容的位置上读出内容,并根据读出的返回地址来跳转, 所以func函数就有机会执行了
     18 }
编译后执行的输出:
^_^ /mnt/codes/03asm_deep # ./a.out 
end
in func ...   //func函数执行的输出
Segmentation fault

溢出攻击实现原理:
如上面的代码, buf数组足够大, 接收用户输入时如果不判断长度, 就可以把要执行的指令存入buf数组, 最后通过数组的越界访问,把栈里存放的原lr寄存器的内容改成buf数组的首地址, 那么buf数组里存放的指令就可以执行了.
而已当main函数是管理员执行时, 那么在buf数组里存放的指令执行就具有管理员的权限了, 手机的root用的就是这种方法

防止溢出攻击的方法:
1). 接用户输时判断数据长度, 防止数组越界访问

2). 尽量在堆里分配空间

3). gcc 编译时加上-fstack-protection选项(man gcc里查看)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值