lab2 binary bomb解析
第一关
1 08048b30 <phase_1>: 2 8048b30: 55 push %ebp 3 8048b31: 89 e5 mov %esp,%ebp 4 8048b33: 83 ec 10 sub $0x10,%esp 5 8048b36: 68 44 a0 04 08 push $0x804a044 //第一个参数,地址是0x804a044 6 8048b3b: ff 75 08 pushl 0x8(%ebp) //第二个参数,输入 7 8048b3e: e8 9a 04 00 00 call 8048fdd <strings_not_equal>//比较字符串的函数,由提示推测不相同返回1。 8 //调用函数后返回值都是存储在EAX中 9 8048b43: 83 c4 10 add $0x10,%esp 10 8048b46: 85 c0 test %eax,%eax //相与,以判断eax是否为0,eax=0时,置ZF=1 11 8048b48: 74 05 je 8048b4f <phase_1+0x1f> //ZF=1时跳转,通关 12 8048b4a: e8 91 05 00 00 call 80490e0 <explode_bomb> //否则爆炸 13 8048b4f: c9 leave 14 8048b50: c3 ret
第二关
1 08048b51 <phase_2>://第一个数字1,后一个是前一个的两倍1 2 4 8 16 32 2 8048b51: 55 push %ebp 3 8048b52: 89 e5 mov %esp,%ebp 4 8048b54: 56 push %esi 5 8048b55: 53 push %ebx 6 8048b56: 83 ec 28 sub $0x28,%esp 7 8048b59: 65 a1 14 00 00 00 mov %gs:0x14,%eax 8 8048b5f: 89 45 f4 mov %eax,-0xc(%ebp) 9 8048b62: 31 c0 xor %eax,%eax //栈保护 10 11 8048b64: 8d 45 dc lea -0x24(%ebp),%eax 12 8048b67: 50 push %eax 13 8048b68: ff 75 08 pushl 0x8(%ebp) 14 8048b6b: e8 98 05 00 00 call 8049108 //读入六个数字<read_six_numbers>,返回1表示成功读入六个整数 15 16 8048b70: 83 c4 10 add $0x10,%esp 17 8048b73: 83 7d dc 01 cmpl $0x1,-0x24(%ebp) //-0x24(%ebp)与常数1比较 1:1 18 8048b77: 74 05 je 8048b7e <phase_2+0x2d> //相等跳转,否则爆炸 19 8048b79: e8 62 05 00 00 call 80490e0 <explode_bomb> //高 20 8048b7e: 8d 5d dc lea -0x24(%ebp),%ebx 21 8048b81: 8d 75 f0 lea -0x10(%ebp),%esi 22 8048b84: 8b 03 mov (%ebx),%eax 23 8048b86: 01 c0 add %eax,%eax //乘2,左移一位 24 8048b88: 39 43 04 cmp %eax,0x4(%ebx) 25 8048b8b: 74 05 je 8048b92 <phase_2+0x41> //相等跳转 26 8048b8d: e8 4e 05 00 00 call 80490e0 <explode_bomb> //否则爆炸 27 8048b92: 83 c3 04 add $0x4,%ebx 28 8048b95: 39 f3 cmp %esi,%ebx 29 8048b97: 75 eb jne 8048b84 <phase_2+0x33> 30 8048b99: 8b 45 f4 mov -0xc(%ebp),%eax 31 8048b9c: 65 33 05 14 00 00 00 xor %gs:0x14,%eax 32 8048ba3: 74 05 je 8048baa <phase_2+0x59> 33 8048ba5: e8 e6 fb ff ff call 8048790 <__stack_chk_fail@plt> 34 8048baa: 8d 65 f8 lea -0x8(%ebp),%esp 35 8048bad: 5b pop %ebx 36 8048bae: 5e pop %esi 37 8048baf: 5d pop %ebp 38 8048bb0: c3 ret
第三关
1 08048bb1 <phase_3>: 2 8048bb1: 55 push %ebp 3 8048bb2: 89 e5 mov %esp,%ebp 4 8048bb4: 83 ec 18 sub $0x18,%esp 5 8048bb7: 65 a1 14 00 00 00 mov %gs:0x14,%eax 6 8048bbd: 89 45 f4 mov %eax,-0xc(%ebp) 7 8048bc0: 31 c0 xor %eax,%eax 8 8048bc2: 8d 45 f0 lea -0x10(%ebp),%eax 9 8048bc5: 50 push %eax 10 8048bc6: 8d 45 ec lea -0x14(%ebp),%eax 11 8048bc9: 50 push %eax 12 8048bca: 68 0f a2 04 08 push $0x804a20f 13 8048bcf: ff 75 08 pushl 0x8(%ebp) 14 8048bd2: e8 39 fc ff ff call 8048810 <__isoc99_sscanf@plt> 15 8048bd7: 83 c4 10 add $0x10,%esp 16 8048bda: 83 f8 01 cmp $0x1,%eax 17 8048bdd: 7f 05 jg 8048be4 <phase_3+0x33>//返回值,成功读入两个数 18 8048bdf: e8 fc 04 00 00 call 80490e0 <explode_bomb> 19 20 8048be4: 83 7d ec 07 cmpl $0x7,-0x14(%ebp) 21 8048be8: 77 3b ja 8048c25 <phase_3+0x74> //<bomb>第一个数不大于7 22 23 8048bea: 8b 45 ec mov -0x14(%ebp),%eax //eax=x1 24 8048bed: ff 24 85 a0 a0 04 08 jmp *0x804a0a0(,%eax,4) //804a0a0+4*x 25 26 8048bf4: b8 db 00 00 00 mov $0xdb,%eax 27 8048bf9: eb 3b jmp 8048c36 <phase_3+0x85> 28 8048bfb: b8 42 03 00 00 mov $0x342,%eax 29 8048c00: eb 34 jmp 8048c36 <phase_3+0x85> 30 8048c02: b8 78 03 00 00 mov $0x378,%eax 31 8048c07: eb 2d jmp 8048c36 <phase_3+0x85> 32 8048c09: b8 7a 03 00 00 mov $0x37a,%eax 33 8048c0e: eb 26 jmp 8048c36 <phase_3+0x85> 34 8048c10: b8 8a 03 00 00 mov $0x38a,%eax 35 8048c15: eb 1f jmp 8048c36 <phase_3+0x85> 36 8048c17: b8 b5 03 00 00 mov $0x3b5,%eax 37 8048c1c: eb 18 jmp 8048c36 <phase_3+0x85> 38 8048c1e: b8 e4 00 00 00 mov $0xe4,%eax 39 8048c23: eb 11 jmp 8048c36 <phase_3+0x85> 40 //switch case 41 42 8048c25: e8 b6 04 00 00 call 80490e0 <explode_bomb> 43 8048c2a: b8 00 00 00 00 mov $0x0,%eax 44 8048c2f: eb 05 jmp 8048c36 <phase_3+0x85> 45 8048c31: b8 7f 03 00 00 mov $0x37f,%eax 46 8048c36: 3b 45 f0 cmp -0x10(%ebp),%eax //比较第二个数和此时的eax。 47 8048c39: 74 05 je 8048c40 <phase_3+0x8f> //相等通过 48 8048c3b: e8 a0 04 00 00 call 80490e0 <explode_bomb> 49 8048c40: 8b 45 f4 mov -0xc(%ebp),%eax 50 8048c43: 65 33 05 14 00 00 00 xor %gs:0x14,%eax 51 8048c4a: 74 05 je 8048c51 <phase_3+0xa0> 52 8048c4c: e8 3f fb ff ff call 8048790 <__stack_chk_fail@plt> 53 8048c51: c9 leave 54 8048c52: c3 ret
查看条件转移指令的寄存器值
1 gdb 2 b phase_3 3 r 4 ni 5 6 Info reg 7 1 219

