【问题标题】:Buffer overflow buffer length缓冲区溢出缓冲区长度
【发布时间】:2015-04-12 20:49:05
【问题描述】:

我有一个缓冲区溢出问题需要解决。下面是问题,底部是我的问题:

#include <stdio.h>
#include <string.h>
void lan(void) {
   printf("Your loyalty to your captors is touching.\n");
}

void vulnerable(char *str) {
   char buf[LENGTH]; //Length is not given
   strcpy(buf, str); //str to fixed size buf (uh-oh)
 }

 int main(int argc, char **argv) {
    if (argc < 2) 
       return -1;
    vulnerable(argv[1]);
    return 0;
 }

 (gdb) disass vulnerable
 0x08048408: push %ebp
 0x08048409: mov %esp, %ebp
 0x0804840b: sub $0x88, %esp
 0x0804840e: mov 0x8(%ebp), %eax
 0x08048411: mov %eax, 0x4(%esp)
 0x08048415: lea -0x80(%ebp), %eax
 0x08048418: mov %eax, (%esp)
 0x0804841b: call 0x8048314 <strcpy>
 0x08048420: leave
 0x08048421: ret
 End of assembler dump.

 (gdb) disass lan
  0x080483f4:   push %ebp
  0x080483f5:   mov %esp, %ebp
  0x080483f7:   sub $0x4, %esp
  0x080483fa:   movl $0x8048514, (%esp)
  0x08048401:   call 0x8048324 <puts>
  0x08048406:   leave
  0x08048407:   ret
  End of assembler dump.

那么我们有以下信息:

 (gdb) break *0x08048420
 Breakpoint 1 at 0x8048420
 (gdb) run 'perl -e' print "\x90" x Length' 'AAAABBBBCCCCDDDDEEEE'
 Breakpoint 1, 0x08048420 in vulnerable
 (gdb) info reg $ebp
 ebp          0xffffd61c 0xffffd61c
 (gdb) # QUESTION: Where in memory does the buf buffer start?
 (gdb) cont
 Program received signal SIGSEGV, Segmentation fault.

最后,perl 命令是写出字符 0x90 的 LENGTH 个副本的简写。

我以前做过一些此类问题,但让我停下来的是以下问题:“通过查看汇编代码,LENGTH 的值是多少?”

我不确定如何从给定的汇编代码中找到它。我所知道的是..我们正在写入的缓冲区位于堆栈的 -128(%ebp) 位置(其中 -128 是十进制数)。但是,我不确定从这里到哪里来获取缓冲区的长度。

【问题讨论】:

    标签: c perl assembly x86 buffer-overflow


    【解决方案1】:

    让我们看看你的vulnerable 函数。

    首先编译器创建一个帧并在堆栈上保留 0x88 字节:

     0x08048408: push %ebp
     0x08048409: mov %esp, %ebp
     0x0804840b: sub $0x88, %esp
    

    然后它将两个值放入堆栈:

     0x0804840e: mov 0x8(%ebp), %eax
     0x08048411: mov %eax, 0x4(%esp)
     0x08048415: lea -0x80(%ebp), %eax
     0x08048418: mov %eax, (%esp)
    

    它在返回之前做的最后一件事是调用strcpy(buf, str)

     0x0804841b: call 0x8048314 <strcpy>
     0x08048420: leave
     0x08048421: ret
    

    因此我们可以推断它放入堆栈的两个值是strcpy 的参数。
    mov 0x8(%ebp) 将是char *strlea -0x80(%ebp) 将是指向char buf[LENGTH] 的指针。

    因此,我们知道您的缓冲区从 -0x80(%ebp) 开始,因此假设编译器没有浪费任何空间,它的长度为 0x80 = 128 字节。

    【讨论】:

      【解决方案2】:

      我所知道的是.. 我们写入的缓冲区在堆栈上 在位置 -128(%ebp)

      由于局部变量以%ebp 结尾,并且您只有一个局部变量,即buffer 本身,因此您可以得出结论,它的长度最多为128。如果编译器为对齐添加了一些填充,它可能会更短。

      【讨论】:

      • 谢谢@Jester,这就是我的想法(这阻止了我回答这个问题)。这是我学校的一次旧考试中的一个问题,当我不知道编译器在其中放置了多少填充时,我觉得(并且仍然觉得)回答 LENGTH 有多大很奇怪。
      猜你喜欢
      • 2015-12-16
      • 1970-01-01
      • 2010-11-11
      • 2017-05-12
      • 2013-04-11
      • 2015-07-07
      • 2012-02-05
      • 2013-07-21
      • 1970-01-01
      相关资源
      最近更新 更多