zoukankan      html  css  js  c++  java
  • 缓冲区溢出以后

    我在CSDN发的一个帖子,很久没写日志了,拿来充数,也回顾一下。

    C代码如下:

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>

    void func1(char *s)
    {
        char buf[12];
        strcpy(buf,s);
    }
    void func2(void)
    {
        printf("Why I can be printed ?\n");
        exit (0);
    }
    int main(void)
    {
        char badcode[]="abcdefghijklmnopqrstuvwxyz";
        unsigned *p=(unsigned*)&badcode[16];
        *p=(unsigned)func2;

        func1(badcode);
        return 0;

    }
    这段代码在有的编译器(比如VC6)编译后,运行会打印“Why I can be printed?"。

    试分析原因:

    概括说就是溢出的字符串覆盖了main函数中“保存fun1返回地址“的栈区,使程序跳转到fun2。

    下面是cygwin下gcc反汇编的代码:

    _mystrcpy:
    pushl %ebp
    movl %esp, %ebp
    subl $
    16, %esp
    movl
    8(%ebp), %eax
    movl %eax, -
    4(%ebp)
    L2:
    movl
    12(%ebp), %eax
    movzbl (%eax), %edx
    movl
    8(%ebp), %eax
    movb %dl, (%eax)
    movl
    8(%ebp), %eax
    movzbl (%eax), %eax
    testb %al, %al
    setne %al
    addl $
    1, 8(%ebp)
    addl $
    1, 12(%ebp)
    testb %al, %al
    jne L2
    movl -
    4(%ebp), %eax
    leave
    ret
    .globl _func1
    .def _func1
    ; .scl 2; .type 32; .endef
    _func1:
    pushl %ebp
    movl %esp, %ebp
    subl $
    24, %esp
    movl
    8(%ebp), %eax
    movl %eax,
    4(%esp)
    leal -
    12(%ebp), %eax
    movl %eax, (%esp)
    call _mystrcpy
    leave
    ret
    .section .rdata,
    "dr"
    LC0:
    .ascii
    "Why I can be printed ?\0"
    .text
    .globl _func2
    .def _func2
    ; .scl 2; .type 32; .endef
    _func2:
    pushl %ebp
    movl %esp, %ebp
    subl $
    8, %esp
    movl $LC0, (%esp)
    call _puts
    movl $
    0, (%esp)
    call _exit
    .def ___main
    ; .scl 2; .type 32; .endef
    .globl _main
    .def _main
    ; .scl 2; .type 32; .endef
    _main:
    leal
    4(%esp), %ecx
    andl $-
    16, %esp
    pushl -
    4(%ecx)
    pushl %ebp
    movl %esp, %ebp
    pushl %ecx
    subl $
    36, %esp
    call ___main
    movl $
    825307441, -29(%ebp)
    movl $
    842150450, -25(%ebp)
    movl $
    858993459, -21(%ebp)
    movl $
    875836468, -17(%ebp)
    movl $
    892679477, -13(%ebp)
    movb $
    0, -9(%ebp)
    leal -
    29(%ebp), %eax
    addl $
    16, %eax
    movl %eax, -
    8(%ebp)
    movl $_func2, %edx
    movl -
    8(%ebp), %eax
    movl %edx, (%eax)
    leal -
    29(%ebp), %eax
    movl %eax, (%esp)
    call _func1
    movl $
    0, %eax
    addl $
    36, %esp
    popl %ecx
    popl %ebp
    leal -
    4(%ecx), %esp
    ret
    尤其需要注意的是fun1中的这几句。
            pushl %ebp
            保存main函数的栈帧,占用4个字节。
    leal -12(%ebp), %eax
    movl %eax, (%esp)

            call
    _mystrcpy

    这三句可知fun1为拷贝留出的缓冲区大小是12个字节。

    再注意到fun2的入口地址在badcode中的偏移恰好是16个字节,由于字符串的拷贝由低地址向高地址进行,所以

    fun2覆盖的地方恰好是fun1执行ret语句返回时应该取出的地址。

    于是程序欢快滴跳转了。

     
  • 相关阅读:
    Flex 布局
    前端跨域之jsonp
    vs code 自定义代码片段
    vue中使用axios进行http通信
    Table边框合并
    getElementsBy 系列方法相比querySelector系列的区别
    vue中watch简单使用
    png图标任意赋色
    pc端与移动端适配解决方案之rem
    Express post请求无法解析参数的原因
  • 原文地址:https://www.cnblogs.com/liujiahi/p/2196397.html
Copyright © 2011-2022 走看看