第四关
1 08048c9e <phase_4>: 2 8048c9e: 55 push %ebp 3 8048c9f: 89 e5 mov %esp,%ebp 4 8048ca1: 83 ec 18 sub $0x18,%esp //24=4*6 5 8048ca4: 65 a1 14 00 00 00 mov %gs:0x14,%eax 6 8048caa: 89 45 f4 mov %eax,-0xc(%ebp) 7 8048cad: 31 c0 xor %eax,%eax 8 8048caf: 8d 45 ec lea -0x14(%ebp),%eax 9 8048cb2: 50 push %eax 10 8048cb3: 8d 45 f0 lea -0x10(%ebp),%eax 11 8048cb6: 50 push %eax 12 8048cb7: 68 0f a2 04 08 push $0x804a20f //输入格式,2个数 13 8048cbc: ff 75 08 pushl 0x8(%ebp) 14 8048cbf: e8 4c fb ff ff call 8048810 <__isoc99_sscanf@plt> 15 8048cc4: 83 c4 10 add $0x10,%esp 16 8048cc7: 83 f8 02 cmp $0x2,%eax 17 8048cca: 75 0b jne 8048cd7 <phase_4+0x39>//不等于时<bomb>,应输入两个 18 8048ccc: 8b 45 ec mov -0x14(%ebp),%eax //第一个数 eax=x1 19 8048ccf: 83 e8 02 sub $0x2,%eax //eax=x1-2 20 8048cd2: 83 f8 02 cmp $0x2,%eax 21 8048cd5: 76 05 jbe 8048cdc <phase_4+0x3e>//eax<=2跳转继续,否则bomb,x1<=4 22 8048cd7: e8 04 04 00 00 call 80490e0 <explode_bomb> 23 24 8048cdc: 83 ec 08 sub $0x8,%esp 25 8048cdf: ff 75 ec pushl -0x14(%ebp) //x1<=4传给func4第二个参数 26 8048ce2: 6a 09 push $0x9 //9 27 8048ce4: e8 6a ff ff ff call 8048c53 <func4> 28 29 8048ce9: 83 c4 10 add $0x10,%esp 30 8048cec: 3b 45 f0 cmp -0x10(%ebp),%eax //func4返回值与第二个参数X2比较 31 8048cef: 74 05 je 8048cf6 <phase_4+0x58> 32 8048cf1: e8 ea 03 00 00 call 80490e0 <explode_bomb> 33 8048cf6: 8b 45 f4 mov -0xc(%ebp),%eax 34 8048cf9: 65 33 05 14 00 00 00 xor %gs:0x14,%eax 35 8048d00: 74 05 je 8048d07 <phase_4+0x69> 36 8048d02: e8 89 fa ff ff call 8048790 <__stack_chk_fail@plt> 37 8048d07: c9 leave 38 8048d08: c3 ret 39 40 08048c53 <func4>: 41 8048c53: 55 push %ebp 42 8048c54: 89 e5 mov %esp,%ebp 43 8048c56: 57 push %edi 44 8048c57: 56 push %esi 45 8048c58: 53 push %ebx 46 8048c59: 83 ec 0c sub $0xc,%esp 47 8048c5c: 8b 5d 08 mov 0x8(%ebp),%ebx 48 8048c5f: 8b 7d 0c mov 0xc(%ebp),%edi 49 8048c62: 85 db test %ebx,%ebx 50 8048c64: 7e 2b jle 8048c91 <func4+0x3e> 51 8048c66: 89 f8 mov %edi,%eax 52 8048c68: 83 fb 01 cmp $0x1,%ebx 53 8048c6b: 74 29 je 8048c96 <func4+0x43> 54 8048c6d: 83 ec 08 sub $0x8,%esp 55 8048c70: 57 push %edi 56 8048c71: 8d 43 ff lea -0x1(%ebx),%eax 57 8048c74: 50 push %eax 58 8048c75: e8 d9 ff ff ff call 8048c53 <func4> 59 //返回值eax(1)=x1 60 8048c7a: 83 c4 08 add $0x8,%esp 61 8048c7d: 8d 34 07 lea (%edi,%eax,1),%esi //esi(1)=edi(1)+eax(0); 62 8048c80: 57 push %edi 63 8048c81: 83 eb 02 sub $0x2,%ebx 64 8048c84: 53 push %ebx 65 8048c85: e8 c9 ff ff ff call 8048c53 <func4> 66 8048c8a: 83 c4 10 add $0x10,%esp 67 8048c8d: 01 f0 add %esi,%eax 68 8048c8f: eb 05 jmp 8048c96 <func4+0x43> 69 8048c91: b8 00 00 00 00 mov $0x0,%eax 70 8048c96: 8d 65 f4 lea -0xc(%ebp),%esp 71 8048c99: 5b pop %ebx 72 8048c9a: 5e pop %esi 73 8048c9b: 5f pop %edi 74 8048c9c: 5d pop %ebp 75 8048c9d: c3 ret

