使用GDB和shell执行时可执行文件的不同行为

时间:2018-01-05 20:03:39

标签: c++ c debugging buffer-overflow

在我尝试理解缓冲区溢出时,我编写了示例C / C ++程序。程序会要求您输入密码,然后根据您是否输入正确的密码显示两条不同的消息。我打开代码并将其拆解以找到我可以跳转到的一点,以便我可以覆盖正确或不正确的密码。我写了一个快速的python脚本,用“A”填充缓冲区,然后返回地址回到我希望代码执行的位置。

这种方法在GDB调试器中运行得很好,但是当我在调试器外运行相同的东西时,我会遇到分段错误。有谁知道为什么会这样?

以下是代码:

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

int checkpw();

int main(int argc, char* argv[])
{
    int r = checkpw();

    if(r==0)
    {
        printf("Congrats, you have been granted access to the program");
    }
    else
    {
        printf("That is the incorret password. Please exit immediately.");
    }

    return 0;
}

int checkpw()
{
    char buffer[10];
    gets(buffer);
    return strcmp(buffer,"password");
}

我使用此行g++ -z execstack -g -fno-stack-protector main.cpp -o main

编译了代码

这会产生这两个反汇编的代码段,第一个代表main函数...

   0x00000000004005bd <+0>: push   %rbp
   0x00000000004005be <+1>: mov    %rsp,%rbp
   0x00000000004005c1 <+4>: sub    $0x20,%rsp
   0x00000000004005c5 <+8>: mov    %edi,-0x14(%rbp)
   0x00000000004005c8 <+11>:    mov    %rsi,-0x20(%rbp)
   0x00000000004005cc <+15>:    callq  0x400601 <checkpw()>
   0x00000000004005d1 <+20>:    mov    %eax,-0x4(%rbp)
   0x00000000004005d4 <+23>:    cmpl   $0x0,-0x4(%rbp)
   0x00000000004005d8 <+27>:    jne    0x4005eb <main(int, char**)+46>
   0x00000000004005da <+29>:    mov    $0x4006b8,%edi
   0x00000000004005df <+34>:    mov    $0x0,%eax
   0x00000000004005e4 <+39>:    callq  0x400480 <printf@plt>
   0x00000000004005e9 <+44>:    jmp    0x4005fa <main(int, char**)+61>
   0x00000000004005eb <+46>:    mov    $0x4006f0,%edi
   0x00000000004005f0 <+51>:    mov    $0x0,%eax
   0x00000000004005f5 <+56>:    callq  0x400480 <printf@plt>
   0x00000000004005fa <+61>:    mov    $0x0,%eax
   0x00000000004005ff <+66>:    leaveq 
   0x0000000000400600 <+67>:    retq  

现在是checkpw()功能...

   0x0000000000400601 <+0>: push   %rbp
   0x0000000000400602 <+1>: mov    %rsp,%rbp
   0x0000000000400605 <+4>: sub    $0x10,%rsp
   0x0000000000400609 <+8>: lea    -0x10(%rbp),%rax
   0x000000000040060d <+12>:    mov    %rax,%rdi
   0x0000000000400610 <+15>:    callq  0x4004c0 <gets@plt>
   0x0000000000400615 <+20>:    lea    -0x10(%rbp),%rax
   0x0000000000400619 <+24>:    mov    $0x400728,%esi
   0x000000000040061e <+29>:    mov    %rax,%rdi
   0x0000000000400621 <+32>:    callq  0x4004a0 <strcmp@plt>
   0x0000000000400626 <+37>:    leaveq 
   0x0000000000400627 <+38>:    retq 

在运行调试器之前,我将此命令输入到终端python -c 'print "AAAAAAAAAAAAAAAA\x40\xdf\xff\xff\xff\x7f\x00\x00\xda\x05\x40\x00\x00\x00\x00\x00"' > /tmp/input1中,它创建了一个充满“A”的文件,更重要的是将返回地址写入打印出的代码的开头。访问该计划。 \xda\x05\x40\x00\x00\x00\x00\x00

这完美无缺。我运行gdb main然后在调试器中输入run < /tmp/input1和“恭喜,您已被授予访问程序的权限”将被打印到屏幕上。

所以我在调试器外部尝试这个尝试失败了。我从终端运行这个命令...... python -c 'print "AAAAAAAAAAAAAAAA\x40\xdf\xff\xff\xff\x7f\x00\x00\xda\x05\x40\x00\x00\x00\x00\x00"' | ./main我收到了一个段错误。

0 个答案:

没有答案