GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2 Copyright (C) 2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
$ gcc -g start.c $ gdb ./a.out GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2 Copyright (C) 2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>.
For help, type "help". Type "apropos word" to search for commands related to "word"... pwndbg: loaded 197 commands. Type pwndbg [filter] for a list. pwndbg: created $rebase, $ida gdb functions (can be used with print/break) Reading symbols from ./a.out... pwndbg>
如此进入到gdb指令交互。
gdb指令
男人一下
1
$ man gdb
Here are some of the most frequently needed GDB commands:
break [file:]function Set a breakpoint at
function (in file).
run [arglist] Start your program (with arglist,
if specified).
bt Backtrace: display the program
stack.
print expr Display the value of an
expression.
c Continue running your program (after stopping,
e.g. at a breakpoint).
next Execute next program line (after stopping);
step over any function calls in the line.
list [file:]function type the text of the
program in the vicinity of where it is presently stopped.
step Execute next program line (after stopping);
step into any function calls in the line.
help [name] Show information about GDB command
name, or general information about using GDB.
pwndbg> b main Breakpoint 1 at 0x555555555169: file start.c, line 3.
b 行号
可搭配list指令(查看源代码),查看代码对应行数,在对应行装b
1 2 3 4 5 6 7 8 9 10 11 12 13
pwndbg> list 1 #include <stdio.h> 2 3 int main(){ 4 int arr[4] = {1, 2, 3, 4}; 5 for (int i=0;i<4;i++) 6 { 7 printf("%d\n", arr[i]); 8 } 9 return 0; 10 } pwndbg> b 7 Breakpoint 2 at 0x5555555551a9: file start.c, line 7.
info b:
康康刚在哪装了b
1 2 3 4
pwndbg> info b Num Type Disp Enb Address What 1 breakpoint keep y 0x0000555555555169 in main at start.c:3 2 breakpoint keep y 0x00005555555551a9 in main at start.c:7
pwndbg> b main Breakpoint 1 at 0x1169: file start.c, line 3. pwndbg> b 7 Breakpoint 2 at 0x11a9: file start.c, line 7. pwndbg> r Starting program: /home/Mo01iHt/Desktop/a.out
Breakpoint 1, main () at start.c:3 3 int main(){ pwndbg> c #继续运行,直到下一次断住 Continuing.
Breakpoint 2, main () at start.c:7 7 printf("%d\n", arr[i]); pwndbg> c 3 #跳过三次 Will ignore next 2 crossings of breakpoint 2. Continuing. 1 2 3
Breakpoint 2, main () at start.c:7 7 printf("%d\n", arr[i]);
u/until: 继续运行到指定位置
例如我们在main函数起始处打断停住,想要运行到第9行时再次停住,则:
1 2 3 4 5 6 7 8 9 10 11
pwndbg> b main Breakpoint 1 at 0x1169: file start.c, line 3. pwndbg> r pwndbg> until 9 1 2 3 4
main () at start.c:9 9 return 0;
gdb一些骚操作
允许执行终端命令: shell xxx
例如shell cat start.c:
1 2 3 4 5 6 7 8 9 10 11
pwndbg> shell cat start.c #include <stdio.h>
int main(){ int arr[4] = {1, 2, 3, 4}; for (int i=0;i<4;i++) { printf("%d\n", arr[i]); } return 0; }
pwndbg> set logging on Copying output to gdb.txt. Copying debug output to gdb.txt. pwndbg> b hello Breakpoint 2 at 0x555555555189: file start1.c, line 3. pwndbg> r Starting program: /home/Mo01iHt/Desktop/a.out 1 2 3 4
Breakpoint 1, main () at start1.c:13 13 hello(); pwndbg> n
Breakpoint 2, hello () at start1.c:3 3 void hello(){ pwndbg> n 4 printf("hello echo~\n"); pwndbg> n hello echo~ 5 } pwndbg> n main () at start1.c:14 14 return 0; pwndbg> n 15 } pwndbg> n __libc_start_main (main=0x5555555551a0 <main>, argc=1, argv=0x7fffffffdf58, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdf48) at ../csu/libc-start.c:342 342 ../csu/libc-start.c: No such file or directory.
pwndbg> list 1 #include <stdio.h> 2 3 void hello(){ 4 printf("hello echo~\n"); 5 } 6 7 int main(){ 8 int arr[4] = {1, 2, 3, 4}; 9 for (int i=0;i<4;i++) 10 { pwndbg> b 9 Breakpoint 1 at 0x11d7: file start1.c, line 9. pwndbg> r Starting program: /home/Mo01iHt/Desktop/a.out
Breakpoint 1, main () at start1.c:9 9 for (int i=0;i<4;i++) pwndbg> p &i $1 = (int *) 0x7fffffffde3c
插个眼watch *0x7fffffffde3c:
1 2 3 4 5
pwndbg> watch *0x7fffffffde3c Hardware watchpoint 2: *0x7fffffffde3c pwndbg> info watchpoints Num Type Disp Enb Address What 2 hw watchpoint keep y *0x7fffffffde3c
Old value = 21845 New value = 0 main () at start1.c:9 9 for (int i=0;i<4;i++) pwndbg> n 11 printf("%d\n", arr[i]); pwndbg> n 1 9 for (int i=0;i<4;i++) pwndbg> n
Hardware watchpoint 2: *0x7fffffffde3c
Old value = 0 New value = 1 0x0000555555555200 in main () at start1.c:9 9 for (int i=0;i<4;i++)
$ gdb a.out core GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2 Copyright (C) 2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>.
For help, type "help". Type "apropos word" to search for commands related to "word"... pwndbg: loaded 197 commands. Type pwndbg [filter] for a list. pwndbg: created $rebase, $ida gdb functions (can be used with print/break) Reading symbols from a.out... [New LWP 173306] Core was generated by `./a.out'. Program terminated with signal SIGSEGV, Segmentation fault. #0 0x000056088e42013d in main () at error.c:5 5 *temp = 10; Exception occurred: Error: maximum recursion depth exceeded in comparison (<class 'RecursionError'>) For more info invoke `set exception-verbose on` and rerun the command or debug it by yourself with `set exception-debugger on` Python Exception <class 'RecursionError'> maximum recursion depth exceeded in comparison:
gdb启动是真的罗里吧嗦啊)
可以看到带着core文件进入到gdb里会直接爆出fault以及产生抛出错误的代码行。
调试一个正在运行的文件
先写一个程序start2.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#include<stdio.h>
voidtest(){ }
voidtest1(){ int i = 0; i++; } intmain(){ for(;;){ test(); test1(); } return0; }
You can run “gdb” with no arguments or options; but the most
usual way to start GDB is with one argument or two, specifying an
executable program as the argument:
gdb program
You can also start with both an executable program and a core
file specified:
gdb program core
You can, instead, specify a process ID as a second argument or
use option “-p”, if you want to debug a running process:
gdb program 1234
gdb -p 1234
would attach GDB to process 1234. With option -p you can omit the
program filename.
$ gdb -p 7514 GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2 Copyright (C) 2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>.
For help, type "help". Type "apropos word" to search for commands related to "word". pwndbg: loaded 197 commands. Type pwndbg [filter] for a list. pwndbg: created $rebase, $ida gdb functions (can be used with print/break) Attaching to process 7514 Reading symbols from /home/Mo01iHt/Desktop/a.out... Reading symbols from /lib/x86_64-linux-gnu/libc.so.6... Reading symbols from /usr/lib/debug/.build-id/18/78e6b475720c7c51969e69ab2d276fae6d1dee.debug... Reading symbols from /lib64/ld-linux-x86-64.so.2... Reading symbols from /usr/lib/debug/.build-id/45/87364908de169dec62ffa538170118c1c3a078.debug... 0x0000559272c30133 in test () at start2.c:4 4 } LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA ─────────────────────────────────[ REGISTERS ]───────────────────────────────── RAX 0x0 RBX 0x559272c30170 (__libc_csu_init) ◂— endbr64 RCX 0x559272c30170 (__libc_csu_init) ◂— endbr64 RDX 0x7ffd166c9ea8 —▸ 0x7ffd166cb33e ◂— 'SHELL=/bin/bash' RDI 0x1 RSI 0x7ffd166c9e98 —▸ 0x7ffd166cb336 ◂— 0x74756f2e612f2e /* './a.out' */ R8 0x0 R9 0x7f7f22a4ed60 (_dl_fini) ◂— endbr64 R10 0x0 R11 0x7f7f229e07c0 (intel_02_known) ◂— 0x200000200406 R12 0x559272c30040 (_start) ◂— endbr64 R13 0x7ffd166c9e90 ◂— 0x1 R14 0x0 R15 0x0 RBP 0x7ffd166c9da0 ◂— 0x0 RSP 0x7ffd166c9d98 —▸ 0x559272c3015c (main+18) ◂— mov eax, 0 RIP 0x559272c30133 (test+10) ◂— ret ──────────────────────────────────[ DISASM ]─────────────────────────────────── ► 0x559272c30133 <test+10> ret <0x559272c3015c; main+18> ↓ 0x559272c3015c <main+18> mov eax, 0 0x559272c30161 <main+23> call test1 <test1> 0x559272c30166 <main+28> jmp main+8 <main+8> 0x559272c30168 nop dword ptr [rax + rax] 0x559272c30170 <__libc_csu_init> endbr64 0x559272c30174 <__libc_csu_init+4> push r15 0x559272c30176 <__libc_csu_init+6> lea r15, [rip + 0x2c73] <0x559272c32df0> 0x559272c3017d <__libc_csu_init+13> push r14 0x559272c3017f <__libc_csu_init+15> mov r14, rdx 0x559272c30182 <__libc_csu_init+18> push r13 ───────────────────────────────[ SOURCE (CODE) ]─────────────────────────────── In file: /home/Mo01iHt/Desktop/start2.c 1 #include <stdio.h> 2 3 void test(){ ► 4 } 5 6 void test1(){ 7 int i = 0; 8 i++; 9 } ───────────────────────────────────[ STACK ]─────────────────────────────────── 00:0000│ rsp 0x7ffd166c9d98 —▸ 0x559272c3015c (main+18) ◂— mov eax, 0 01:0008│ rbp 0x7ffd166c9da0 ◂— 0x0 02:0010│ 0x7ffd166c9da8 —▸ 0x7f7f22855083 (__libc_start_main+243) ◂— mov edi, eax 03:0018│ 0x7ffd166c9db0 —▸ 0x7f7f22a6a620 (_rtld_global_ro) ◂— 0x50f4000000000 04:0020│ 0x7ffd166c9db8 —▸ 0x7ffd166c9e98 —▸ 0x7ffd166cb336 ◂— 0x74756f2e612f2e /* './a.out' */ 05:0028│ 0x7ffd166c9dc0 ◂— 0x100000000 06:0030│ 0x7ffd166c9dc8 —▸ 0x559272c3014a (main) ◂— endbr64 07:0038│ 0x7ffd166c9dd0 —▸ 0x559272c30170 (__libc_csu_init) ◂— endbr64 ─────────────────────────────────[ BACKTRACE ]───────────────────────────────── ► f 0 0x559272c30133 test+10 f 1 0x559272c3015c main+18 f 2 0x7f7f22855083 __libc_start_main+243 ───────────────────────────────────────────────────────────────────────────────
可以看到进程执行到test()处。
(很难受的是我在这里又寄乐,报错如下:Could not attach to process. If your uid matches the uid of the target process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try again as the root user. For more details, see /etc/sysctl.d/10-ptrace.conf ptrace: Operation not permitted.,cn一下:使用GDB调试时attach
ID不被允许 - longyuan-z - 博客园
(cnblogs.com) $ cat /etc/sysctl.d/10-ptrace.conf查看配置文件。最后一行默认是kernel.yama.ptrace_scope = 1,这个值不允许用户使用普通账户使用attach
ID连接程序进行调试,需要使用超级用户权限才能连接。 解决方法:sudo vim /etc/sysctl.d/10-ptrace.conf将最后一行改为
kernel.yama.ptrace_scope = 0,保存退出。重启系统后,普通用户就可以使用attach
ID连接程序调试了。)
简单调试观察一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
pwndbg> n main () at start2.c:13 13 test1(); pwndbg> s test1 () at start2.c:6 6 void test1(){ pwndbg> n 7 int i = 0; pwndbg> n 8 i++; pwndbg> p i $1 = 0 pwndbg> n 9 } pwndbg> p i $2 = 1 pwndbg> n main () at start2.c:12 12 test();