当前位置: 首页 > news >正文

免费1级做爰片在线观看 历史网站wordpress优化技巧

免费1级做爰片在线观看 历史网站,wordpress优化技巧,加盟装修公司哪家好,工业产品设计用什么软件文章目录 前言实验内容phase_1phase_2phase_3phase_4phase_5phase_6secret_phase 前言 刚做了csapp lab2#xff0c;记录一下。 我这里用的的系统环境是Ubuntu22.04#xff0c;是64位系统#xff0c;与用32位系统可能有所差异。 实验共包括七个阶段#xff0c;每个阶段考… 文章目录 前言实验内容phase_1phase_2phase_3phase_4phase_5phase_6secret_phase 前言 刚做了csapp lab2记录一下。 我这里用的的系统环境是Ubuntu22.04是64位系统与用32位系统可能有所差异。 实验共包括七个阶段每个阶段考察机器级语言程序的不同方面难度递增 阶段一字符串比较阶段二循环阶段三条件/分支含switch语句阶段四递归调用和栈阶段五指针阶段六链表/指针/结构隐藏阶段第四阶段之后附加特定字符串后出现 在实验过程中gdb调试起到了相当重要的作用下面是我调试过程中频繁使用的几条指令不熟悉gdb的小伙伴一定要熟悉一下 r ans.txt - 开始运行ans.txt为命令行参数可以省略 c - 运行至下一个断点处 b \*addr - 在addr处的指令打断点 d num - 删除断点num display /x %reg - 每次执行完指令时打印寄存器rgx的值 undisplay num - 删除监视变量num ni - 执行下一条指令 x/nws addr - x是examine表示进行内存检查n表示显示n个数据项w表示以8个字节为单位进行显示s是以字符串的形式显示解释可以替换成x以十六进制的形式进行解释可以替换成u以十进制的形式进行解释 为了方便我们创建一个ans.txt文件每做出来一题就把答案写进去这样就避免了一条一条输入答案。一题占一行要注意最后要多一个空行目的是最后一题的输入以 换行符结尾保证是正确输入 实验内容 phase_1 找到 phase_1 函数在 main 函数中被调用的位置 8048a6d: c7 04 24 70 a0 04 08 movl $0x804a070,(%esp)8048a74: e8 47 fd ff ff call 80487c0 putsplt8048a79: e8 69 07 00 00 call 80491e7 read_line8048a7e: 89 04 24 mov %eax,(%esp)8048a81: e8 aa 00 00 00 call 8048b30 phase_18048a86: e8 5f 08 00 00 call 80492ea phase_defused在反汇编文件中继续查找 phase_1 的位置 08048b30 phase_1:8048b30: 55 push %ebp8048b31: 89 e5 mov %esp,%ebp8048b33: 83 ec 10 sub $0x10,%esp8048b36: 68 ec a0 04 08 push $0x804a0ec8048b3b: ff 75 08 push 0x8(%ebp)8048b3e: e8 3f 05 00 00 call 8049082 strings_not_equal8048b43: 83 c4 10 add $0x10,%esp8048b46: 85 c0 test %eax,%eax8048b48: 74 05 je 8048b4f phase_10x1f8048b4a: e8 36 06 00 00 call 8049185 explode_bomb8048b4f: c9 leave 8048b50: c3 ret $0x804a0ec: 数据区地址也是 strings_not_equal 的第二个参数 0x8(%ebp): phase_1 的参数也是 strings_not_equal 的第一个参数 在main()函数的汇编代码中可以进一步找到 8048a79: e8 69 07 00 00 call 80491e7 read_line8048a7e: 89 04 24 mov %eax,(%esp)%eax 里存储的是调用 read_line 函数的返回值也是用户输入的字符串首地址 推测拆弹密码字符串的存储地址为 $0x804a0ec因为调用 strings_not_equal前有语句 8048b36: 68 ec a0 04 08 push $0x804a0ec 执行 gdb bomb 找到答案When a problem comes along, you must zip it! phase_2 查看phase_2的代码 08048b51 phase_2:8048b51: 55 push %ebp8048b52: 89 e5 mov %esp,%ebp8048b54: 53 push %ebx8048b55: 83 ec 2c sub $0x2c,%esp8048b58: 65 a1 14 00 00 00 mov %gs:0x14,%eax8048b5e: 89 45 f4 mov %eax,-0xc(%ebp)8048b61: 31 c0 xor %eax,%eax8048b63: 8d 45 dc lea -0x24(%ebp),%eax8048b66: 50 push %eax8048b67: ff 75 08 push 0x8(%ebp)8048b6a: e8 3e 06 00 00 call 80491ad read_six_numbers8048b6f: 83 c4 10 add $0x10,%esp8048b72: 83 7d dc 00 cmpl $0x0,-0x24(%ebp)8048b76: 79 05 jns 8048b7d phase_20x2c8048b78: e8 08 06 00 00 call 8049185 explode_bomb8048b7d: bb 01 00 00 00 mov $0x1,%ebx 8048b82: 89 d8 mov %ebx,%eax 8048b84: 03 44 9d d8 add -0x28(%ebp,%ebx,4),%eax8048b88: 39 44 9d dc cmp %eax,-0x24(%ebp,%ebx,4)8048b8c: 74 05 je 8048b93 phase_20x428048b8e: e8 f2 05 00 00 call 8049185 explode_bomb8048b93: 83 c3 01 add $0x1,%ebx8048b96: 83 fb 06 cmp $0x6,%ebx8048b99: 75 e7 jne 8048b82 phase_20x318048b9b: 8b 45 f4 mov -0xc(%ebp),%eax8048b9e: 65 33 05 14 00 00 00 xor %gs:0x14,%eax8048ba5: 74 05 je 8048bac phase_20x5b8048ba7: e8 e4 fb ff ff call 8048790 __stack_chk_failplt8048bac: 8b 5d fc mov -0x4(%ebp),%ebx8048baf: c9 leave 8048bb0: c3 ret 关注到8048b6a: e8 3e 06 00 00 call 80491ad read_six_numbers这题应该是要输入六个数字。 观察这部分汇编代码 8048b7d: bb 01 00 00 00 mov $0x1,%ebx 8048b82: 89 d8 mov %ebx,%eax 8048b84: 03 44 9d d8 add -0x28(%ebp,%ebx,4),%eax8048b88: 39 44 9d dc cmp %eax,-0x24(%ebp,%ebx,4)8048b8c: 74 05 je 8048b93 phase_20x428048b8e: e8 f2 05 00 00 call 8049185 explode_bomb8048b93: 83 c3 01 add $0x1,%ebx8048b96: 83 fb 06 cmp $0x6,%ebx8048b99: 75 e7 jne 8048b82 phase_20x31可以看出这就是一段循环循环次数为5每次循环是做一次比较%ebx是循环计数器每轮循环结束后 1。循环内会进行一次比较如果两个数不相等就会爆炸。那么关键就是待比较的两个数。 ebx比较数1比较数211 ebp-0x281*4ebp-0x241*422 ebp-0x282*4ebp-0x242*433 ebp-0x283*4ebp-0x243*444 ebp-0x284*4ebp-0x244*455 ebp-0x285*4ebp-0x245*4 经过观察和不断地调试发现比较数1是第一个输入的数ebx比较数2是第二个输入的数。 经过大量试错调试最终得出这一题的答案输入六个数每两个数之间的差依次为1/2/3/4/5。 所以这样得到本题的一组答案1 2 4 7 11 16当然答案不唯一比如符合条件的2 3 5 8 12 17也是可以通 过的。 部分调试记录截图 这题后面的比较循环一开始看到以6结尾想当然地认为循环比较六次这样就多出来一个输入的数百思不得其解在网上查阅相关教程发现题目也不一样。最终就逐步调试发现只是循环了5次这样就对上了。在调试过程中也找到了本题的答案。 phase_3 先把phase_3的代码贴出来 08048bb1 phase_3:8048bb1: 55 push %ebp8048bb2: 89 e5 mov %esp,%ebp8048bb4: 83 ec 24 sub $0x24,%esp8048bb7: 65 a1 14 00 00 00 mov %gs:0x14,%eax8048bbd: 89 45 f4 mov %eax,-0xc(%ebp)8048bc0: 31 c0 xor %eax,%eax8048bc2: 8d 45 f0 lea -0x10(%ebp),%eax8048bc5: 50 push %eax8048bc6: 8d 45 eb lea -0x15(%ebp),%eax8048bc9: 50 push %eax8048bca: 8d 45 ec lea -0x14(%ebp),%eax8048bcd: 50 push %eax8048bce: 68 42 a1 04 08 push $0x804a1428048bd3: ff 75 08 push 0x8(%ebp)8048bd6: e8 35 fc ff ff call 8048810 __isoc99_sscanfplt8048bdb: 83 c4 20 add $0x20,%esp8048bde: 83 f8 02 cmp $0x2,%eax8048be1: 7f 05 jg 8048be8 phase_30x378048be3: e8 9d 05 00 00 call 8049185 explode_bomb8048be8: 83 7d ec 07 cmpl $0x7,-0x14(%ebp)8048bec: 0f 87 ef 00 00 00 ja 8048ce1 phase_30x1308048bf2: 8b 45 ec mov -0x14(%ebp),%eax8048bf5: ff 24 85 54 a1 04 08 jmp *0x804a154(,%eax,4)8048bfc: b8 78 00 00 00 mov $0x78,%eax8048c01: 81 7d f0 44 01 00 00 cmpl $0x144,-0x10(%ebp)8048c08: 0f 84 dd 00 00 00 je 8048ceb phase_30x13a8048c0e: e8 72 05 00 00 call 8049185 explode_bomb8048c13: b8 78 00 00 00 mov $0x78,%eax8048c18: e9 ce 00 00 00 jmp 8048ceb phase_30x13a8048c1d: b8 69 00 00 00 mov $0x69,%eax8048c22: 81 7d f0 99 01 00 00 cmpl $0x199,-0x10(%ebp)8048c29: 0f 84 bc 00 00 00 je 8048ceb phase_30x13a8048c2f: e8 51 05 00 00 call 8049185 explode_bomb8048c34: b8 69 00 00 00 mov $0x69,%eax8048c39: e9 ad 00 00 00 jmp 8048ceb phase_30x13a8048c3e: b8 74 00 00 00 mov $0x74,%eax8048c43: 81 7d f0 f6 02 00 00 cmpl $0x2f6,-0x10(%ebp)8048c4a: 0f 84 9b 00 00 00 je 8048ceb phase_30x13a8048c50: e8 30 05 00 00 call 8049185 explode_bomb8048c55: b8 74 00 00 00 mov $0x74,%eax8048c5a: e9 8c 00 00 00 jmp 8048ceb phase_30x13a8048c5f: b8 68 00 00 00 mov $0x68,%eax8048c64: 81 7d f0 37 02 00 00 cmpl $0x237,-0x10(%ebp)8048c6b: 74 7e je 8048ceb phase_30x13a8048c6d: e8 13 05 00 00 call 8049185 explode_bomb8048c72: b8 68 00 00 00 mov $0x68,%eax8048c77: eb 72 jmp 8048ceb phase_30x13a8048c79: b8 79 00 00 00 mov $0x79,%eax8048c7e: 81 7d f0 1c 03 00 00 cmpl $0x31c,-0x10(%ebp)8048c85: 74 64 je 8048ceb phase_30x13a8048c87: e8 f9 04 00 00 call 8049185 explode_bomb8048c8c: b8 79 00 00 00 mov $0x79,%eax8048c91: eb 58 jmp 8048ceb phase_30x13a8048c93: b8 62 00 00 00 mov $0x62,%eax8048c98: 81 7d f0 bd 01 00 00 cmpl $0x1bd,-0x10(%ebp)8048c9f: 74 4a je 8048ceb phase_30x13a8048ca1: e8 df 04 00 00 call 8049185 explode_bomb8048ca6: b8 62 00 00 00 mov $0x62,%eax8048cab: eb 3e jmp 8048ceb phase_30x13a8048cad: b8 64 00 00 00 mov $0x64,%eax8048cb2: 81 7d f0 5a 03 00 00 cmpl $0x35a,-0x10(%ebp)8048cb9: 74 30 je 8048ceb phase_30x13a8048cbb: e8 c5 04 00 00 call 8049185 explode_bomb8048cc0: b8 64 00 00 00 mov $0x64,%eax8048cc5: eb 24 jmp 8048ceb phase_30x13a8048cc7: b8 65 00 00 00 mov $0x65,%eax8048ccc: 81 7d f0 50 02 00 00 cmpl $0x250,-0x10(%ebp)8048cd3: 74 16 je 8048ceb phase_30x13a8048cd5: e8 ab 04 00 00 call 8049185 explode_bomb8048cda: b8 65 00 00 00 mov $0x65,%eax8048cdf: eb 0a jmp 8048ceb phase_30x13a8048ce1: e8 9f 04 00 00 call 8049185 explode_bomb8048ce6: b8 6b 00 00 00 mov $0x6b,%eax8048ceb: 3a 45 eb cmp -0x15(%ebp),%al8048cee: 74 05 je 8048cf5 phase_30x1448048cf0: e8 90 04 00 00 call 8049185 explode_bomb8048cf5: 8b 45 f4 mov -0xc(%ebp),%eax8048cf8: 65 33 05 14 00 00 00 xor %gs:0x14,%eax8048cff: 74 05 je 8048d06 phase_30x1558048d01: e8 8a fa ff ff call 8048790 __stack_chk_failplt8048d06: c9 leave 8048d07: c3 ret 首先观察到phase_3的代码中有一段 8048bce: 68 42 a1 04 08 push $0x804a1428048bd3: ff 75 08 push 0x8(%ebp)8048bd6: e8 35 fc ff ff call 8048810 __isoc99_sscanfplt其中$0x804a142是输入格式字符串这里要作为参数压栈传递给sscanf查看一下 (gdb) x/s 0x804a142 0x804a142: %d %c %d这题的输入就是两个整数中间用字符隔开。 紧接着的一段代码也印证了这一点 8048bdb: 83 c4 20 add $0x20,%esp8048bde: 83 f8 02 cmp $0x2,%eax8048be1: 7f 05 jg 8048be8 phase_30x378048be3: e8 9d 05 00 00 call 8049185 explode_bombeax也就是sscanf的返回值也就是输入的变量的个数如果小于等于2就bomb。 紧接着有一个判断 8048be8: 83 7d ec 07 cmpl $0x7,-0x14(%ebp)8048bec: 0f 87 ef 00 00 00 ja 8048ce1 phase_30x130如果-0x14(%ebp) 0x7就会跳转这里会跳转到call explode_bomb所以要求-0x14(%ebp) 7那它是什么呢观察调用sscanf之前的一段代码 8048bc2: 8d 45 f0 lea -0x10(%ebp),%eax8048bc5: 50 push %eax8048bc6: 8d 45 eb lea -0x15(%ebp),%eax8048bc9: 50 push %eax8048bca: 8d 45 ec lea -0x14(%ebp),%eax8048bcd: 50 push %eax根据参数传递的顺序应该是我们输入的第一个数这也就要求我们输入的第一个数小于等于7。 继续往下看发现程序会跳转并且跳转的位置和我们输入的数相关联 8048bf2: 8b 45 ec mov -0x14(%ebp),%eax8048bf5: ff 24 85 54 a1 04 08 jmp *0x804a154(,%eax,4)用第一个输入的数是1进行下一步调试 跳转到了 8048c1d: b8 69 00 00 00 mov $0x69,%eax8048c22: 81 7d f0 99 01 00 00 cmpl $0x199,-0x10(%ebp)8048c29: 0f 84 bc 00 00 00 je 8048ceb phase_30x13a8048c2f: e8 51 05 00 00 call 8049185 explode_bomb继续看这里把eax更新成了0x69并且比较了我们的第三个输入也就是第二个整数和0x199也就是409所以确定了我们要输入的第二个数是409接下来程序跳转到了8048ceb 8048ceb: 3a 45 eb cmp -0x15(%ebp),%al8048cee: 74 05 je 8048cf5 phase_30x1448048cf0: e8 90 04 00 00 call 8049185 explode_bomb8048cf5: 8b 45 f4 mov -0xc(%ebp),%eax8048cf8: 65 33 05 14 00 00 00 xor %gs:0x14,%eax8048cff: 74 05 je 8048d06 phase_30x1558048d01: e8 8a fa ff ff call 8048790 __stack_chk_failplt8048d06: c9 leave 8048d07: c3 ret 这里比较的是我们输入的字符和%al%al是累加器寄存器eax的低八位如下图所示转成十进制就是105所以我们要输入的字符的ascii码值是105也就是i。这样就得到了最终的答案1i409 不过这道题应该有8个答案因为输入的第一个整数有8个取值所以会有八个分支对应八个答案。 phase_4 先贴代码 08048d08 func4:8048d08: 55 push %ebp8048d09: 89 e5 mov %esp,%ebp8048d0b: 56 push %esi8048d0c: 53 push %ebx8048d0d: 8b 55 08 mov 0x8(%ebp),%edx8048d10: 8b 4d 0c mov 0xc(%ebp),%ecx8048d13: 8b 75 10 mov 0x10(%ebp),%esi8048d16: 89 f0 mov %esi,%eax8048d18: 29 c8 sub %ecx,%eax8048d1a: 89 c3 mov %eax,%ebx8048d1c: c1 eb 1f shr $0x1f,%ebx8048d1f: 01 d8 add %ebx,%eax8048d21: d1 f8 sar %eax8048d23: 8d 1c 08 lea (%eax,%ecx,1),%ebx8048d26: 39 d3 cmp %edx,%ebx8048d28: 7e 15 jle 8048d3f func40x378048d2a: 83 ec 04 sub $0x4,%esp8048d2d: 8d 43 ff lea -0x1(%ebx),%eax8048d30: 50 push %eax8048d31: 51 push %ecx8048d32: 52 push %edx8048d33: e8 d0 ff ff ff call 8048d08 func48048d38: 83 c4 10 add $0x10,%esp8048d3b: 01 d8 add %ebx,%eax8048d3d: eb 19 jmp 8048d58 func40x508048d3f: 89 d8 mov %ebx,%eax8048d41: 39 d3 cmp %edx,%ebx8048d43: 7d 13 jge 8048d58 func40x508048d45: 83 ec 04 sub $0x4,%esp8048d48: 56 push %esi8048d49: 8d 43 01 lea 0x1(%ebx),%eax8048d4c: 50 push %eax8048d4d: 52 push %edx8048d4e: e8 b5 ff ff ff call 8048d08 func48048d53: 83 c4 10 add $0x10,%esp8048d56: 01 d8 add %ebx,%eax8048d58: 8d 65 f8 lea -0x8(%ebp),%esp8048d5b: 5b pop %ebx8048d5c: 5e pop %esi8048d5d: 5d pop %ebp8048d5e: c3 ret 08048d5f phase_4:8048d5f: 55 push %ebp8048d60: 89 e5 mov %esp,%ebp8048d62: 83 ec 18 sub $0x18,%esp8048d65: 65 a1 14 00 00 00 mov %gs:0x14,%eax8048d6b: 89 45 f4 mov %eax,-0xc(%ebp)8048d6e: 31 c0 xor %eax,%eax8048d70: 8d 45 f0 lea -0x10(%ebp),%eax8048d73: 50 push %eax8048d74: 8d 45 ec lea -0x14(%ebp),%eax8048d77: 50 push %eax8048d78: 68 93 a2 04 08 push $0x804a2938048d7d: ff 75 08 push 0x8(%ebp)8048d80: e8 8b fa ff ff call 8048810 __isoc99_sscanfplt8048d85: 83 c4 10 add $0x10,%esp8048d88: 83 f8 02 cmp $0x2,%eax8048d8b: 75 06 jne 8048d93 phase_40x348048d8d: 83 7d ec 0e cmpl $0xe,-0x14(%ebp)8048d91: 76 05 jbe 8048d98 phase_40x398048d93: e8 ed 03 00 00 call 8049185 explode_bomb8048d98: 83 ec 04 sub $0x4,%esp8048d9b: 6a 0e push $0xe8048d9d: 6a 00 push $0x08048d9f: ff 75 ec push -0x14(%ebp)8048da2: e8 61 ff ff ff call 8048d08 func48048da7: 83 c4 10 add $0x10,%esp8048daa: 83 f8 13 cmp $0x13,%eax8048dad: 75 06 jne 8048db5 phase_40x568048daf: 83 7d f0 13 cmpl $0x13,-0x10(%ebp)8048db3: 74 05 je 8048dba phase_40x5b8048db5: e8 cb 03 00 00 call 8049185 explode_bomb8048dba: 8b 45 f4 mov -0xc(%ebp),%eax8048dbd: 65 33 05 14 00 00 00 xor %gs:0x14,%eax8048dc4: 74 05 je 8048dcb phase_40x6c8048dc6: e8 c5 f9 ff ff call 8048790 __stack_chk_failplt8048dcb: c9 leave 8048dcc: c3 ret 还是先观察调用sscanf之前的代码确定输入格式 8048d70: 8d 45 f0 lea -0x10(%ebp),%eax8048d73: 50 push %eax8048d74: 8d 45 ec lea -0x14(%ebp),%eax8048d77: 50 push %eax8048d78: 68 93 a2 04 08 push $0x804a2938048d7d: ff 75 08 push 0x8(%ebp)8048d80: e8 8b fa ff ff call 8048810 __isoc99_sscanfplt8048d85: 83 c4 10 add $0x10,%esp8048d88: 83 f8 02 cmp $0x2,%eax8048d8b: 75 06 jne 8048d93 phase_40x34输入格式是两个整数中间用空格隔开。 其中第一个数存在-0x14(%ebp)第二个数存在-0x10(%ebp)。 继续向下看 8048d8d: 83 7d ec 0e cmpl $0xe,-0x14(%ebp)8048d91: 76 05 jbe 8048d98 phase_40x398048d93: e8 ed 03 00 00 call 8049185 explode_bomb这里比较了输入的第一个数和0xe也就是14说明第一个数要小于等于14这里还是用输入1来进一步调试。继续看代码 8048d98: 83 ec 04 sub $0x4,%esp8048d9b: 6a 0e push $0xe8048d9d: 6a 00 push $0x08048d9f: ff 75 ec push -0x14(%ebp)8048da2: e8 61 ff ff ff call 8048d08 func4调用了func4先分析一下参数第一个参数是输入的第一个整数第二个参数是 0第三个参数是0xe也就是14。继续分析func4的代码先看参数的处理 8048d0d: 8b 55 08 mov 0x8(%ebp),%edx8048d10: 8b 4d 0c mov 0xc(%ebp),%ecx8048d13: 8b 75 10 mov 0x10(%ebp),%esi这里把第一个参数也就是输入的第一个整数1赋给了edx把0赋给了ecx14赋给了esi继续看代码 8048d16: 89 f0 mov %esi,%eax8048d18: 29 c8 sub %ecx,%eax8048d1a: 89 c3 mov %eax,%ebx8048d1c: c1 eb 1f shr $0x1f,%ebx8048d1f: 01 d8 add %ebx,%eax8048d21: d1 f8 sar %eax8048d23: 8d 1c 08 lea (%eax,%ecx,1),%ebx8048d26: 39 d3 cmp %edx,%ebx8048d28: 7e 15 jle 8048d3f func40x37一直执行到比较之前各个寄存器存放的值如下 接下来过不了比较会继续向下执行 8048d2a: 83 ec 04 sub $0x4,%esp8048d2d: 8d 43 ff lea -0x1(%ebx),%eax8048d30: 50 push %eax8048d31: 51 push %ecx8048d32: 52 push %edx8048d33: e8 d0 ff ff ff call 8048d08 func4这样就开始了递归先看一下此时递归前各个寄存器存放的值 从左到右三个参数依次为1、0、1与上一次调用相比第三个参数发生了变化继续调试到比较 此时仍无法结束递归下面会进行第三次调用调用前各个寄存器的值如下 第三个参数变成了2继续调试到比较 此时终于符合条件ebx edx跳转到新阶段 8048d3f: 89 d8 mov %ebx,%eax8048d41: 39 d3 cmp %edx,%ebx8048d43: 7d 13 jge 8048d58 func40x50接下来有个判断要求ebx edx先看一下此时各个寄存器的值 符合条件跳转到新位置 8048d58: 8d 65 f8 lea -0x8(%ebp),%esp8048d5b: 5b pop %ebx8048d5c: 5e pop %esi8048d5d: 5d pop %ebp8048d5e: c3 ret 此时跳出第三次调用来到第二次调用的栈帧 8048d33: e8 d0 ff ff ff call 8048d08 func48048d38: 83 c4 10 add $0x10,%esp8048d3b: 01 d8 add %ebx,%eax8048d3d: eb 19 jmp 8048d58 func40x50跳转之前各个寄存器的值如下 第二次调用随之也结束来到第一次调用的栈帧还是与第二次一样返回phase_4之前eax变为11。 之后回到phase_4的栈帧 8048da2: e8 61 ff ff ff call 8048d08 func48048da7: 83 c4 10 add $0x10,%esp8048daa: 83 f8 13 cmp $0x13,%eax8048dad: 75 06 jne 8048db5 phase_40x568048daf: 83 7d f0 13 cmpl $0x13,-0x10(%ebp)8048db3: 74 05 je 8048dba phase_40x5b8048db5: e8 cb 03 00 00 call 8049185 explode_bomb此时各个寄存器的值如下 此时eax(11) ! 0x13(19)所以会爆炸所以拆弹的关键来到了eax。在经过函数递归之后eax的值要变为19那就观察一下eax的值是如何变化的。不过这里还能看出第二个输入的整数应该是0x13(19) 在分析eax的过程中被绕晕了索性摆烂反正最大不超过14一个个试试出了正确答案4。 所以这一题的最终答案就是4 19 phase_5 贴代码 08048dcd phase_5:8048dcd: 55 push %ebp8048dce: 89 e5 mov %esp,%ebp8048dd0: 53 push %ebx8048dd1: 83 ec 20 sub $0x20,%esp8048dd4: 8b 5d 08 mov 0x8(%ebp),%ebx8048dd7: 65 a1 14 00 00 00 mov %gs:0x14,%eax8048ddd: 89 45 f4 mov %eax,-0xc(%ebp)8048de0: 31 c0 xor %eax,%eax8048de2: 53 push %ebx8048de3: e8 78 02 00 00 call 8049060 string_length8048de8: 83 c4 10 add $0x10,%esp8048deb: 83 f8 06 cmp $0x6,%eax8048dee: 74 05 je 8048df5 phase_50x288048df0: e8 90 03 00 00 call 8049185 explode_bomb8048df5: b8 00 00 00 00 mov $0x0,%eax8048dfa: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx8048dfe: 83 e2 0f and $0xf,%edx8048e01: 0f b6 92 74 a1 04 08 movzbl 0x804a174(%edx),%edx8048e08: 88 54 05 ed mov %dl,-0x13(%ebp,%eax,1)8048e0c: 83 c0 01 add $0x1,%eax8048e0f: 83 f8 06 cmp $0x6,%eax8048e12: 75 e6 jne 8048dfa phase_50x2d8048e14: c6 45 f3 00 movb $0x0,-0xd(%ebp)8048e18: 83 ec 08 sub $0x8,%esp8048e1b: 68 4b a1 04 08 push $0x804a14b8048e20: 8d 45 ed lea -0x13(%ebp),%eax8048e23: 50 push %eax8048e24: e8 59 02 00 00 call 8049082 strings_not_equal8048e29: 83 c4 10 add $0x10,%esp8048e2c: 85 c0 test %eax,%eax8048e2e: 74 05 je 8048e35 phase_50x688048e30: e8 50 03 00 00 call 8049185 explode_bomb8048e35: 8b 45 f4 mov -0xc(%ebp),%eax8048e38: 65 33 05 14 00 00 00 xor %gs:0x14,%eax8048e3f: 74 05 je 8048e46 phase_50x798048e41: e8 4a f9 ff ff call 8048790 __stack_chk_failplt8048e46: 8b 5d fc mov -0x4(%ebp),%ebx8048e49: c9 leave 8048e4a: c3 ret 先看部分代码 8048de3: e8 78 02 00 00 call 8049060 string_length8048de8: 83 c4 10 add $0x10,%esp8048deb: 83 f8 06 cmp $0x6,%eax8048dee: 74 05 je 8048df5 phase_50x288048df0: e8 90 03 00 00 call 8049185 explode_bomb一开始调用了一次string_length并且比较了一下字符串的长度和6如果不相等就会爆炸需要知道string_length是计算的谁的长度 经过测试发现是我们输入的字符串的长度这样就确定了我们要输入的字符串的长度是6。 接下来是一段循环 8048df5: b8 00 00 00 00 mov $0x0,%eax8048dfa: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx8048dfe: 83 e2 0f and $0xf,%edx8048e01: 0f b6 92 74 a1 04 08 movzbl 0x804a174(%edx),%edx8048e08: 88 54 05 ed mov %dl,-0x13(%ebp,%eax,1)8048e0c: 83 c0 01 add $0x1,%eax8048e0f: 83 f8 06 cmp $0x6,%eax8048e12: 75 e6 jne 8048dfa phase_50x2deax从0开始每次1直到等于6。分析一下这个循环做了什么。 首先给edx赋值且这个值随着循环次数改变而改变然后保留edx低4位把某个地址加上第四位作为偏移量得到的地址处的值赋给edx然后把这个值赋给-0x13(%ebp,%eax,1)只占一个字节空间猜测每一次取了一个字符并且后面调用了strings_not_equal 8048e1b: 68 4b a1 04 08 push $0x804a14b8048e20: 8d 45 ed lea -0x13(%ebp),%eax8048e23: 50 push %eax8048e24: e8 59 02 00 00 call 8049082 strings_not_equal六次循环得到一个字符串并把这个字符串的首地址作为参数传给strings_not_equal所以这六个字符串是什么呢答案在0x804a14b 所以要通过循环构造出这么一个字符串。循环是从0x804a174加偏移得到的先看一下0x804a174指向的内容 很显然要从maduiersnfotvbylSo通过加偏移量的方式依次构造出f l a m e s偏移量依次是9 15 1 0 5 7偏移量从哪来呢 8048dd4: 8b 5d 08 mov 0x8(%ebp),%ebx 很显然是传过来的参数这个参数就是我们输入的字符串所以是取我们输入的字符串对应的ascii码值的低四位作为偏移量所以答案的要求就出来了低四位分别是1001(9) 1111(15) 0001(1) 0000(0) 0101(5) 0111(7) 令高位为0100(64)得到一组解I(73) O(79) A(65) (64) E(69) G(71)所以正确答案就是IOAEG。 phase_6 贴代码 08048e4b phase_6:8048e4b: 55 push %ebp8048e4c: 89 e5 mov %esp,%ebp8048e4e: 56 push %esi8048e4f: 53 push %ebx8048e50: 83 ec 48 sub $0x48,%esp8048e53: 65 a1 14 00 00 00 mov %gs:0x14,%eax8048e59: 89 45 f4 mov %eax,-0xc(%ebp)8048e5c: 31 c0 xor %eax,%eax8048e5e: 8d 45 c4 lea -0x3c(%ebp),%eax8048e61: 50 push %eax8048e62: ff 75 08 push 0x8(%ebp)8048e65: e8 43 03 00 00 call 80491ad read_six_numbers8048e6a: 83 c4 10 add $0x10,%esp8048e6d: be 00 00 00 00 mov $0x0,%esi8048e72: 8b 44 b5 c4 mov -0x3c(%ebp,%esi,4),%eax8048e76: 83 e8 01 sub $0x1,%eax8048e79: 83 f8 05 cmp $0x5,%eax8048e7c: 76 05 jbe 8048e83 phase_60x388048e7e: e8 02 03 00 00 call 8049185 explode_bomb8048e83: 83 c6 01 add $0x1,%esi8048e86: 83 fe 06 cmp $0x6,%esi8048e89: 74 33 je 8048ebe phase_60x738048e8b: 89 f3 mov %esi,%ebx8048e8d: 8b 44 9d c4 mov -0x3c(%ebp,%ebx,4),%eax8048e91: 39 44 b5 c0 cmp %eax,-0x40(%ebp,%esi,4)8048e95: 75 05 jne 8048e9c phase_60x518048e97: e8 e9 02 00 00 call 8049185 explode_bomb8048e9c: 83 c3 01 add $0x1,%ebx8048e9f: 83 fb 05 cmp $0x5,%ebx8048ea2: 7e e9 jle 8048e8d phase_60x428048ea4: eb cc jmp 8048e72 phase_60x278048ea6: 8b 52 08 mov 0x8(%edx),%edx8048ea9: 83 c0 01 add $0x1,%eax8048eac: 39 c8 cmp %ecx,%eax8048eae: 75 f6 jne 8048ea6 phase_60x5b8048eb0: 89 54 b5 dc mov %edx,-0x24(%ebp,%esi,4)8048eb4: 83 c3 01 add $0x1,%ebx8048eb7: 83 fb 06 cmp $0x6,%ebx8048eba: 75 07 jne 8048ec3 phase_60x788048ebc: eb 1c jmp 8048eda phase_60x8f8048ebe: bb 00 00 00 00 mov $0x0,%ebx8048ec3: 89 de mov %ebx,%esi8048ec5: 8b 4 c 9d c4 mov -0x3c(%ebp,%ebx,4),%ecx8048ec9: b8 01 00 00 00 mov $0x1,%eax8048ece: ba 3c c1 04 08 mov $0x804c13c,%edx8048ed3: 83 f9 01 cmp $0x1,%ecx8048ed6: 7f ce jg 8048ea6 phase_60x5b8048ed8: eb d6 jmp 8048eb0 phase_60x658048eda: 8b 5d dc mov -0x24(%ebp),%ebx8048edd: 8d 45 dc lea -0x24(%ebp),%eax8048ee0: 8d 75 f0 lea -0x10(%ebp),%esi8048ee3: 89 d9 mov %ebx,%ecx8048ee5: 8b 50 04 mov 0x4(%eax),%edx8048ee8: 89 51 08 mov %edx,0x8(%ecx)8048eeb: 83 c0 04 add $0x4,%eax8048eee: 89 d1 mov %edx,%ecx8048ef0: 39 f0 cmp %esi,%eax8048ef2: 75 f1 jne 8048ee5 phase_60x9a8048ef4: c7 42 08 00 00 00 00 movl $0x0,0x8(%edx)8048efb: be 05 00 00 00 mov $0x5,%esi8048f00: 8b 43 08 mov 0x8(%ebx),%eax8048f03: 8b 00 mov (%eax),%eax8048f05: 39 03 cmp %eax,(%ebx)8048f07: 7d 05 jge 8048f0e phase_60xc38048f09: e8 77 02 00 00 call 8049185 explode_bomb8048f0e: 8b 5b 08 mov 0x8(%ebx),%ebx8048f11: 83 ee 01 sub $0x1,%esi8048f14: 75 ea jne 8048f00 phase_60xb58048f16: 8b 45 f4 mov -0xc(%ebp),%eax8048f19: 65 33 05 14 00 00 00 xor %gs:0x14,%eax8048f20: 74 05 je 8048f27 phase_60xdc8048f22: e8 69 f8 ff ff call 8048790 __stack_chk_failplt8048f27: 8d 65 f8 lea -0x8(%ebp),%esp8048f2a: 5b pop %ebx8048f2b: 5e pop %esi8048f2c: 5d pop %ebp8048f2d: c3 ret 先看 8048e5e: 8d 45 c4 lea -0x3c(%ebp),%eax8048e61: 50 push %eax8048e62: ff 75 08 push 0x8(%ebp)8048e65: e8 43 03 00 00 call 80491ad read_six_numbers通过开始的一段代码可知是输入六个数字并且首个元素存放地址为-0x3c(%ebp)假设输入的六个数字分别是a[0], a[1], a[2], a[3], a[4], a[5]。 之后有一个判断 8048e6a: 83 c4 10 add $0x10,%esp8048e6d: be 00 00 00 00 mov $0x0,%esi8048e72: 8b 44 b5 c4 mov -0x3c(%ebp,%esi,4),%eax8048e76: 83 e8 01 sub $0x1,%eax8048e79: 83 f8 05 cmp $0x5,%eax8048e7c: 76 05 jbe 8048e83 phase_60x388048e7e: e8 02 03 00 00 call 8049185 explode_bomb跳转条件是(a[0] - 1 5)这就限制了a[0] 6后面以输入1进行尝试。 8048e83: 83 c6 01 add $0x1,%esi8048e86: 83 fe 06 cmp $0x6,%esi8048e89: 74 33 je 8048ebe phase_60x738048e8b: 89 f3 mov %esi,%ebx8048e8d: 8b 44 9d c4 mov -0x3c(%ebp,%ebx,4),%eax8048e91: 39 44 b5 c0 cmp %eax,-0x40(%ebp,%esi,4)8048e95: 75 05 jne 8048e9c phase_60x518048e97: e8 e9 02 00 00 call 8049185 explode_bomb接下来esi 1与6进行比较可以猜想出这是一个循环esi是计数器循环六次。接下来又比较了a[0]和a[1]要求两个数不能相等。 8048e9c: 83 c3 01 add $0x1,%ebx8048e9f: 83 fb 05 cmp $0x5,%ebx8048ea2: 7e e9 jle 8048e8d phase_60x428048ea4: eb cc jmp 8048e72 phase_60x27然后ebx成了新计数器循环5次这里是把a[0]依次与a[1] ~ a[5]各比较一次保证不相等。可以发现其实这是两层循环先判断循环到的a[i]是否小于等于6然后判断它与后面几个数是否相等。 整个大循环结束后来到新部分 8048ea6: 8b 52 08 mov 0x8(%edx),%edx8048ea9: 83 c0 01 add $0x1,%eax8048eac: 39 c8 cmp %ecx,%eax8048eae: 75 f6 jne 8048ea6 phase_60x5b8048eb0: 89 54 b5 dc mov %edx,-0x24(%ebp,%esi,4)8048eb4: 83 c3 01 add $0x1,%ebx8048eb7: 83 fb 06 cmp $0x6,%ebx8048eba: 75 07 jne 8048ec3 phase_60x788048ebc: eb 1c jmp 8048eda phase_60x8f8048ebe: bb 00 00 00 00 mov $0x0,%ebx8048ec3: 89 de mov %ebx,%esi8048ec5: 8b 4 c 9d c4 mov -0x3c(%ebp,%ebx,4),%ecx8048ec9: b8 01 00 00 00 mov $0x1,%eax8048ece: ba 3c c1 04 08 mov $0x804c13c,%edx8048ed3: 83 f9 01 cmp $0x1,%ecx8048ed6: 7f ce jg 8048ea6 phase_60x5b8048ed8: eb d6 jmp 8048eb0 phase_60x65程序从8048ebe开始执行这里的计数器是ebx从0开始循环到6共循环7次。 第一次cmp跳转之前各个寄存器的值如图 比较的是ecx和1ecx是a[ebx]第一次是a[0]我输入的是1 2 3 4 5 6显然jg不会跳转程序来到了8048eb0。接下来把edx给到了-0x24(%ebp,%esi,4)地址处推测ebp-0x24地址处存放的是一个指针804c13c。 可以看一下这个地址处存放的内容 推测是链表进一步查看 链表一共有六个节点每个节点存放三个数据显然第三个数据是下一个节点的地址。第二个数据从1~6推测是链表的节点编号那第一个数据应该就是链表存放的有效数据。 mov 0x8(%edx), %edx 操作其实是把edx更新成下个节点的指针当eax与ecx相等时把节点指针压栈 否则会进入一个循环eax; edx继续指向下个指针直到eax ecx这也就意味着六个节点压栈的顺序与我们输入的六个数字相关如果输入的2 4 1 3 6 5则六个节点在栈中存放的顺序依次为node2 node4 node1 node3 node6 node5存放地址依次为%ebp-0x24、%ebp-0x20、%ebp-0x1c、%ebp-0x18、%ebp-0x14、%ebp-0x10。其实就是node[a[0]] ~ node[a[6]]。 继续看代码 8048eda: 8b 5d dc mov -0x24(%ebp),%ebx8048edd: 8d 45 dc lea -0x24(%ebp),%eax8048ee0: 8d 75 f0 lea -0x10(%ebp),%esi8048ee3: 89 d9 mov %ebx,%ecx8048ee5: 8b 50 04 mov 0x4(%eax),%edx8048ee8: 89 51 08 mov %edx,0x8(%ecx)8048eeb: 83 c0 04 add $0x4,%eax8048eee: 89 d1 mov %edx,%ecx8048ef0: 39 f0 cmp %esi,%eax8048ef2: 75 f1 jne 8048ee5 phase_60x9a这段代码也是循环会改变链表指向通过多次调试可以发现如果输入的是1 2 3 4 5 6则链表指向不变如果输入的是6 5 4 3 2 1则链表指向变为6543212最后有个环如果输入的是1 3 5 2 4 6则链表指向变为135246。 部分调试记录如下 以上发现了链表指向顺序会跟输入的六个数有关。 来到最后一段代码 8048ef4: c7 42 08 00 00 00 00 movl $0x0,0x8(%edx)8048efb: be 05 00 00 00 mov $0x5,%esi8048f00: 8b 43 08 mov 0x8(%ebx),%eax8048f03: 8b 00 mov (%eax),%eax8048f05: 39 03 cmp %eax,(%ebx)8048f07: 7d 05 jge 8048f0e phase_60xc38048f09: e8 77 02 00 00 call 8049185 explode_bomb8048f0e: 8b 5b 08 mov 0x8(%ebx),%ebx8048f11: 83 ee 01 sub $0x1,%esi8048f14: 75 ea jne 8048f00 phase_60xb5这段代码其实就是遍历链表遍历顺序就是刚刚重新排列好的顺序然后依次取相邻两个链表的值进行比较这一点可以调试到 8048f05 cmp %eax, (%ebx) 之前看一下eax的值和ebx指向的值如果前者大于后者就能通过然后继续遍历否则bomb 所以链表的正确排列顺序就有依据了先记录一下各个链表存放的数据都是多少 1-995 2-959 3-779 4-921 5-853 6-363 要求前者大于后者所以正确顺序也就是正确答案应该是1 2 4 5 3 6。 secret_phase 还有一个函数名叫secret_phase的代码如下 08048f80 secret_phase:8048f80: 55 push %ebp8048f81: 89 e5 mov %esp,%ebp8048f83: 53 push %ebx8048f84: 83 ec 04 sub $0x4,%esp8048f87: e8 5b 02 00 00 call 80491e7 read_line8048f8c: 83 ec 04 sub $0x4,%esp8048f8f: 6a 0a push $0xa8048f91: 6a 00 push $0x08048f93: 50 push %eax8048f94: e8 e7 f8 ff ff call 8048880 strtolplt8048f99: 89 c3 mov %eax,%ebx8048f9b: 8d 40 ff lea -0x1(%eax),%eax8048f9e: 83 c4 10 add $0x10,%esp8048fa1: 3d e8 03 00 00 cmp $0x3e8,%eax8048fa6: 76 05 jbe 8048fad secret_phase0x2d8048fa8: e8 d8 01 00 00 call 8049185 explode_bomb8048fad: 83 ec 08 sub $0x8,%esp8048fb0: 53 push %ebx8048fb1: 68 88 c0 04 08 push $0x804c0888048fb6: e8 73 ff ff ff call 8048f2e fun78048fbb: 83 c4 10 add $0x10,%esp8048fbe: 83 f8 03 cmp $0x3,%eax8048fc1: 74 05 je 8048fc8 secret_phase0x488048fc3: e8 bd 01 00 00 call 8049185 explode_bomb8048fc8: 83 ec 0c sub $0xc,%esp8048fcb: 68 1c a1 04 08 push $0x804a11c8048fd0: e8 eb f7 ff ff call 80487c0 putsplt8048fd5: e8 10 03 00 00 call 80492ea phase_defused8048fda: 83 c4 10 add $0x10,%esp8048fdd: 8b 5d fc mov -0x4(%ebp),%ebx8048fe0: c9 leave 8048fe1: c3 ret 在phase_defused中有调用所以贴一下phase_defused的代码 080492ea phase_defused:80492ea: 55 push %ebp80492eb: 89 e5 mov %esp,%ebp80492ed: 83 ec 68 sub $0x68,%esp80492f0: 65 a1 14 00 00 00 mov %gs:0x14,%eax80492f6: 89 45 f4 mov %eax,-0xc(%ebp)80492f9: 31 c0 xor %eax,%eax80492fb: 83 3d cc c3 04 08 06 cmpl $0x6,0x804c3cc8049302: 75 6f jne 8049373 phase_defused0x898049304: 83 ec 0c sub $0xc,%esp8049307: 8d 45 a4 lea -0x5c(%ebp),%eax804930a: 50 push %eax804930b: 8d 45 a0 lea -0x60(%ebp),%eax804930e: 50 push %eax804930f: 8d 45 9c lea -0x64(%ebp),%eax8049312: 50 push %eax8049313: 68 ed a2 04 08 push $0x804a2ed8049318: 68 d0 c4 04 08 push $0x804c4d0804931d: e8 ee f4 ff ff call 8048810 __isoc99_sscanfplt8049322: 83 c4 20 add $0x20,%esp8049325: 83 f8 03 cmp $0x3,%eax8049328: 75 39 jne 8049363 phase_defused0x79804932a: 83 ec 08 sub $0x8,%esp804932d: 68 f6 a2 04 08 push $0x804a2f68049332: 8d 45 a4 lea -0x5c(%ebp),%eax8049335: 50 push %eax8049336: e8 47 fd ff ff call 8049082 strings_not_equal804933b: 83 c4 10 add $0x10,%esp804933e: 85 c0 test %eax,%eax8049340: 75 21 jne 8049363 phase_defused0x798049342: 83 ec 0c sub $0xc,%esp8049345: 68 bc a1 04 08 push $0x804a1bc804934a: e8 71 f4 ff ff call 80487c0 putsplt804934f: c7 04 24 e4 a1 04 08 movl $0x804a1e4,(%esp)8049356: e8 65 f4 ff ff call 80487c0 putsplt804935b: e8 20 fc ff ff call 8048f80 secret_phase8049360: 83 c4 10 add $0x10,%esp8049363: 83 ec 0c sub $0xc,%esp8049366: 68 1c a2 04 08 push $0x804a21c804936b: e8 50 f4 ff ff call 80487c0 putsplt8049370: 83 c4 10 add $0x10,%esp8049373: 8b 45 f4 mov -0xc(%ebp),%eax8049376: 65 33 05 14 00 00 00 xor %gs:0x14,%eax804937d: 74 05 je 8049384 phase_defused0x9a804937f: e8 0c f4 ff ff call 8048790 __stack_chk_failplt8049384: c9 leave 8049385: c3 ret 在phase_defused的代码中发现了这句 804935b: e8 20 fc ff ff call 8048f80 secret_phase 这也就意味着每次拆除炸弹都有可能触发secret_phase继续对phase_defused的代码进行分析寻找触发条件着重关注最这行 8049312: 50 push %eax8049313: 68 ed a2 04 08 push $0x804a2ed8049318: 68 d0 c4 04 08 push $0x804c4d0804931d: e8 ee f4 ff ff call 8048810 __isoc99_sscanfplt8049322: 83 c4 20 add $0x20,%esp8049325: 83 f8 03 cmp $0x3,%eax8049328: 75 39 jne 8049363 phase_defused0x79调用sscanf之前先看一下输入格式 两个整数一个字符串这里会判断输入了几个如果输入的是两个数据并不会bomb而是正常结束输入两个的正好是phase_4猜测phase_4多输一个字符串会触发secret_phase下面继续分析这个字符串应该是什么 804932a: 83 ec 08 sub $0x8,%esp804932d: 68 f6 a2 04 08 push $0x804a2f68049332: 8d 45 a4 lea -0x5c(%ebp),%eax8049335: 50 push %eax8049336: e8 47 fd ff ff call 8049082 strings_not_equal804933b: 83 c4 10 add $0x10,%esp804933e: 85 c0 test %eax,%eax8049340: 75 21 jne 8049363 phase_defused0x79看到一个关键地址0x804a2f6查看内容 这就找到了我们要多输入的字符串DrEvil。 输入进去之后程序最后输出了小彩蛋印证了它就是目标字符串; 回过头来对secret_phase进行分析 8048f8f: 6a 0a push $0xa8048f91: 6a 00 push $0x08048f93: 50 push %eax8048f94: e8 e7 f8 ff ff call 8048880 strtolplt8048f99: 89 c3 mov %eax,%ebx8048f9b: 8d 40 ff lea -0x1(%eax),%eax8048f9e: 83 c4 10 add $0x10,%esp8048fa1: 3d e8 03 00 00 cmp $0x3e8,%eax8048fa6: 76 05 jbe 8048fad secret_phase0x2d8048fa8: e8 d8 01 00 00 call 8049185 explode_bomb开始会调用一个strtol函数将字符串转成long这里要转的字符串的首地址是eax也就是上一次调用的函数的返回值上一个函数是read_line所以也就是把我们的输入转成long-1后与0x3e8(1000)进行比较要求小于等于1000也就意味着我们要输入一个数字并且这个数字要小于等于1001。 继续向下看; 8048fb0: 53 push %ebx8048fb1: 68 88 c0 04 08 push $0x804c0888048fb6: e8 73 ff ff ff call 8048f2e fun78048fbb: 83 c4 10 add $0x10,%esp8048fbe: 83 f8 03 cmp $0x3,%eax8048fc1: 74 05 je 8048fc8 secret_phase0x488048fc3: e8 bd 01 00 00 call 8049185 explode_bomb8048fbb: 83 c4 10 add $0x10,%esp8048fbe: 83 f8 03 cmp $0x3,%eax8048fc1: 74 05 je 8048fc8 secret_phase0x488048fc3: e8 bd 01 00 00 call 8049185 explode_bomb看最后三句可以看出当调用完fun7后eax3时才不会爆炸secret_phase也就会结束所以关键看eax在fun7中的变化。 调用fun7之前传递的参数为ebx和0x804c088ebx根据之前的代码可知是我们输入的整数看一下0x804c088存的是什么64是显示64个单位u是以十进制格式输出换成x就是以十六进制格式输出w是以8个字节为单位我一开始是用默认的4个字节为单位结果什么也看不出来耽误了好久 数据有nxx后面还有nodex其实就是phase_6中的链表节点结构。不难看出nxx也有着异曲同工之妙。再看一眼能看出nxx是以三个单位为一组第一个存放的是一个较小的数猜测为有效数据后两个显然是指针并且前七个节点中的两个指针都有指向猜测为二叉树结构一共15个节点8个叶子结点根据各个节点之间的连接关系和对应地址处的标识可以推断出这棵树的形状如下 整理出来发现这是一颗平衡搜索二叉树左节点都比父节点小右节点都比父节点大。 那么fun7的参数就有了第一个参数是这颗二叉树根节点的地址第二个参数是我们输入的数接下来可以继续分析fun7先打出完整代码然后顺着翻译一下 08048f2e fun7:8048f2e: 55 push %ebp8048f2f: 89 e5 mov %esp,%ebp8048f31: 53 push %ebx8048f32: 83 ec 04 sub $0x4,%esp8048f35: 8b 55 08 mov 0x8(%ebp),%edx8048f38: 8b 4d 0c mov 0xc(%ebp),%ecx8048f3b: 85 d2 test %edx,%edx8048f3d: 74 37 je 8048f76 fun70x488048f3f: 8b 1a mov (%edx),%ebx8048f41: 39 cb cmp %ecx,%ebx8048f43: 7e 13 jle 8048f58 fun70x2a8048f45: 83 ec 08 sub $0x8,%esp8048f48: 51 push %ecx8048f49: ff 72 04 push 0x4(%edx)8048f4c: e8 dd ff ff ff call 8048f2e fun78048f51: 83 c4 10 add $0x10,%esp8048f54: 01 c0 add %eax,%eax8048f56: eb 23 jmp 8048f7b fun70x4d8048f58: b8 00 00 00 00 mov $0x0,%eax8048f5d: 39 cb cmp %ecx,%ebx8048f5f: 74 1a je 8048f7b fun70x4d8048f61: 83 ec 08 sub $0x8,%esp8048f64: 51 push %ecx8048f65: ff 72 08 push 0x8(%edx)8048f68: e8 c1 ff ff ff call 8048f2e fun78048f6d: 83 c4 10 add $0x10,%esp8048f70: 8d 44 00 01 lea 0x1(%eax,%eax,1),%eax8048f74: eb 05 jmp 8048f7b fun70x4d8048f76: b8 ff ff ff ff mov $0xffffffff,%eax8048f7b: 8b 5d fc mov -0x4(%ebp),%ebx8048f7e: c9 leave 8048f7f: c3 ret 顺着思路翻译一下还是很简单的 fun7 (node* root, int num) {if (root null) {eax 0xffffffff;return}if (root-val num) {eax 0; # ①if (root-val num)return;fun7(root-right, num);eax eax * 2 1; # ②return;}fun7(root-left, num);eax * 2; # ③return; }本来是想一步步分析汇编的但递归实在太绕了 还是顺着把汇编翻译一下比较简单。 最终目标是让eax变为3。这里有关eax的有效操作有①eax 0②eax eax * 2 1③eax * 2。 所以一个可行的顺序是①②②,对应的在递归第一层要执行②第二层要执行②第三层执行①。 来到第一层此时root-val 36第一层要走到②之前那一句进入二层调用这就要求num 36。 来到第二层此时root-val 50仍需要走到②之前那一句进入三层调用这就要求num 50。 来到第三层此时root-val 107这次需要走到①处然后返回要求num 107。 这样就推理出了最终答案107 测试一下完全通过
http://www.zqtcl.cn/news/789693/

