gdb地址:0x565561f5而不是0x41414141

时间:2019-06-03 16:34:43

标签: c gdb

我想在C程序上尝试缓冲区溢出。我用gcc像这样function rowHighlight() { $("TR").click(function() { try { $(this).parent().prev()[0].tagName; HighLightTR(this); } catch (err) {} }); } 编译了它。如果我在gdb中运行该程序并且缓冲区溢出,则应该说0x41414141,因为我发送了A。但俗话说0x565561f5。对不起,我的英语不好。有人可以帮我吗?

这是源代码:

gcc -fno-stack-protector -m32 buggy_program.c
#include <stdio.h>

int main(int argc, char **argv)
{
    char buffer[64];

    printf("Type in something: ");
    gets(buffer);
}

我想看这个:

Starting program: /root/Downloads/a.out 
Type in something: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Program received signal SIGSEGV, Segmentation fault.
0x565561f5 in main ()

3 个答案:

答案 0 :(得分:1)

现代操作系统使用地址空间布局随机化ASLR使得这些东西不太容易工作。

我记得它刚开始时的争议。对于32位进程而言,ASLR并不是一个好主意,因为它对系统施加了其他限制,并且带来了可疑的安全性好处。另一方面,它可以在64位进程上很好地工作,并且现在几乎每个人都使用它。

您不知道代码在哪里。您不知道堆在哪里。您不知道堆栈在哪里。编写漏洞利用代码现在很困难。

此外,您尝试在64位进程上使用32位shellcode和文档。

在阅读更新的问题时:您的代码是使用帧指针编译的(默认设置)。这会导致ret指令本身出错,因为esp已被破坏。 ASLR似乎仍在发挥作用,实际上并不重要。

答案 1 :(得分:1)

查看段错误处理的地址,在反汇编代码中显示相关行:

  

gdb a.out << EOF
  设置登录
  r   拆卸主   x / i $ eip
  p / x $ esp

产生以下输出:

  

(gdb)启动程序:... / a.out      

程序收到信号SIGSEGV,分段错误。   tmp.c:10 10处主(argc =,argv =)中的0x08048482   (gdb)函数main的汇编代码转储:
  0x08048436 <+0>: lea 0x4(%esp),%ecx
  0x0804843a <+4>:和$ 0xfffffff0,%esp
  0x0804843d <+7>:pushl -0x4(%ecx)
  0x08048440 <+10>:推送%ebp
  0x08048441 <+11>:mov%esp,%ebp
  0x08048443 <+13>:推送%ebx
  0x08048444 <+14>:推%ecx
  0x08048445 <+15>:子$ 0x40,%esp
  0x08048448 <+18>:呼叫
  0x8048370 <__ x86.get_pc_thunk.bx>
  0x0804844d <+23>:添加$ 0x1bb3,%ebx
  0x08048453 <+29>:子$ 0xc,%esp
  0x08048456 <+32>:lea -0x1af0(%ebx),%eax
  0x0804845c <+38>:推送%eax
  0x0804845d <+39>:致电0x8048300
  0x08048462 <+44>:加$ 0x10,%esp
  0x08048465 <+47>:子$ 0xc,%esp
  0x08048468 <+50>:lea -0x48(%ebp),%eax
  0x0804846b <+53>:推送%eax
  0x0804846c <+54>:致电0x8048310
  0x08048471 <+59>:添加$ 0x10,%esp
  0x08048474 <+62>:mov $ 0x0,%eax
  0x08048479 <+67>:lea -0x8(%ebp),%esp
  0x0804847c <+70>:弹出%ecx
  0x0804847d <+71>:弹出%ebx
  0x0804847e <+72>:弹出%ebp
  0x0804847f <+73>: lea -0x4(%ecx),%esp
  => 0x08048482 <+76>:ret
  汇编程序转储结束。
  (gdb)=> 0x8048482:ret
  (gdb)$ 1 = 0x4141413d
  (gdb)退出

失败的语句是ret末尾的main。当ret尝试从堆栈顶部加载返回地址时,程序失败。生成的可执行文件在对齐字边界之前将旧值esp存储在堆栈中。 main完成后,程序将尝试从堆栈中恢复esp,然后读取返回地址。但是,整个堆栈的顶部被破坏了,因此呈现了堆栈指针垃圾($1 = 0x4141413d)的新值。执行ret时,它将尝试从地址0x4141413d中读取一个单词,该单词未分配,并产生段错误。

注释

上面的反汇编是使用以下编译器选项从问题中的代码产生的:

  

-m32 -fno-stack-protector -g -O0

答案 2 :(得分:1)

所以,我找到了解决方案: 只需使用gcc 3.3.4进行编译 gcc -m32 buggy_program.c