缓冲区溢出,调用函数

时间:2017-11-22 02:39:01

标签: c gdb buffer-overflow

我必须使用buffer oveflow覆盖函数的返回地址。

函数本身看起来像这样(我传递了name参数):

void vuln(char *name)
{
    int n = 20;
    char buf[1024];
    int f[n];
    int i;
    for (i=0; i<n; i++) {
      f[i] = fib(i);
    }
    strcpy(buf, name);
    ...
}

我正在使用gdb拆解它,它给了我以下

   0x080485ae <+0>: push   %ebp
   0x080485af <+1>: mov    %esp,%ebp
   0x080485b1 <+3>: push   %ebx
   0x080485b2 <+4>: sub    $0x414,%esp
   0x080485b8 <+10>:    mov    %esp,%eax
   0x080485ba <+12>:    mov    %eax,%ebx
   0x080485bc <+14>:    movl   $0x14,-0x10(%ebp)
   0x080485c3 <+21>:    mov    -0x10(%ebp),%eax
   0x080485c6 <+24>:    lea    -0x1(%eax),%edx
   0x080485c9 <+27>:    mov    %edx,-0x14(%ebp)
   0x080485cc <+30>:    shl    $0x2,%eax
   0x080485cf <+33>:    lea    0x3(%eax),%edx
   0x080485d2 <+36>:    mov    $0x10,%eax
   0x080485d7 <+41>:    sub    $0x1,%eax
   0x080485da <+44>:    add    %edx,%eax
   0x080485dc <+46>:    mov    $0x10,%ecx
   0x080485e1 <+51>:    mov    $0x0,%edx
   0x080485e6 <+56>:    div    %ecx
   0x080485e8 <+58>:    imul   $0x10,%eax,%eax
   0x080485eb <+61>:    sub    %eax,%esp
   0x080485ed <+63>:    mov    %esp,%eax
   0x080485ef <+65>:    add    $0x3,%eax
   0x080485f2 <+68>:    shr    $0x2,%eax
   0x080485f5 <+71>:    shl    $0x2,%eax
   0x080485f8 <+74>:    mov    %eax,-0x18(%ebp)
   0x080485fb <+77>:    movl   $0x0,-0xc(%ebp)
   0x08048602 <+84>:    jmp    0x8048621 <vuln+115>
   0x08048604 <+86>:    sub    $0xc,%esp
   0x08048607 <+89>:    pushl  -0xc(%ebp)
   0x0804860a <+92>:    call   0x8048560 <fib>
   0x0804860f <+97>:    add    $0x10,%esp
   0x08048612 <+100>:   mov    %eax,%ecx
   0x08048614 <+102>:   mov    -0x18(%ebp),%eax
   0x08048617 <+105>:   mov    -0xc(%ebp),%edx
   0x0804861a <+108>:   mov    %ecx,(%eax,%edx,4)
   0x0804861d <+111>:   addl   $0x1,-0xc(%ebp)
   0x08048621 <+115>:   mov    -0xc(%ebp),%eax
   0x08048624 <+118>:   cmp    -0x10(%ebp),%eax
   0x08048627 <+121>:   jl     0x8048604 <vuln+86>
   0x08048629 <+123>:   sub    $0x8,%esp
   0x0804862c <+126>:   pushl  0x8(%ebp)
   0x0804862f <+129>:   lea    -0x418(%ebp),%eax
   0x08048635 <+135>:   push   %eax
   0x08048636 <+136>:   call   0x80483c0 <strcpy@plt>
   0x0804863b <+141>:   add    $0x10,%esp
   0x0804863e <+144>:   sub    $0x8,%esp
   0x08048641 <+147>:   lea    -0x418(%ebp),%eax
   0x08048647 <+153>:   push   %eax
   0x08048648 <+154>:   push   $0x80487b7
   0x0804864d <+159>:   call   0x80483a0 <printf@plt>
   0x08048652 <+164>:   add    $0x10,%esp
   0x08048655 <+167>:   movl   $0x0,-0xc(%ebp)
   0x0804865c <+174>:   jmp    0x804867f <vuln+209>
   0x0804865e <+176>:   mov    -0x18(%ebp),%eax
   0x08048661 <+179>:   mov    -0xc(%ebp),%edx
=> 0x08048664 <+182>:   mov    (%eax,%edx,4),%eax
   0x08048667 <+185>:   sub    $0x4,%esp
   0x0804866a <+188>:   push   %eax
   0x0804866b <+189>:   pushl  -0xc(%ebp)
   0x0804866e <+192>:   push   $0x80487c4
   0x08048673 <+197>:   call   0x80483a0 <printf@plt>
   0x08048678 <+202>:   add    $0x10,%esp
   0x0804867b <+205>:   addl   $0x1,-0xc(%ebp)
   0x0804867f <+209>:   cmpl   $0x13,-0xc(%ebp)
   0x08048683 <+213>:   jle    0x804865e <vuln+176>
   0x08048685 <+215>:   mov    %ebx,%esp
   0x08048687 <+217>:   nop
   0x08048688 <+218>:   mov    -0x4(%ebp),%ebx
   0x0804868b <+221>:   leave  
   0x0804868c <+222>:   ret 

应该通过返回vuln()调用的函数的地址是0x804850b。 在到达要覆盖的返回地址之前,我怎么知道填充量? 我想name参数应该采用&#34; a&#34; * n +&#34; \ x0b \ x85 \ x04 \ x08&#34;的形式,其中n是我想猜的一些数字。我想这应该是基本的东西,但我还是初学者,所以请不要评判我......

1 个答案:

答案 0 :(得分:0)

  

我怎么知道...

您的代码是:

0x080485ae <+0>: push   %ebp
0x080485af <+1>: mov    %esp,%ebp
...
0x0804862f <+129>:   lea    -0x418(%ebp),%eax
0x08048635 <+135>:   push   %eax
0x08048636 <+136>:   call   0x80483c0 <strcpy@plt>

在输入函数之前,返回地址位于偏移0(%esp)

在第一个push之后,它位于4(%esp)。自%esp下次复制到%ebp后,它也会4(%ebp)

接下来,您会看到您开始复制的位置位于-0x418(%ebp)

结论:&buf[0]&return_address之间的差值为0x418 + 4 == 0x41C

替代解决方案:使用无效地址填写name输入:0x010101010x01010102,... 0x010102FF。执行代码并观察它崩溃的地址。

如果我的计算是正确的,当vuln尝试返回&#34; slot&#34; 0x41C / 4 == 0x107,应包含0x01010208

相关问题