相关文章:

  • 网站主关键词湖南网站定制
  • 长沙seo网站排名优化公司进入秦皇岛最新规定
  • 企业网站优化平台宝山北京网站建设
  • 给人做代工的网站加盟代理网
  • 网站建设用dw电脑谷歌浏览器打开是2345网址导航
  • 做外贸一般总浏览的网站太原的网站建设公司哪家好
  • 台州建网站公司wordpress 用微信登陆
  • 广州白云网站建设家在深圳业主
  • 呼和浩特网站建设哪家最便宜?携程旅行网网站策划书
  • 网站建设及相关流程北京网站备案域名
  • 汉字叔叔花了多少钱做网站微商城科技
  • 网站代理被抓html网站开发实战
  • 如何建立免费的网站网站copyright写法
  • 官方网站下载12306合肥有没有做网站的单位
  • 甘露园网站建设网站框架图片
  • 做网站怎样赚卖流量石家庄网站建设联系电话
  • wordpress 图片网站本地免费发布信息网站
  • 建设网站和别人公司重名新乡建设招标投标网站
  • 四川省建设厅网站证想开个网站怎样开公司
  • 做机械一般做那个外贸网站电商软件开发费用
  • 网站外链坏处龙岗网站设计信息
  • 郑州网站建设乙汉狮网络搜索优化网络推广
  • Dw做html网站百度推广竞价排名
  • 北京市电力建设公司网站万云网络网站
  • 校园网站开发方案做网站现在用什么语言
  • 网站建设学什么书中联建设集团股份有限公司网站
  • 制作个人业务网站go 做视频网站
  • 域名对网站建设有什么影响吗找人做仿网站
  • 网站建设翻译谁提供爱心代码html简单
  • 上海专业网站建站公司asp.net商务网站 包括哪些文件