输入的第一个参数应该不超过4,当第一个参数是4时,第二个参数应该等于352,由此得到一组答案:4 352.
第五关
1 08048d09 <phase_5>: 2 8048d09: 55 push %ebp 3 8048d0a: 89 e5 mov %esp,%ebp 4 8048d0c: 83 ec 18 sub $0x18,%esp 5 8048d0f: 65 a1 14 00 00 00 mov %gs:0x14,%eax 6 8048d15: 89 45 f4 mov %eax,-0xc(%ebp) 7 8048d18: 31 c0 xor %eax,%eax 8 8048d1a: 8d 45 f0 lea -0x10(%ebp),%eax 9 8048d1d: 50 push %eax 10 8048d1e: 8d 45 ec lea -0x14(%ebp),%eax 11 8048d21: 50 push %eax 12 8048d22: 68 0f a2 04 08 push $0x804a20f //"%d %d"x1 x2 13 8048d27: ff 75 08 pushl 0x8(%ebp) 14 8048d2a: e8 e1 fa ff ff call 8048810 <__isoc99_sscanf@plt> 15 16 8048d2f: 83 c4 10 add $0x10,%esp 17 8048d32: 83 f8 01 cmp $0x1,%eax 18 8048d35: 7f 05 jg 8048d3c <phase_5+0x33>//成功读入 19 8048d37: e8 a4 03 00 00 call 80490e0 <explode_bomb> 20 21 8048d3c: 8b 45 ec mov -0x14(%ebp),%eax //保存第一个数:x1 22 8048d3f: 83 e0 0f and $0xf,%eax //按位与//只留低4位 23 8048d42: 89 45 ec mov %eax,-0x14(%ebp) //结果覆盖掉第一个参数x1 24 8048d45: 83 f8 0f cmp $0xf,%eax 25 8048d48: 74 2c je 8048d76 <phase_5+0x6d> //eax 16不可为f,即输入的数用二进制表示最低4位要有0 26 27 8048d4a: b9 00 00 00 00 mov $0x0,%ecx //ecx=0 28 8048d4f: ba 00 00 00 00 mov $0x0,%edx //edx=0 29 30 31 //循环 32 8048d54: 83 c2 01 add $0x1,%edx //edx++ 33 8048d57: 8b 04 85 c0 a0 04 08 mov 0x804a0c0(,%eax,4),%eax //整型数组 34 eax=0x804a0c0+eax*4=0x804a0c4,arr[eax] 35 8048d5e: 01 c1 add %eax,%ecx //ecx+=eax 36 8048d60: 83 f8 0f cmp $0xf,%eax 37 8048d63: 75 ef jne 8048d54 <phase_5+0x4b>//循环结束条件eax=0xf
经过15次循环之后,eax的值若恰好为15,则能够安全跳出,而eax中的值是我们输入的参数1,ecx存放的是每次循环时eax数的加和。

