c - 缓冲区溢出,调用函数

标签 c gdb buffer-overflow

我必须使用缓冲区溢出来覆盖函数的返回地址。

函数本身如下所示(我传递名称参数):

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。 在到达要覆盖的返回地址之前,我如何知道填充物的数量? 我想名称参数的形式应该是“a”*n +“\x0b\x85\x04\x08”,其中n是我试图猜测的某个数字。我想这应该是基本的东西,但我仍然是一个初学者,所以请不要评判我......

最佳答案

How am I supposed to know ...

您的代码是:

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)处。

第一次推送后,它位于4(%esp)。由于 %esp 接下来被复制到 %ebp,因此它也在 4(%ebp)

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

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

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

如果我的计算正确,当vuln尝试返回“槽”0x41C/4 == 0x107时,它会崩溃,其中应该包含0x01010208.

关于c - 缓冲区溢出,调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47425934/

相关文章:

c - 缓冲区溢出C

c - 如何将 skb 推送到 Linux 网络堆栈的特定点?

c - 如何使用循环在 C 中制作表格

c - C 中的命名空间

c - 使用单个套接字接收单播和多播数据

计算 cmp 中汇编的实际地址

cocoa - 如何检查 self.navigationController 是否为零

c++ - 如何在跳过所有内部实现的同时跳转到 GDB 中 std::function 中的函数?

在雪豹中创建缓冲区溢出

c - 使用 c 的缓冲区溢出