This file is an extended transcript of a debugging session in which I solved phase 2 and 3 of the bomb lab, using the bomb available from the CS:APP website. http://csapp.cs.cmu.edu/public/1e/public/labs.html $ gdb ./bomb ... (gdb) b phase_2 Breakpoint 1 at 0x8048b50 (gdb) r input.txt Starting program: /home/student/bomb/bomb input.txt Welcome to my fiendish little bomb. You have 6 phases with which to blow yourself up. Have a nice day! Phase 1 defused. How about the next one? dog cat pig Breakpoint 1, 0x08048b50 in phase_2 () (gdb) disas Dump of assembler code for function phase_2: ... 0x08048b4b : sub $0x20,%esp // allocate stack space 0x08048b4e : push %esi // save callee registers 0x08048b4f : push %ebx // save callee registers 0x08048b50 : mov 0x8(%ebp),%edx // %edx = arg1 0x08048b53 : add $0xfffffff8,%esp // allocate stack space 0x08048b56 : lea -0x18(%ebp),%eax // %eax = &tmp 0x08048b59 : push %eax // Push &tmp 0x08048b5a : push %edx // Push arg1 0x08048b5b : call 0x8048fd8 // read_six_numbers(arg1,&tmp) ... (gdb) b read_six_numbers Breakpoint 2 at 0x8048fde (gdb) c Continuing. Breakpoint 2, 0x08048fde in read_six_numbers () (gdb) disas Dump of assembler code for function read_six_numbers: ... 0x08048fdb : sub $0x8,%esp // allocate stack space 0x08048fde : mov 0x8(%ebp),%ecx // %ecx = arg1 0x08048fe1 : mov 0xc(%ebp),%edx // %edx = arg2 0x08048fe4 : lea 0x14(%edx),%eax // Push &arg2[5] 0x08048fe7 : push %eax 0x08048fe8 : lea 0x10(%edx),%eax // Push &arg2[3] 0x08048feb : push %eax 0x08048fec : lea 0xc(%edx),%eax // Push &arg2[4] 0x08048fef : push %eax 0x08048ff0 : lea 0x8(%edx),%eax // Push &arg2[2] 0x08048ff3 : push %eax 0x08048ff4 : lea 0x4(%edx),%eax // Push &arg2[1] 0x08048ff7 : push %eax 0x08048ff8 : push %edx // Push &arg2[0] 0x08048ff9 : push $0x8049b1b // Push $0x8049b1b 0x08048ffe : push %ecx // Push arg1 0x08048fff : call 0x8048860 ... (gdb) x/s 0x8049b1b 0x8049b1b: "%d %d %d %d %d %d" (gdb) clear read_six_numbers Deleted breakpoint 2 (gdb) clear phase_2 Deleted breakpoint 1 (gdb) b *0x08048b5b Breakpoint 3 at 0x8048b5b (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/student/bomb/bomb input.txt Welcome to my fiendish little bomb. You have 6 phases with which to blow yourself up. Have a nice day! Phase 1 defused. How about the next one? 11 12 13 14 15 16 Breakpoint 3, 0x08048b5b in phase_2 () (gdb) disas ... 0x08048b56 : lea -0x18(%ebp),%eax // %eax = &tmp 0x08048b59 : push %eax // Push &tmp 0x08048b5a : push %edx // Push arg1 0x08048b5b : call 0x8048fd8 // read_six_numbers(arg1,&tmp) ... (gdb) ni 0x08048b60 in phase_2 () (gdb) p *((int*)($ebp-0x18)) $2 = 11 (gdb) p *((int*)($ebp-0x18+0x04)) $4 = 12 (gdb) p *((int*)($ebp-0x18+0x08)) $5 = 13 (gdb) p *((int*)($ebp-0x18+0x0C)) $6 = 14 (gdb) p *((int*)($ebp-0x18+0x10)) $7 = 15 (gdb) p *((int*)($ebp-0x18+0x14)) $8 = 16 (gdb) x/d $ebp - 0x18 0xbfdd7dc0: 11 (gdb) x/d $ebp - 0x18 + 0x4 0xbfdd7dc4: 12 (gdb) x/d $ebp - 0x18 + 0x8 0xbfdd7dc8: 13 (gdb) x/d $ebp - 0x18 + 0xC 0xbfdd7dcc: 14 (gdb) x/4d $ebp - 0x18 0xbfdd7dc0: 11 12 13 14 (gdb) x/8d $ebp - 0x18 0xbfdd7dc0: 11 12 13 14 0xbfdd7dd0: 15 16 -1076003320 134515331 (gdb) disas ... 0x08048b60 : add $0x10,%esp // deallocate stack space 0x08048b63 : cmpl $0x1,-0x18(%ebp) // if (tmp[0] == 1) 0x08048b67 : je 0x8048b6e // goto next1 0x08048b69 : call 0x80494fc // explode_bomb() 0x08048b6e : mov $0x1,%ebx // next1: %ebx = 1 ... (gdb) si 0x08048b63 in phase_2 () (gdb) si 0x08048b67 in phase_2 () (gdb) si 0x08048b69 in phase_2 () // THE EDGE OF DISASTER!!! (gdb) delete Delete all breakpoints? (y or n) y (gdb) b *0x08048b67 Breakpoint 4 at 0x8048b67 (gdb) r bombin.txt The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/student/bomb/bomb input.txt Welcome to my fiendish little bomb. You have 6 phases with which to blow yourself up. Have a nice day! Phase 1 defused. How about the next one? 1 12 13 14 15 16 Breakpoint 4, 0x08048b67 in phase_2 () (gdb) si 0x08048b6e in phase_2 () // HURRAY! (gdb) disas ... 0x08048b6e : mov $0x1,%ebx // next1: %ebx = 1 0x08048b73 : lea -0x18(%ebp),%esi // %esi = &tmp[0] 0x08048b76 : lea 0x1(%ebx),%eax // loop: ? 0x08048b79 : imul -0x4(%esi,%ebx,4),%eax // ? 0x08048b7e : cmp %eax,(%esi,%ebx,4) // if (?) 0x08048b81 : je 0x8048b88 // goto next2: 0x08048b83 : call 0x80494fc // explode_bomb() (AVOID!!!) 0x08048b88 : inc %ebx // next2: ? 0x08048b89 : cmp $0x5,%ebx // if (?) 0x08048b8c : jle 0x8048b76 // goto loop (BACKWARD JUMP IS A LOOP) 0x08048b8e : lea -0x28(%ebp),%esp // ? ... (gdb) until *0x08048b7e 0x08048b7e in phase_2 () (gdb) p $eax $9 = 2 (gdb) p *((int*)($esi+$ebx*4)) $10 = 12 (gdb) delete Delete all breakpoints? (y or n) y (gdb) b *0x08048b7e Breakpoint 5 at 0x8048b7e (gdb) r bombin.txt The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/student/bomb/bomb input.txt Welcome to my fiendish little bomb. You have 6 phases with which to blow yourself up. Have a nice day! Phase 1 defused. How about the next one? 1 2 11 12 13 14 Breakpoint 5, 0x08048b7e in phase_2 () (gdb) p $eax $11 = 2 (gdb) p *((int*)($esi+$ebx*4)) $12 = 2 (gdb) c Continuing. Breakpoint 5, 0x08048b7e in phase_2 () (gdb) p $eax $13 = 6 (gdb) p *((int*)($esi+$ebx*4)) $14 = 11 (gdb) r bombin.txt The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/student/bomb/bomb input.txt Welcome to my fiendish little bomb. You have 6 phases with which to blow yourself up. Have a nice day! Phase 1 defused. How about the next one? 1 2 6 11 12 13 Breakpoint 5, 0x08048b7e in phase_2 () (gdb) c Continuing. Breakpoint 5, 0x08048b7e in phase_2 () (gdb) p $eax $16 = 6 (gdb) p *((int*)($esi+$ebx*4)) $15 = 6 (gdb) c Continuing. Breakpoint 5, 0x08048b7e in phase_2 () (gdb) p $eax $18 = 24 (gdb) p *((int*)($esi+$ebx*4)) $17 = 11 (gdb) r bombin.txt The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/student/bomb/bomb input.txt Welcome to my fiendish little bomb. You have 6 phases with which to blow yourself up. Have a nice day! Phase 1 defused. How about the next one? 1 2 6 24 11 12 Breakpoint 5, 0x08048b7e in phase_2 () (gdb) c Continuing. Breakpoint 5, 0x08048b7e in phase_2 () (gdb) c Continuing. Breakpoint 5, 0x08048b7e in phase_2 () (gdb) c Continuing. Breakpoint 5, 0x08048b7e in phase_2 () (gdb) p $eax $19 = 120 (gdb) r bombin.txt The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/student/bomb/bomb input.txt Welcome to my fiendish little bomb. You have 6 phases with which to blow yourself up. Have a nice day! Phase 1 defused. How about the next one? 1 2 6 24 120 720 //Factorial!!! Breakpoint 5, 0x08048b7e in phase_2 () (gdb) c Continuing. Breakpoint 5, 0x08048b7e in phase_2 () (gdb) c Continuing. Breakpoint 5, 0x08048b7e in phase_2 () (gdb) c Continuing. Breakpoint 5, 0x08048b7e in phase_2 () (gdb) c Continuing. Breakpoint 5, 0x08048b7e in phase_2 () (gdb) p $eax $20 = 720 (gdb) c Continuing. That's number 2. Keep going! ------------------------------------------------------------------------ If you want to understand the loop in phase_2 you can proceed as follows: 0x08048b6e : mov $0x1,%ebx // %ebx = 1 0x08048b73 : lea -0x18(%ebp),%esi // %esi = &tmp[0] 0x08048b76 : lea 0x1(%ebx),%eax // loop: %eax = %ebx + 1 0x08048b79 : imul -0x4(%esi,%ebx,4),%eax // %eax = (%ebx+1) * tmp[%ebx-1] 0x08048b7e : cmp %eax,(%esi,%ebx,4) // if (%eax == tmp[%ebx]) 0x08048b81 : je 0x8048b88 // goto next2 0x08048b83 : call 0x80494fc // explode_bomb() 0x08048b88 : inc %ebx // next2: %ebx ++ 0x08048b89 : cmp $0x5,%ebx // if (%ebx < 5) 0x08048b8c : jle 0x8048b76 // goto loop execution as: with input 1 2 6 0x08048b6e : mov $0x1,%ebx // %ebx = 1 0x08048b73 : lea -0x18(%ebp),%esi // %esi = &tmp[0] 0x08048b76 : lea 0x1(%ebx),%eax // loop: %eax = 2 0x08048b79 : imul -0x4(%esi,%ebx,4),%eax // %eax = 2 * 1 0x08048b7e : cmp %eax,(%esi,%ebx,4) // if (2 == tmp[1]) 0x08048b81 : je 0x8048b88 // goto next2 0x08048b88 : inc %ebx // next2: %ebx = 2 0x08048b89 : cmp $0x5,%ebx // if (%ebx < 5) 0x08048b8c : jle 0x8048b76 // goto loop 0x08048b76 : lea 0x1(%ebx),%eax // loop: %eax = 3 0x08048b79 : imul -0x4(%esi,%ebx,4),%eax // %eax = 3 * 2 0x08048b7e : cmp %eax,(%esi,%ebx,4) // if (6 == tmp[2]) 0x08048b81 : je 0x8048b88 // goto next2 0x08048b88 : inc %ebx // next2: %ebx = 3 0x08048b89 : cmp $0x5,%ebx // if (%ebx < 5) 0x08048b8c : jle 0x8048b76 // goto loop 0x08048b76 : lea 0x1(%ebx),%eax // loop: %eax = 4 0x08048b79 : imul -0x4(%esi,%ebx,4),%eax // %eax = 4 * 6 0x08048b7e : cmp %eax,(%esi,%ebx,4) // if (24 == tmp[3]) ... ------------------------------------------------------------------------ Using display: $ gdb ./bomb ... (gdb) b *0x08048b7e Breakpoint 1 at 0x8048b7e (gdb) r input.txt Starting program: /home/jriely/student/bomb/bomb input.txt Welcome to my fiendish little bomb. You have 6 phases with which to blow yourself up. Have a nice day! Phase 1 defused. How about the next one? 1 2 6 24 120 720 Breakpoint 2, 0x08048b7e in phase_2 () (gdb) disp $eax 1: $eax = 2 (gdb) disp *((int*)($esi+($ebx*4))) 2: *(int *) ($esi + $ebx * 4) = 2 (gdb) c Continuing. Breakpoint 2, 0x08048b7e in phase_2 () 2: *(int *) ($esi + $ebx * 4) = 6 1: $eax = 6 (gdb) c Continuing. Breakpoint 2, 0x08048b7e in phase_2 () 2: *(int *) ($esi + $ebx * 4) = 24 1: $eax = 24 (gdb) c Continuing. Breakpoint 2, 0x08048b7e in phase_2 () 2: *(int *) ($esi + $ebx * 4) = 120 1: $eax = 120 (gdb) c Continuing. Breakpoint 2, 0x08048b7e in phase_2 () 2: *(int *) ($esi + $ebx * 4) = 720 1: $eax = 720 (gdb) q The program is running. Exit anyway? (y or n) y -------------------------------------------------------------------- Now for phase 3! student@bomb:~/bomb$ cat input.txt Public speaking is very easy. 1 2 6 24 120 720 student@bomb:~/bomb$ gdb ./bomb GNU gdb 6.8-debian Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later 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 "i486-linux-gnu"... (gdb) b phase_3 Breakpoint 1 at 0x8048b9f (gdb) r input.txt Starting program: /home/student/bomb/bomb input.txt Welcome to my fiendish little bomb. You have 6 phases with which to blow yourself up. Have a nice day! Phase 1 defused. How about the next one? That's number 2. Keep going! 3 c 25 Breakpoint 1, 0x08048b9f in phase_3 () (gdb) disas Dump of assembler code for function phase_3: 0x08048b98 : push %ebp 0x08048b99 : mov %esp,%ebp 0x08048b9b : sub $0x14,%esp 0x08048b9e : push %ebx 0x08048b9f : mov 0x8(%ebp),%edx 0x08048ba2 : add $0xfffffff4,%esp 0x08048ba5 : lea -0x4(%ebp),%eax 0x08048ba8 : push %eax 0x08048ba9 : lea -0x5(%ebp),%eax 0x08048bac : push %eax 0x08048bad : lea -0xc(%ebp),%eax 0x08048bb0 : push %eax 0x08048bb1 : push $0x80497de 0x08048bb6 : push %edx 0x08048bb7 : call 0x8048860 0x08048bbc : add $0x20,%esp 0x08048bbf : cmp $0x2,%eax 0x08048bc2 : jg 0x8048bc9 0x08048bc4 : call 0x80494fc 0x08048bc9 : cmpl $0x7,-0xc(%ebp) 0x08048bcd : ja 0x8048c88 0x08048bd3 : mov -0xc(%ebp),%eax 0x08048bd6 : jmp *0x80497e8(,%eax,4) 0x08048bdd : lea 0x0(%esi),%esi 0x08048be0 : mov $0x71,%bl 0x08048be2 : cmpl $0x309,-0x4(%ebp) 0x08048be9 : je 0x8048c8f 0x08048bef : call 0x80494fc 0x08048bf4 : jmp 0x8048c8f 0x08048bf9 : lea 0x0(%esi,%eiz,1),%esi 0x08048c00 : mov $0x62,%bl 0x08048c02 : cmpl $0xd6,-0x4(%ebp) 0x08048c09 : je 0x8048c8f 0x08048c0f : call 0x80494fc 0x08048c14 : jmp 0x8048c8f 0x08048c16 : mov $0x62,%bl 0x08048c18 : cmpl $0x2f3,-0x4(%ebp) 0x08048c1f : je 0x8048c8f 0x08048c21 : call 0x80494fc 0x08048c26 : jmp 0x8048c8f 0x08048c28 : mov $0x6b,%bl 0x08048c2a : cmpl $0xfb,-0x4(%ebp) 0x08048c31 : je 0x8048c8f 0x08048c33 : call 0x80494fc 0x08048c38 : jmp 0x8048c8f 0x08048c3a : lea 0x0(%esi),%esi 0x08048c40 : mov $0x6f,%bl 0x08048c42 : cmpl $0xa0,-0x4(%ebp) 0x08048c49 : je 0x8048c8f 0x08048c4b : call 0x80494fc 0x08048c50 : jmp 0x8048c8f 0x08048c52 : mov $0x74,%bl 0x08048c54 : cmpl $0x1ca,-0x4(%ebp) 0x08048c5b : je 0x8048c8f 0x08048c5d : call 0x80494fc 0x08048c62 : jmp 0x8048c8f 0x08048c64 : mov $0x76,%bl 0x08048c66 : cmpl $0x30c,-0x4(%ebp) 0x08048c6d : je 0x8048c8f 0x08048c6f : call 0x80494fc 0x08048c74 : jmp 0x8048c8f 0x08048c76 : mov $0x62,%bl 0x08048c78 : cmpl $0x20c,-0x4(%ebp) 0x08048c7f : je 0x8048c8f 0x08048c81 : call 0x80494fc 0x08048c86 : jmp 0x8048c8f 0x08048c88 : mov $0x78,%bl 0x08048c8a : call 0x80494fc 0x08048c8f : cmp -0x5(%ebp),%bl 0x08048c92 : je 0x8048c99 0x08048c94 : call 0x80494fc 0x08048c99 : mov -0x18(%ebp),%ebx 0x08048c9c : mov %ebp,%esp 0x08048c9e : pop %ebp 0x08048c9f : ret End of assembler dump. // WE'LL LOOK AFTER SSCANF RETURNS (gdb) b *0x08048bbc Breakpoint 2 at 0x8048bbc (gdb) c Continuing. // THE INPUT STRING IS THE LAST ARGUMENT TO SSCANF (gdb) x/a $ebp+8 0xbffffc40: 0x804b720 (gdb) x/s 0x804b720 0x804b720 : "3 c 25" // THE FORMAT IS THE SECOND TO LAST ARGUMENT TO SSCANF (gdb) x/s 0x80497de 0x80497de: "%d %c %d" // NOW I AM GOING TO CHECK THAT THE INPUTS GOT IN THERE CORRECTLY Breakpoint 2, 0x08048bbc in phase_3 () (gdb) x/d $ebp-4 0xbffffc34: 25 (gdb) x/c $ebp-5 0xbffffc33: 99 'c' (gdb) x/d $ebp-0xc 0xbffffc2c: 3 // EXCITMENT STARTS WHEN WE GET TO JUMP TABLE (gdb) b *0x08048bd6 Breakpoint 3 at 0x8048bd6 (gdb) c Continuing. Breakpoint 3, 0x08048bd6 in phase_3 () // LETS PRINT THE JUMP TABLE (I ADDED SPACES TO THE DISAS ABOVE TO SHOW THE TABLE) (gdb) x/8x 0x80497e8 0x80497e8: 0x08048be0 0x08048c00 0x08048c16 0x08048c28 0x80497f8: 0x08048c40 0x08048c52 0x08048c64 0x08048c76 (gdb) x/8a 0x80497e8 0x80497e8: 0x8048be0 0x8048c00 0x8048c16 0x8048c28 0x80497f8: 0x8048c40 0x8048c52 0x8048c64 0x8048c76 // WHEN WE CONTINUE, WE SHOULD GO TO THE FOURTH ENTRY, SINCE MY INPUT WAS "3" (gdb) si 0x08048c28 in phase_3 () // IT WORKED! LOOKING AT THE CODE I CAN SEE THAT I NEEDED TO ENTER "0xFB" OR "251" RATHER THAN "25" (gdb) delete Delete all breakpoints? (y or n) y (gdb) b *0x08048c28 Breakpoint 4 at 0x8048c28 (gdb) r input.txt The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/student/bomb/bomb input.txt Welcome to my fiendish little bomb. You have 6 phases with which to blow yourself up. Have a nice day! Phase 1 defused. How about the next one? That's number 2. Keep going! 3 c 251 Breakpoint 4, 0x08048c28 in phase_3 () (gdb) si 0x08048c2a in phase_3 () (gdb) si 0x08048c31 in phase_3 () (gdb) si 0x08048c8f in phase_3 () // LOOKING AT THE CODE WE SEE THAT WE ARE GOING TO CHECK THE CHARACTER INPUT AGAINST %BL (gdb) p $bl $2 = void // THAT DOESN'T WORK! (gdb) p/x $ebx $3 = 0xbffffc6b // HEX 6B IS THE LETTER "k" (gdb) delete Delete all breakpoints? (y or n) y (gdb) b phase_4 Breakpoint 5 at 0x8048ce6 (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/student/bomb/bomb input.txt Welcome to my fiendish little bomb. You have 6 phases with which to blow yourself up. Have a nice day! Phase 1 defused. How about the next one? That's number 2. Keep going! 3 k 251 Halfway there! NOW TESTING PHASE 4!!!! Breakpoint 5, 0x08048ce6 in phase_4 () (gdb)