当x1=5时,符合要求,得到的x2=115
1 8048d65: c7 45 ec 0f 00 00 00 movl $0xf,-0x14(%ebp) 2 8048d6c: 83 fa 0f cmp $0xf,%edx 3 8048d6f: 75 05 jne 8048d76 <phase_5+0x6d> //edx要等于16 4 8048d71: 3b 4d f0 cmp -0x10(%ebp),%ecx //ecx要等于第二个参数 5 8048d74: 74 05 je 8048d7b <phase_5+0x72> 6 8048d76: e8 65 03 00 00 call 80490e0 <explode_bomb>

1 8048d7b: 8b 45 f4 mov -0xc(%ebp),%eax 2 8048d7e: 65 33 05 14 00 00 00 xor %gs:0x14,%eax 3 8048d85: 74 05 je 8048d8c <phase_5+0x83> 4 8048d87: e8 04 fa ff ff call 8048790 <__stack_chk_fail@plt> 5 8048d8c: c9 leave 6 8048d8d: c3 ret
第六关
1 08048d8e <phase_6>: 2 08048d8e <phase_6>: 3 8048d8e: 55 push %ebp 4 8048d8f: 89 e5 mov %esp,%ebp 5 8048d91: 56 push %esi 6 8048d92: 53 push %ebx 7 8048d93: 83 ec 48 sub $0x48,%esp 8 8048d96: 65 a1 14 00 00 00 mov %gs:0x14,%eax 9 8048d9c: 89 45 f4 mov %eax,-0xc(%ebp) 10 8048d9f: 31 c0 xor %eax,%eax 11 8048da1: 8d 45 c4 lea -0x3c(%ebp),%eax 12 8048da4: 50 push %eax 13 8048da5: ff 75 08 pushl 0x8(%ebp) 14 8048da8: e8 5b 03 00 00 call 8049108 <read_six_numbers>//输入6个数 15 8048dad: 83 c4 10 add $0x10,%esp 16 8048db0: be 00 00 00 00 mov $0x0,%esi //s=0 17 8048db5: 8b 44 b5 c4 mov -0x3c(%ebp,%esi,4),%eax //获取输入 18 8048db9: 83 e8 01 sub $0x1,%eax //eax-=1 19 8048dbc: 83 f8 05 cmp $0x5,%eax //比较5和a 20 8048dbf: 76 05 jbe 8048dc6 <phase_6+0x38> //<=5否则爆炸 21 8048dc1: e8 1a 03 00 00 call 80490e0 <explode_bomb> 22 8048dc6: 83 c6 01 add $0x1,%esi //s+=1 23 8048dc9: 83 fe 06 cmp $0x6,%esi //比较s和6 24 8048dcc: 74 1b je 8048de9 <phase_6+0x5b> //相等跳转 25 8048dce: 89 f3 mov %esi,%ebx //b=s 26 8048dd0: 8b 44 9d c4 mov -0x3c(%ebp,%ebx,4),%eax //eax赋值 27 8048dd4: 39 44 b5 c0 cmp %eax,-0x40(%ebp,%esi,4) //比较上一个参数 28 8048dd8: 75 05 jne 8048ddf <phase_6+0x51> //不相等,否则爆炸 29 8048dda: e8 01 03 00 00 call 80490e0 <explode_bomb> 30 输入的六个数要<=5且不相同。 31 32 8048ddf: 83 c3 01 add $0x1,%ebx //b=b+1 33 8048de2: 83 fb 05 cmp $0x5,%ebx //比较b和5 34 8048de5: 7e e9 jle 8048dd0 <phase_6+0x42> 35 8048de7: eb cc jmp 8048db5 <phase_6+0x27> 36 8048de9: 8d 45 c4 lea -0x3c(%ebp),%eax 37 8048dec: 8d 5d dc lea -0x24(%ebp),%ebx 38 8048def: b9 07 00 00 00 mov $0x7,%ecx //c=7 39 8048df4: 89 ca mov %ecx,%edx //d=7 40 8048df6: 2b 10 sub (%eax),%edx //d=d-eax 41 //改变后x=7-x 42 8048df8: 89 10 mov %edx,(%eax) 43 8048dfa: 83 c0 04 add $0x4,%eax 44 8048dfd: 39 c3 cmp %eax,%ebx //比较ebx和eax的 45 8048dff: 75 f3 jne 8048df4 <phase_6+0x66> 46 8048e01: bb 00 00 00 00 mov $0x0,%ebx 47 8048e06: eb 16 jmp 8048e1e <phase_6+0x90> //跳转 48 8048e08: 8b 52 08 mov 0x8(%edx),%edx //下一个链表元素 49 8048e0b: 83 c0 01 add $0x1,%eax //a=a+1 50 8048e0e: 39 c8 cmp %ecx,%eax 51 8048e10: 75 f6 jne 8048e08 <phase_6+0x7a> 52 8048e12: 89 54 b5 dc mov %edx,-0x24(%ebp,%esi,4)//修改链表中值 53 8048e16: 83 c3 01 add $0x1,%ebx //b=b+1 54 8048e19: 83 fb 06 cmp $0x6,%ebx 55 8048e1c: 74 17 je 8048e35 <phase_6+0xa7>//循环6次 56 8048e1e: 89 de mov %ebx,%esi//s=b 57 8048e20: 8b 4c 9d c4 mov -0x3c(%ebp,%ebx,4),%ecx 58 8048e24: b8 01 00 00 00 mov $0x1,%eax//a=1 59 8048e29: ba 3c c1 04 08 mov $0x804c13c,%edx
链表结构

