插入 gdb 断点失败

Inserting gdb breakpoints fail

我正在学习 c 中的缓冲区溢出。 为此,我将遵循 this 简单示例。

我有以下 gcc 版本:

$ gcc --version
gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

还有这个简单的 c 文件:

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

int main(int argc, char *argv[]){
    char buf[256];
    strcpy(buf, argv[1]);
    printf("%s,", buf);
    return 0;
}

然后我用 $ gcc buf.c -o buf 编译这个文件。 然后我通过 $ gdb ./buf

在 gdb 中打开

我调用 disas 并得到结果集:

(gdb) disas main
Dump of assembler code for function main:
   0x0000000000001189 <+0>:     endbr64 
   0x000000000000118d <+4>:     push   %rbp
   0x000000000000118e <+5>:     mov    %rsp,%rbp
   0x0000000000001191 <+8>:     sub    [=12=]x120,%rsp
   0x0000000000001198 <+15>:    mov    %edi,-0x114(%rbp)
   0x000000000000119e <+21>:    mov    %rsi,-0x120(%rbp)
   0x00000000000011a5 <+28>:    mov    %fs:0x28,%rax
   0x00000000000011ae <+37>:    mov    %rax,-0x8(%rbp)
   0x00000000000011b2 <+41>:    xor    %eax,%eax
   0x00000000000011b4 <+43>:    mov    -0x120(%rbp),%rax
   0x00000000000011bb <+50>:    add    [=12=]x8,%rax
   0x00000000000011bf <+54>:    mov    (%rax),%rdx
   0x00000000000011c2 <+57>:    lea    -0x110(%rbp),%rax
   0x00000000000011c9 <+64>:    mov    %rdx,%rsi
   0x00000000000011cc <+67>:    mov    %rax,%rdi
   0x00000000000011cf <+70>:    callq  0x1070 <strcpy@plt>
--Type <RET> for more, q to quit, c to continue without paging--
   0x00000000000011d4 <+75>:    lea    -0x110(%rbp),%rax
   0x00000000000011db <+82>:    mov    %rax,%rsi
   0x00000000000011de <+85>:    lea    0xe1f(%rip),%rdi        # 0x2004
   0x00000000000011e5 <+92>:    mov    [=12=]x0,%eax
   0x00000000000011ea <+97>:    callq  0x1090 <printf@plt>
   0x00000000000011ef <+102>:   mov    [=12=]x0,%eax
   0x00000000000011f4 <+107>:   mov    -0x8(%rbp),%rcx
   0x00000000000011f8 <+111>:   xor    %fs:0x28,%rcx
   0x0000000000001201 <+120>:   je     0x1208 <main+127>
   0x0000000000001203 <+122>:   callq  0x1080 <__stack_chk_fail@plt>
   0x0000000000001208 <+127>:   leaveq 
   0x0000000000001209 <+128>:   retq   
End of assembler dump.

一些非常低的内存地址。 然后我想看看如果我在程序中输入一大串 A 会发生什么,因此我在 0x00000000000011db 处放置了一个断点 我接着运行吧:

(gdb) run $(python3 -c "print('A'*256)"
Starting program: /home/ask/Notes/ctf/bufoverflow/code/buf $(python3 -c "print('A'*256)"
/bin/bash: -c: line 0: unexpected EOF while looking for matching `)'
/bin/bash: -c: line 1: syntax error: unexpected end of file
During startup program exited with code 1.
(gdb) run $(python3 -c "print('A'*256)")
Starting program: /home/ask/Notes/ctf/bufoverflow/code/buf $(python3 -c "print('A'*256)")
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x11db

好的,内存地址有点古怪。 我 google 问题并找到 我发现这是因为可能启用了位置无关可执行文件 (PIE),并且当程序实际 运行 时内存地址将被更改. 我可以在 运行ning 程序之后通过 运行ning disas 确认这一点,并且看到内存地址在更高的范围内。

这一切都是有道理的,但它让我想知道,如果每次我 运行 它的地址都改变,那么我怎样才能在程序 运行 之前的内存地址处放置一个断点小号?

iif the adresses change every time I run it, then how can I then place a breakpoint at a memory adress before the program runs?

发生这种情况是因为 GDB 默认禁用地址随机化(以便于调试)。

如果您 re-enable 使用 (gdb) set disable-randomization off 的 ASLR,那么您将无法在地址上设置断点。

您仍然可以设置断点,例如main——在那种情况下,GDB 将等待直到可执行文件被重定位,并将在实际的 运行time 指令上设置断点(地址将在每个 运行 上更改)。