EPL475:Εργαστήριο 5, GDB Στο σημερινό εργαστήριο θα χρησιμοποιήσουμε το εργαλείο gdb για αποσφαλμάτωση. Με το τέλος αυτού του εργαστήριου οι φοιτητές θα μπορούν να: Να φορτώνουν εκτελέσιμο αρχείο στον gdb και να κάνουν αποσφαλμάτωση Να βάζουν breakpoints Να εκτελούν εντολη εντλοη ένα προγραμμα Να βλέπουν περιεχόμενα μνήμης Βήμα 1: Μεταγλωττίστε το πιο κάτω πρόγραμμα ------------------------------------- #include <stdio.h> void display(void) { unsigned int a = 0xdeadbeef; printf("hello World: 0x%x\n", a); } int main(int argc, char *argv[]) { display(); return 1; } -------------------------------------- $gcc -Wall -ggdb -m32 -fno-pic -fno-stack-protector test.c -o test Compiler options: -Wall display all warnings -ggdb debugging information for gdb -m32 compile to Intel 32-bit machine code -no-pie do not produce position independent executable -fno-pic do not produce position independent code -fno-stack-protector do not use stack canaries
Να τρέξετε το πρόγραμμα σας: $./test Βήμα 2: Φορτώστε το πρόγραμμα σας στον debugger gdb Εάν επιθυμείτε να χωρίσετε την οθόνη στα δυο εκτελεστέ την εντολή $gdb -tui./test Διαφορετικά εκτελεστέ $ gdb./test GNU gdb (Ubuntu 7.12.50.20170314-0ubuntu1) 7.12.50.20170314-git Copyright (C) 2017 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"... Reading symbols from./test...(no debugging symbols found)...done. r [Inferior 1 (process 25686) exited with code 01]
Βήμα 3: Φορτώστε το πρόγραμμα σας στον debugger gdb, τρέξετε το μέχρι την συνάρτηση main, να δείτε τον κώδικα της συνάρτησης main και να προχωρήσετε μέχρι το τέλος του προγράμματος. start (stops at main function) Temporary breakpoint 1 at 0x804843c Temporary breakpoint 1, 0x0804843c in main () disas Dump of assembler code for function main: 0x0804842e <+0>: lea 0x4(%esp),%ecx 0x08048432 <+4>: and $0xfffffff0,%esp 0x08048435 <+7>: pushl -0x4(%ecx) 0x08048438 <+10>: push %ebp 0x08048439 <+11>: mov %esp,%ebp 0x0804843b <+13>: push %ecx => 0x0804843c <+14>: sub $0x4,%esp 0x0804843f <+17>: call 0x804840b <display> 0x08048444 <+22>: mov $0x1,%eax 0x08048449 <+27>: add $0x4,%esp 0x0804844c <+30>: pop %ecx 0x0804844d <+31>: pop %ebp 0x0804844e <+32>: lea -0x4(%ecx),%esp 0x08048451 <+35>: ret End of assembler dump. c [Inferior 1 (process 25704) exited with code 01] Βήμα 4: Να βάλετε ένα breakpoint στην συνάρτηση display και να τρέξετε το πρόγραμμα μας μέχρι το breakpoint, να παρατηρήσετε τον κώδικα τις συναρτήσεις display, μετα να τρέξετε το πρόγραμμα σας μέχρι το τέλος του προγράμματος. b display Breakpoint 2 at 0x8048411 r Breakpoint 2, 0x08048411 in display ()
disas Dump of assembler code for function display: 0x0804840b <+0>: push %ebp 0x0804840c <+1>: mov %esp,%ebp 0x0804840e <+3>: sub $0x18,%esp => 0x08048411 <+6>: movl $0xdeadbeef,-0xc(%ebp) 0x08048418 <+13>: sub $0x8,%esp 0x0804841b <+16>: pushl -0xc(%ebp) 0x0804841e <+19>: push $0x80484e0 0x08048423 <+24>: call 0x80482e0 <printf@plt> 0x08048428 <+29>: add $0x10,%esp 0x0804842b <+32>: nop 0x0804842c <+33>: leave 0x0804842d <+34>: ret End of assembler dump. c [Inferior 1 (process 25707) exited with code 01] Βήμα 5: Να ελέγξετε τα breakpoints, να διαγράψετε και να προσθέσετε breakpoint στην συνάρτηση display info b Num Type Disp Enb Address What 2 breakpoint keep y 0x08048411 <display+6> breakpoint already hit 1 time d 2 b display Breakpoint 3 at 0x8048411 r Breakpoint 3, 0x08048411 in display () c [Inferior 1 (process 25710) exited with code 01] quit
Βήμα 6: Τρέξετε το πρόγραμμα σας μέχρι την συνάρτηση main, ελέγξετε τους καταχώρητες και τρέξετε το μέχρι την συνάρτηση display. Να εκτελείται εντολή εντολή και να ελέγχετε τον stack σας, επίσης να βρείτε το EBP και την διεύθυνση επιστροφής. b display Breakpoint 1 at 0x8048411: file test.c, line 5. start Temporary breakpoint 2 at 0x804843f: file test.c, line 12. Temporary breakpoint 2, main (argc=1, argv=0xffffd384) at test.c:12 12 display(); i r eax 0xf7fb6dbc -134517316 ecx 0xffffd2f0-11536 edx 0xffffd314-11500 ebx 0x0 0 esp 0xffffd2d0 0xffffd2d0 ebp 0xffffd2d8 0xffffd2d8 esi 0x1 1 edi 0xf7fb5000-134524928 eip 0x804843f 0x804843f <main+17> eflags 0x282 [ SF IF ] cs 0x23 35 ss 0x2b 43 ds 0x2b 43 es 0x2b 43 fs 0x0 0 gs 0x63 99 c Breakpoint 1, display () at test.c:5 5 unsigned int a = 0xdeadbeef; i r eax 0xf7fb6dbc -134517316 ecx 0xffffd2f0-11536 edx 0xffffd314-11500 ebx 0x0 0 esp 0xffffd2b0 0xffffd2b0 ebp 0xffffd2c8 0xffffd2c8 esi 0x1 1 edi 0xf7fb5000-134524928
eip 0x8048411 0x8048411 <display+6> eflags 0x282 [ SF IF ] cs 0x23 35 ss 0x2b 43 ds 0x2b 43 es 0x2b 43 fs 0x0 0 gs 0x63 99 disas Dump of assembler code for function display: 0x0804840b <+0>: push %ebp 0x0804840c <+1>: mov %esp,%ebp 0x0804840e <+3>: sub $0x18,%esp => 0x08048411 <+6>: movl $0xdeadbeef,-0xc(%ebp) 0x08048418 <+13>: sub $0x8,%esp 0x0804841b <+16>: pushl -0xc(%ebp) 0x0804841e <+19>: push $0x80484e0 0x08048423 <+24>: call 0x80482e0 <printf@plt> 0x08048428 <+29>: add $0x10,%esp 0x0804842b <+32>: nop 0x0804842c <+33>: leave 0x0804842d <+34>: ret End of assembler dump. ni 7 printf("hello World: 0x%x\n", a); x/32x $ebp-32 0xffffd2a8: 0xf7ffcd00 0x00040000 0x00000000 0xffffd384 0xffffd2b8: 0xf7e2f940 0xdeadbeef 0x00000001 0xffffd384 0xffffd2c8: 0xffffd2d8 0x08048444 0xf7fb53dc 0xffffd2f0 0xffffd2d8: 0x00000000 0xf7e19276 0x00000001 0xf7fb5000 0xffffd2e8: 0x00000000 0xf7e19276 0x00000001 0xffffd384 0xffffd2f8: 0xffffd38c 0x00000000 0x00000000 0x00000000 0xffffd308: 0xf7fb5000 0xf7ffdc04 0xf7ffd000 0x00000000 0xffffd318: 0x00000001 0xf7fb5000 0x00000000 0x4ce28a7c where #0 display () at test.c:7 #1 0x08048444 in main (argc=1, argv=0xffffd384) at test.c:12 NOTES: 1) Before breaking to display() EBP has value: 0xffffd2d8 2) The return address is 0x08048444 (shown in the 'where' command) 3) Address for argv is 0xffffd384 4) The stack should be (from higher address to lower addresses):
Return Address EBP pointer to argv argc Local variables (0xdeadbeef) All these should be identified by the students. Βήμα 7: Να γράψετε ένα πρόγραμμα το οποίο εμφανίζει τις πληροφορίες του stack, frame pointer, argv,argc (Write a program that dumps the stack (display the return address, the frame pointer, argv, etc.).