This shows you the differences between two versions of the page.
isc:labs:05:extra:gdb-tutorial [2024/11/03 11:46] florin.stancu created |
isc:labs:05:extra:gdb-tutorial [2024/11/03 11:58] (current) florin.stancu |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== GDB tutorial ===== | + | ====== GDB tutorial ====== |
- | ==== PwnDbg ==== | + | ===== Loading a program ===== |
- | + | ||
- | ==== Loading a program ==== | + | |
In order to start debugging using GDB, you need to specify the program to be inspected. There are two options for doing this: | In order to start debugging using GDB, you need to specify the program to be inspected. There are two options for doing this: | ||
Line 67: | Line 65: | ||
</note> | </note> | ||
- | ==== Breakpoints ==== | + | ===== Breakpoints ===== |
Breakpoints represent places in your program where the execution should be stopped. | Breakpoints represent places in your program where the execution should be stopped. | ||
Line 127: | Line 125: | ||
The ''start'' command is very similar to ''run'', but instead of running the program until it ends (or until it crashes), it sets a breakpoint at the beginning of the main function. | The ''start'' command is very similar to ''run'', but instead of running the program until it ends (or until it crashes), it sets a breakpoint at the beginning of the main function. | ||
- | <code> | + | ===== Stepping ===== |
- | + | ||
- | 22 if (argc == 1) { | + | |
- | LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA | + | |
- | ─────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]────────────────────────── | + | |
- | *EAX 0xffffd880 ◂— 0x2 | + | |
- | *EBX 0x56558fcc (_GLOBAL_OFFSET_TABLE_) ◂— 0x3ed4 | + | |
- | *ECX 0xffffd880 ◂— 0x2 | + | |
- | *EDX 0xffffd8a0 —▸ 0xf7fa9000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x229dac | + | |
- | *EDI 0xf7ffcb80 (_rtld_global_ro) ◂— 0x0 | + | |
- | *ESI 0xffffd934 —▸ 0xffffdabd ◂— '/home/student/appsec/buggy' | + | |
- | *EBP 0xffffd868 —▸ 0xf7ffd020 (_rtld_global) —▸ 0xf7ffda40 —▸ 0x56555000 ◂— 0x464c457f | + | |
- | *ESP 0xffffd850 —▸ 0xffffd890 —▸ 0xf7fa9000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x229dac | + | |
- | *EIP 0x56556281 (main+31) ◂— cmp dword ptr [eax], 1 | + | |
- | ───────────────────────────────────[ DISASM / i386 / set emulate on ]──────────────────────────────────── | + | |
- | ► 0x56556281 <main+31> cmp dword ptr [eax], 1 | + | |
- | 0x56556284 <main+34> jne main+61 <main+61> | + | |
- | ↓ | + | |
- | 0x5655629f <main+61> mov dword ptr [ebp - 0xc], 0x796568 | + | |
- | 0x565562a6 <main+68> mov eax, dword ptr [eax + 4] | + | |
- | 0x565562a9 <main+71> add eax, 4 | + | |
- | 0x565562ac <main+74> mov eax, dword ptr [eax] | + | |
- | 0x565562ae <main+76> sub esp, 4 | + | |
- | 0x565562b1 <main+79> push eax | + | |
- | 0x565562b2 <main+80> lea eax, [ebp - 0xc] | + | |
- | 0x565562b5 <main+83> push eax | + | |
- | 0x565562b6 <main+84> lea eax, [ebx - 0x1f6e] | + | |
- | ────────────────────────────────────────────[ SOURCE (CODE) ]──────────────────────────────────────────── | + | |
- | In file: /home/student/appsec/buggy.c | + | |
- | 17 gets(name); | + | |
- | 18 printf("bye\n"); | + | |
- | 19 } | + | |
- | 20 | + | |
- | 21 int main(int argc, char **argv) { | + | |
- | ► 22 if (argc == 1) { | + | |
- | 23 puts("Usage: %s <name>\n"); | + | |
- | 24 return 1; | + | |
- | 25 } | + | |
- | 26 char buf[] = "hey"; | + | |
- | 27 | + | |
- | ────────────────────────────────────────────────[ STACK ]──────────────────────────────────────────────── | + | |
- | 00:0000│ esp 0xffffd850 —▸ 0xffffd890 —▸ 0xf7fa9000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x229dac | + | |
- | 01:0004│-014 0xffffd854 —▸ 0xf7fbe66c —▸ 0xf7ffdba0 —▸ 0xf7fbe780 —▸ 0xf7ffda40 ◂— ... | + | |
- | 02:0008│-010 0xffffd858 —▸ 0xf7fbeb20 —▸ 0xf7d99cc6 ◂— 'GLIBC_PRIVATE' | + | |
- | 03:000c│-00c 0xffffd85c ◂— 0x1 | + | |
- | 04:0010│-008 0xffffd860 —▸ 0xffffd880 ◂— 0x2 | + | |
- | 05:0014│-004 0xffffd864 —▸ 0xf7fa9000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x229dac | + | |
- | 06:0018│ ebp 0xffffd868 —▸ 0xf7ffd020 (_rtld_global) —▸ 0xf7ffda40 —▸ 0x56555000 ◂— 0x464c457f | + | |
- | 07:001c│+004 0xffffd86c —▸ 0xf7da0519 (__libc_start_call_main+121) ◂— add esp, 0x10 | + | |
- | ──────────────────────────────────────────────[ BACKTRACE ]────────────────────────────────────────────── | + | |
- | ► 0 0x56556281 main+31 | + | |
- | 1 0xf7da0519 __libc_start_call_main+121 | + | |
- | 2 0xf7da05f3 __libc_start_main+147 | + | |
- | 3 0x565560cb _start+43 | + | |
- | ───────────────────────────────────────────────────────────────────────────────────────────────────────── | + | |
- | + | ||
- | </code> | + | |
- | + | ||
- | Let's take a look at the previous output that PwnDbg prints. You can see it is seprated into 5 sections: REGISTERS, DISASM, SOURCE, STACK and TRACE. | + | |
- | With the original GDB you would have to manually print registers, disassemble code and inspect the stack. Thanks, God, for PwnDbg! | + | |
- | + | ||
- | ==== Step ==== | + | |
There might be situations when you only want to execute one line of source code, or one machine instruction from your program. | There might be situations when you only want to execute one line of source code, or one machine instruction from your program. | ||
Line 197: | Line 134: | ||
* ''next'' or ''n'' (step over) - Continue to the next source line in the current stack frame. This is similar to step, but function calls that appear within the line of code are executed without stopping. | * ''next'' or ''n'' (step over) - Continue to the next source line in the current stack frame. This is similar to step, but function calls that appear within the line of code are executed without stopping. | ||
- | There are also equivalent functions for the machine instructions: ''stepi'' and ''nexti''. | + | There are also equivalent functions for the machine instructions: ''stepi'' and ''nexti''. Those are useful when the binary uses various compiler optimizations and the source lines debug metadata are unreliable (i.e., they skip too much). |
If you stepped into a function and you want to continue the execution until the function returns, you can use the ''finish'' or ''f'' (step out) command. | If you stepped into a function and you want to continue the execution until the function returns, you can use the ''finish'' or ''f'' (step out) command. | ||
- | ==== Printing variables and memory ==== | + | ===== Printing variables and memory ===== |
No need to manually print registers anymore, but you still might need to print the content of a variable: | No need to manually print registers anymore, but you still might need to print the content of a variable: | ||
Line 271: | Line 208: | ||
</code> | </code> | ||
- | ==== Stack info ==== | + | ===== Stack info ===== |
A backtrace is a summary of how your program got where it is. It shows one line per frame, for many frames, starting with the currently executing frame (frame zero), followed by its caller (frame one), and on up the stack. | A backtrace is a summary of how your program got where it is. It shows one line per frame, for many frames, starting with the currently executing frame (frame zero), followed by its caller (frame one), and on up the stack. | ||
Line 312: | Line 249: | ||
* which registers were saved in the frame | * which registers were saved in the frame | ||
+ |