每个链表有3个参数,第一个为当前节点的值,第二个为在链表中的序号,第三个为指向的下一个链表的地址。
1 8048e2e: 83 f9 01 cmp $0x1,%ecx//c与1 2 8048e31: 7f d5 jg 8048e08 <phase_6+0x7a>//大于回跳 3 8048e33: eb dd jmp 8048e12 <phase_6+0x84>//回跳 4 8048e35: 8b 5d dc mov -0x24(%ebp),%ebx 5 8048e38: 8d 45 dc lea -0x24(%ebp),%eax 6 8048e3b: 8d 75 f0 lea -0x10(%ebp),%esi 7 8048e3e: 89 d9 mov %ebx,%ecx//c=b 8 8048e40: 8b 50 04 mov 0x4(%eax),%edx 9 8048e43: 89 51 08 mov %edx,0x8(%ecx) 10 8048e46: 83 c0 04 add $0x4,%eax//a=4 11 8048e49: 89 d1 mov %edx,%ecx//c=d 12 8048e4b: 39 c6 cmp %eax,%esi//s=i 13 8048e4d: 75 f1 jne 8048e40 <phase_6+0xb2>//不相等跳转 14 8048e4f: c7 42 08 00 00 00 00 movl $0x0,0x8(%edx) 15 8048e56: be 05 00 00 00 mov $0x5,%esi//s=5 16 8048e5b: 8b 43 08 mov 0x8(%ebx),%eax//eax赋值 17 8048e5e: 8b 00 mov (%eax),%eax //地址赋值 18 8048e60: 39 03 cmp %eax,(%ebx)//比较i与i-1个节点 19 8048e62: 7d 05 jge 8048e69 <phase_6+0xdb>//>=否则爆炸 20 按序号降序排列 21 8048e64: e8 77 02 00 00 call 80490e0 <explode_bomb> 22 8048e69: 8b 5b 08 mov 0x8(%ebx),%ebx//b移位。移到下一个 23 8048e6c: 83 ee 01 sub $0x1,%esi //s=s-1 24 8048e6f: 75 ea jne 8048e5b <phase_6+0xcd> 查看zf是否为1,否则循环 25 8048e71: 8b 45 f4 mov -0xc(%ebp),%eax //移位 26 8048e74: 65 33 05 14 00 00 00 xor %gs:0x14,%eax 27 8048e7b: 74 05 je 8048e82 <phase_6+0xf4> //相等通过 28 8048e7d: e8 0e f9 ff ff call 8048790 <__stack_chk_fail@plt> 29 8048e82: 8d 65 f8 lea -0x8(%ebp),%esp 30 8048e85: 5b pop %ebx 31 8048e86: 5e pop %esi 32 8048e87: 5d pop %ebp 33 8048e88: c3 ret
1 814 2 913 3 241 4 764 5 141 6 407
2 1 4 6 3 5
5 6 3 1 4 2

浙公网安备 33010602011771号