实验一-Bomblab(炸弹实验)

  实验概述:该实验就是通过分析汇编代码,并使用GDB调试,找到每一题的通关钥匙                   

第一关:(key=“He is evil and fits easily into most overhead storage bins.”)

简单解析:比较简单,字符串比较问题,找到比较地址中存储的字符串即可。

(1)分析:   

 

(2)运行:

第二关:(key=1 2 4 8 16 32)

简单解析:循环输入六个值问题,按循环条件观察变化即可。

(1)分析:

(2)运行:

第三关:(key=0,276)

简单解析:switch跳转问题,按部就班,比较简单。

(1)分析:

08048c02 <phase_3>:

 8048c02: 83 ec 2c              sub    $0x2c,%esp//开辟栈帧

 8048c05: 8d 44 24 1c           lea    0x1c(%esp),%eax

 8048c09: 89 44 24 0c           mov    %eax,0xc(%esp)

 8048c0d: 8d 44 24 18           lea    0x18(%esp),%eax

 8048c11: 89 44 24 08           mov    %eax,0x8(%esp)

 8048c15: c7 44 24 04 17 a3 04      movl   $0x804a317,0x4(%esp)//查看该地址中的内容

                            说明应该输入两个数字

 8048c1c: 08

 8048c1d: 8b 44 24 30           mov    0x30(%esp),%eax

 8048c21: 89 04 24              mov    %eax,(%esp)

 8048c24: e8 37 fc ff ff             call   8048860 <__isoc99_sscanf@plt>//调用函数

 8048c29: 83 f8 01              cmp    $0x1,%eax //

 8048c2c: 7f 05                    jg   8048c33 <phase_3+0x31>//输入参数个数大于1个

  8048c2e:e8 22 05 00 00            call   8049155 <explode_bomb>

 8048c33: 83 7c 24 18 07        cmpl   $0x7,0x18(%esp)//第一个参数值<=7,否则跳转到炸弹处(可以输入0 1 2 3 4 5 6 7)

 8048c38: 77 66                   ja     8048ca0 <phase_3+0x9e>//无符号数比较

 8048c3a: 8b 44 24 18           mov    0x18(%esp),%eax

 8048c3e: ff 24 85 d8 a1 04 08     jmp    *0x804a1d8(,%eax,4)//跳转到以*0x804a1d8为基址的跳转表中,如果此时第一个输入数为0,由此看出跳转到0x8048c4c地址

 8048c45: b8 00 00 00 00           mov    $0x0,%eax

 8048c4a: eb 05                  jmp    8048c51 <phase_3+0x4f>

 8048c4c: b8 33 03 00 00           mov    $0x333,%eax//第一个输入数为0就跳转到了这里

 8048c51: 2d ea 00 00 00        sub    $0xea,%eax  //eax=0x333-0xea继续跳转

 8048c56: eb 05                  jmp    8048c5d <phase_3+0x5b>

 8048c58: b8 00 00 00 00        mov    $0x0,%eax

 8048c5d: 05 0f 02 00 00          add    $0x20f,%eax  //eax=0x333-0xea+0x20f

 8048c62: eb 05                 jmp    8048c69 <phase_3+0x67>

 8048c64: b8 00 00 00 00        mov    $0x0,%eax

 8048c69: 2d 44 03 00 00        sub    $0x344,%eax  //eax=0x333-0xea+0x20f-0x344

 8048c6e: eb 05                 jmp    8048c75 <phase_3+0x73>

 8048c70: b8 00 00 00 00        mov    $0x0,%eax

 8048c75: 05 44 03 00 00        add    $0x344,%eax  //eax=0x333-0xea+0x20f-0x344+0x344

 8048c7a: eb 05                 jmp    8048c81 <phase_3+0x7f>

 8048c7c: b8 00 00 00 00        mov    $0x0,%eax

 8048c81: 2d 44 03 00 00        sub    $0x344,%eax  //eax=0x333-0xea+0x20f-0x344+0x344-0x344

 8048c86: eb 05                 jmp    8048c8d <phase_3+0x8b>

 8048c88: b8 00 00 00 00        mov    $0x0,%eax

 8048c8d: 05 44 03 00 00        add $0x344,%eax  //eax=0x333-0xea+0x20f-0x344+0x344-0x344+0x344

 8048c92: eb 05                 jmp    8048c99 <phase_3+0x97>

 8048c94: b8 00 00 00 00        mov    $0x0,%eax

 8048c99: 2d 44 03 00 00        sub $0x344,%eax //eax=0x333-0xea+0x20f-0x344+0x344-0x344+0x344-0x344

 8048c9e: eb 0a                 jmp    8048caa <phase_3+0xa8>

 8048ca0: e8 b0 04 00 00        call   8049155 <explode_bomb>

 8048ca5: b8 00 00 00 00        mov    $0x0,%eax

 8048caa: 83 7c 24 18 05        cmpl   $0x5,0x18(%esp)  //说明第一个输入数小于等于5

 8048caf: 7f 06                 jg     8048cb7 <phase_3+0xb5>

 8048cb1: 3b 44 24 1c           cmp    0x1c(%esp),%eax //第二个输入数就是输入第一个数后 跳转完毕的结果

 8048cb5: 74 05                 je     8048cbc <phase_3+0xba>

 8048cb7: e8 99 04 00 00        call   8049155 <explode_bomb>

 8048cbc: 83 c4 2c              add    $0x2c,%esp

 8048cbf: 90                    nop

 8048cc0: c3                    ret    

(2)运行:

(3)总结:

综上可知,第一个数的输入限制为:小于等于5,又因为经过排查,当第一个

 数为0,3,才可以找到在跳转表中的地址。又因为当第一个数为3时,最终结果

为-309,不符合开头时要求无符号数的要求,所以Password为:(0,276)。

跳转示意:

第四关:(key=0,11或1,11)

简单解析:递归和二分问题,注意递归和二分条件和递归的返回值,还要注意递归的结束条件。

08048d1e <phase_4>:

 8048d1e: 83 ec 2c              sub    $0x2c,%esp

 8048d21: 8d 44 24 1c           lea    0x1c(%esp),%eax

 8048d25: 89 44 24 0c           mov    %eax,0xc(%esp)

 8048d29: 8d 44 24 18           lea    0x18(%esp),%eax

 8048d2d: 89 44 24 08           mov    %eax,0x8(%esp)

 8048d31: c7 44 24 04 17 a3 04    movl $0x804a317,0x4(%esp)   //要求输入两个数

                              

 8048d38: 08

 8048d39: 8b 44 24 30           mov    0x30(%esp),%eax

 8048d3d: 89 04 24              mov    %eax,(%esp)

 8048d40: e8 1b fb ff ff             call   8048860 <__isoc99_sscanf@plt>//调用函数

 8048d45: 83 f8 02              cmp    $0x2,%eax   //说明输入个数为2,否则会爆炸

 8048d48: 75 07                 jne    8048d51 <phase_4+0x33>

 8048d4a: 83 7c 24 18 0e        cmpl   $0xe,0x18(%esp)

 8048d4f: 76 05                 jbe    8048d56 <phase_4+0x38>//小于等于就跳转,否则爆炸,说明

第一个输入数<=14

 8048d51: e8 ff 03 00 00         call   8049155 <explode_bomb>

 8048d56: c7 44 24 08 0e 00 00      movl   $0xe,0x8(%esp)

 8048d5d: 00

 8048d5e: c7 44 24 04 00 00 00     movl   $0x0,0x4(%esp)

 8048d65: 00

 8048d66: 8b 44 24 18           mov    0x18(%esp),%eax

 8048d6a: 89 04 24              mov    %eax,(%esp)//  将第一个输入数作为参数传入并调用func4

 8048d6d: e8 4f ff ff ff            call     8048cc1 <func4>//  此时将目光转到func4

 8048d72: 83 f8 0b              cmp   $0xb,%eax //  func4()应该返回值为11,根据func(x)=11,推出x

即可

 8048d75: 75 07                 jne    8048d7e <phase_4+0x60>

 8048d77: 83 7c 24 1c 0b         cmpl   $0xb,0x1c(%esp)  //第二个输入数一定为11

 8048d7c: 74 05                 je     8048d83 <phase_4+0x65>

 8048d7e: e8 d2 03 00 00        call   8049155 <explode_bomb>

 8048d83: 83 c4 2c              add    $0x2c,%esp

 8048d86: c3                    ret    

//接下来查看func4函数的功能

08048cc1 <func4>:

 8048cc1: 56                    push   %esi

 8048cc2: 53                    push   %ebx

 8048cc3: 83 ec 14              sub    $0x14,%esp

 8048cc6: 8b 54 24 20           mov    0x20(%esp),%edx //传入参数

 8048cca: 8b 44 24 24           mov    0x24(%esp),%eax //e

 8048cce: 8b 74 24 28           mov    0x28(%esp),%esi //0

 8048cd2: 89 f1                 mov    %esi,%ecx

 8048cd4: 29 c1                 sub    %eax,%ecx

 8048cd6: 89 cb                 mov    %ecx,%ebx

 8048cd8: c1 eb 1f              shr    $0x1f,%ebx  //逻辑右移31位

 8048cdb: 01 d9                 add    %ebx,%ecx

 8048cdd: d1 f9                 sar    %ecx//对于二分的右边界值,算数右移一位,就是除以2

 8048cdf: 8d 1c 01              lea    (%ecx,%eax,1),%ebx

 8048ce2: 39 d3                 cmp    %edx,%ebx//比较右边界值和参数的大小

 8048ce4: 7e 17                 jle    8048cfd <func4+0x3c>

 8048ce6: 8d 4b ff              lea    -0x1(%ebx),%ecx //大于参数时就对该边界值-1,继续进行递归二分

 8048ce9: 89 4c 24 08           mov    %ecx,0x8(%esp)

 8048ced: 89 44 24 04           mov    %eax,0x4(%esp)

 8048cf1: 89 14 24              mov    %edx,(%esp)

 8048cf4: e8 c8 ff ff ff             call   8048cc1 <func4>

 8048cf9: 01 d8                 add    %ebx,%eax//将之前二分的值累加到eax作为返回结果

 8048cfb: eb 1b                 jmp    8048d18 <func4+0x57>

 8048cfd: 89 d8                 mov    %ebx,%eax

 8048cff: 39 d3                 cmp    %edx,%ebx

 8048d01: 7d 15                 jge    8048d18 <func4+0x57>

 8048d03: 89 74 24 08           mov    %esi,0x8(%esp)

 8048d07: 8d 43 01              lea    0x1(%ebx),%eax//等于传入参数就退出递归返回值

                                              大于参数时就对该边界值+1,继续进行递归二分

 8048d0a: 89 44 24 04           mov    %eax,0x4(%esp)

 8048d0e: 89 14 24              mov    %edx,(%esp)

 8048d11: e8 ab ff ff ff           call   8048cc1 <func4>

 8048d16: 01 d8                 add    %ebx,%eax

 8048d18: 83 c4 14              add    $0x14,%esp

 8048d1b: 5b                    pop    %ebx

 8048d1c: 5e                    pop    %esi

 8048d1d: c3                    ret    

综上:func4()的功能就是递归二分,并将每次二分中间值保留累加,作为返回值,直到二分中间值=传入参数示意:

(2)运行结果:

第五关:(key=mfcdhg)

简单解析:利用输入字符ASCII码低四位作为偏置,去某个地址查找对应字符,以便组成所需字符串,注意小端法存储问题。

  1. 分析:

08048d87 <phase_5>:

 8048d87: 53                    push   %ebx

 8048d88: 83 ec 28              sub    $0x28,%esp

 8048d8b: 8b 5c 24 30           mov    0x30(%esp),%ebx

 8048d8f: 65 a1 14 00 00 00       mov    %gs:0x14,%eax

 8048d95: 89 44 24 1c           mov    %eax,0x1c(%esp)

 8048d99: 31 c0                 xor    %eax,%eax//清零

 8048d9b: 89 1c 24              mov    %ebx,(%esp)

 8048d9e: e8 88 02 00 00        call   804902b <string_length>

 8048da3: 83 f8 06              cmp    $0x6,%eax //   要求输入一个长度为6的字符串

 8048da6: 74 4a                 je     8048df2 <phase_5+0x6b>//满足条件就跳转

 8048da8: e8 a8 03 00 00        call   8049155 <explode_bomb>

 8048dad: 8d 76 00              lea    0x0(%esi),%esi

 8048db0: eb 40                 jmp    8048df2 <phase_5+0x6b>

 8048db2: 0f b6 14 03           movzbl (%ebx,%eax,1),%edx  //从这儿开始一个小循环

 8048db6: 83 e2 0f              and    $0xf,%edx

 8048db9: 0f b6 92 f8 a1 04 08     movzbl  0x804a1f8(%edx),%edx

//保存输入字符的低八位,并将低四位作为偏置,查找基址0x804a1f8中保存的对应字符,组合拼装成目的字符串“bruins”即可。

由此看出,其中存的字符为:maduiersnfotvbyl

 对应偏置为:0 1 2 3 4 5 6 7 8 9 a b c d e f

 8048dc0: 88 54 04 15           mov    %dl,0x15(%esp,%eax,1)

 8048dc4: 83 c0 01              add    $0x1,%eax   //加1

 8048dc7: 83 f8 06             cmp    $0x6,%eax//意思是处理完六个字符,保存完毕偏置就退出循环

 8048dca: 75 e6                 jne    8048db2 <phase_5+0x2b>

 8048dcc: c6 44 24 1b 00        movb   $0x0,0x1b(%esp)

 8048dd1: c7 44 24 04 ce a1 04      movl   $0x804a1ce,0x4(%esp)//查看内容

                                      

所以目的字符串为:bruins

因此可知:需要的偏置为:d 6 3 4 8 7,又因为我们要输入长度为6的字符串,且取该字符串中的低四位为偏置,因此根据下表可以得知,输入应该为:m、f、c、d、h、g(其中一种情况)

 8048dd8: 08

 8048dd9: 8d 44 24 15           lea    0x15(%esp),%eax

 8048ddd: 89 04 24              mov    %eax,(%esp)

 8048de0: e8 65 02 00 00        call   804904a <strings_not_equal>

 8048de5: 85 c0                 test   %eax,%eax  //

 8048de7: 74 10                 je     8048df9 <phase_5+0x72>

 8048de9: e8 67 03 00 00        call   8049155 <explode_bomb>

 8048dee: 66 90                 xchg   %ax,%ax

 8048df0: eb 07                 jmp    8048df9 <phase_5+0x72>

 8048df2: b8 00 00 00 00        mov    $0x0,%eax //跳转到这儿并赋初值0给eax

 8048df7: eb b9                 jmp    8048db2 <phase_5+0x2b>//再跳转回去

 8048df9: 8b 44 24 1c           mov    0x1c(%esp),%eax

 8048dfd: 65 33 05 14 00 00 00     xor    %gs:0x14,%eax

 8048e04: 74 05                 je     8048e0b <phase_5+0x84>

 8048e06: e8 b5 f9 ff ff             call   80487c0 <__stack_chk_fail@plt>

 8048e0b: 83 c4 28              add    $0x28,%esp

 8048e0e: 5b                    pop    %ebx

 8048e0f: 90                    nop

 8048e10: c3                    ret   

 2.运行结果:

第六关(链表):

简单解析:有六个节点,每个节点中存储一个值,把结点1-6按顺序输入,保证其中结点的值按要求顺序排列即可。

(1)分析:

08048e11 <phase_6>:

 8048e11: 56                    push   %esi

 8048e12: 53                    push   %ebx

 8048e13: 83 ec 44              sub    $0x44,%esp

 8048e16: 8d 44 24 10           lea    0x10(%esp),%eax

 8048e1a: 89 44 24 04           mov    %eax,0x4(%esp)

 8048e1e: 8b 44 24 50           mov    0x50(%esp),%eax

 8048e22: 89 04 24              mov    %eax,(%esp)

 8048e25: e8 52 03 00 00        call   804917c <read_six_numbers>//输入6个数字

 8048e2a: be 00 00 00 00        mov    $0x0,%esi

 8048e2f: 8b 44 b4 10           mov    0x10(%esp,%esi,4),%eax

 8048e33: 83 e8 01              sub    $0x1,%eax

 8048e36: 83 f8 05              cmp    $0x5,%eax

 8048e39: 76 05               jbe    8048e40 <phase_6+0x2f>//输入数字为无符号数

且<=6.可知输入数字必然为1-6,顺序未知

 8048e3b: e8 15 03 00 00        call   8049155 <explode_bomb>

 8048e40: 83 c6 01              add    $0x1,%esi

 8048e43: 83 fe 06              cmp    $0x6,%esi

 8048e46: 75 07                jne    8048e4f <phase_6+0x3e>

 8048e48: bb 00 00 00 00        mov    $0x0,%ebx

 8048e4d: eb 38                jmp    8048e87 <phase_6+0x76>

 8048e4f: 89 f3                mov    %esi,%ebx

 8048e51: 8b 44 9c 10           mov    0x10(%esp,%ebx,4),%eax

 8048e55: 39 44 b4 0c           cmp    %eax,0xc(%esp,%esi,4)

 8048e59: 75 05                jne    8048e60 <phase_6+0x4f>

 8048e5b: e8 f5 02 00 00        call   8049155 <explode_bomb>

 8048e60: 83 c3 01              add    $0x1,%ebx

 8048e63: 83 fb 05              cmp    $0x5,%ebx

 8048e66: 7e e9                jle    8048e51 <phase_6+0x40>

 8048e68: eb c5                jmp    8048e2f <phase_6+0x1e>

//到这儿,其实以上操作用了双层for说明不能有重复数字出现,因此可知输入数字一定为1,2,3,4,5,6,顺序未知,因此接下来讨论顺序问题

 8048e6a: 8b 52 08             mov    0x8(%edx),%edx

 8048e6d: 83 c0 01              add    $0x1,%eax

 8048e70: 39 c8                cmp    %ecx,%eax

 8048e72: 75 f6                jne    8048e6a <phase_6+0x59>

 8048e74: eb 05                jmp    8048e7b <phase_6+0x6a>

 8048e76: ba 3c c1 04 08        mov    $0x804c13c,%edx

 8048e7b: 89 54 b4 28           mov    %edx,0x28(%esp,%esi,4)

 8048e7f: 83 c3 01              add    $0x1,%ebx

 8048e82: 83 fb 06              cmp    $0x6,%ebx

 8048e85: 74 17                je     8048e9e <phase_6+0x8d>

 8048e87: 89 de                mov    %ebx,%esi

 8048e89: 8b 4c 9c 10           mov    0x10(%esp,%ebx,4),%ecx

 8048e8d: 83 f9 01              cmp    $0x1,%ecx

 8048e90: 7e e4                jle    8048e76 <phase_6+0x65>

 8048e92: b8 01 00 00 00        mov    $0x1,%eax

 8048e97: ba 3c c1 04 08        mov    $0x804c13c,%edx //以0x804c13c为基址进行

后续操作                         

 8048e9c: eb cc                jmp    8048e6a <phase_6+0x59>

 8048e9e: 8b 5c 24 28           mov    0x28(%esp),%ebx

 8048ea2: 8d 44 24 2c           lea    0x2c(%esp),%eax

 8048ea6: 8d 74 24 40           lea    0x40(%esp),%esi

 8048eaa: 89 d9                mov    %ebx,%ecx

 8048eac: 8b 10                mov    (%eax),%edx

 8048eae: 89 51 08              mov    %edx,0x8(%ecx)

 8048eb1: 83 c0 04              add    $0x4,%eax

 8048eb4: 39 f0                cmp    %esi,%eax

 8048eb6: 74 04                je     8048ebc <phase_6+0xab>

 8048eb8: 89 d1                mov    %edx,%ecx

 8048eba: eb f0                jmp    8048eac <phase_6+0x9b>

 8048ebc: c7 42 08 00 00 00 00 movl   $0x0,0x8(%edx)

 8048ec3: be 05 00 00 00        mov    $0x5,%esi

 8048ec8: 8b 43 08             mov    0x8(%ebx),%eax//

 8048ecb: 8b 00                mov    (%eax),%eax

 8048ecd: 39 03                cmp    %eax,(%ebx)

 8048ecf: 7d 05                jge    8048ed6 <phase_6+0xc5>//说明后一个数得<=

前一个数,就是说,根据我们输入的序列,对应的偏移地址中存储的值应该从大到小排列

 8048ed1: e8 7f 02 00 00        call   8049155 <explode_bomb>

 8048ed6: 8b 5b 08             mov    0x8(%ebx),%ebx

 8048ed9: 83 ee 01              sub    $0x1,%esi

 8048edc: 75 ea                jne    8048ec8 <phase_6+0xb7>//全部判断完毕就退出

 8048ede: 83 c4 44              add    $0x44,%esp

 8048ee1: 5b                   pop    %ebx

 8048ee2: 5e                   pop    %esi

 8048ee3: c3                   ret    

总结:

 (2)运行示意:

隐藏关(树):

(1)寻找入口:

080492c6 <phase_defused>:

 80492c6: 81 ec 8c 00 00 00     sub    $0x8c,%esp

 80492cc: 65 a1 14 00 00 00     mov    %gs:0x14,%eax

 80492d2: 89 44 24 7c           mov    %eax,0x7c(%esp)

 80492d6: 31 c0                xor    %eax,%eax

 80492d8: 83 3d c8 c3 04 08 06 cmpl   $0x6,0x804c3c8//如果前六关过了,就进入,否

则直接结束

 80492df: 75 72                jne    8049353 <phase_defused+0x8d>

 80492e1: 8d 44 24 2c           lea    0x2c(%esp),%eax

 80492e5: 89 44 24 10           mov    %eax,0x10(%esp)

 80492e9: 8d 44 24 28           lea    0x28(%esp),%eax

 80492ed: 89 44 24 0c           mov    %eax,0xc(%esp)

 80492f1: 8d 44 24 24           lea    0x24(%esp),%eax

 80492f5: 89 44 24 08           mov    %eax,0x8(%esp)

 80492f9: c7 44 24 04 71 a3 04 movl   $0x804a371,0x4(%esp)//查询该地址:

说明此时输入两个数字,一个字符串,继续向下看

 8049300: 08

 8049301: c7 04 24 d0 c4 04 08 movl   $0x804c4d0,(%esp)

 8049308: e8 53 f5 ff ff        call   8048860 <__isoc99_sscanf@plt>//发现第四关中,

同样调用了该函数,因此可知,第四关中输入两个数字后,还得输入一个字符串

 804930d: 83 f8 03              cmp    $0x3,%eax

 8049310: 75 35                jne    8049347 <phase_defused+0x81>

 8049312: c7 44 24 04 7a a3 04 movl   $0x804a37a,0x4(%esp)

//查看该地址中的内容:,找到入场券:“DrEvil”

 8049319: 08

 804931a: 8d 44 24 2c           lea    0x2c(%esp),%eax

 804931e: 89 04 24              mov    %eax,(%esp)

 8049321: e8 24 fd ff ff        call   804904a <strings_not_equal>

 8049326: 85 c0                est   %eax,%eax

 8049328: 75 1d                jne    8049347 <phase_defused+0x81>

 804932a: c7 04 24 40 a2 04 08 movl   $0x804a240,(%esp)

 8049331: e8 ba f4 ff ff        call   80487f0 <puts@plt>

 8049336: c7 04 24 68 a2 04 08 movl   $0x804a268,(%esp)

 804933d: e8 ae f4 ff ff        call   80487f0 <puts@plt>

 8049342: e8 ee fb ff ff        call   8048f35 <secret_phase>//这里显示进入秘密关卡

 8049347: c7 04 24 a0 a2 04 08 movl   $0x804a2a0,(%esp)

 804934e: e8 9d f4 ff ff        call   80487f0 <puts@plt>

 8049353: 8b 44 24 7c           mov    0x7c(%esp),%eax

 8049357: 65 33 05 14 00 00 00 xor    %gs:0x14,%eax

 804935e: 74 05                 je     8049365 <phase_defused+0x9f>

 8049360: e8 5b f4 ff ff        call   80487c0 <__stack_chk_fail@plt>

 8049365: 81 c4 8c 00 00 00     add    $0x8c,%esp

 804936b: c3                    ret    

 804936c: 66 90                 xchg   %ax,%ax

 804936e: 66 90                 xchg   %ax,%ax

成功进入秘密关卡:(入场券“DrEvil”)

(2)解秘密关:

08048f35 <secret_phase>:

 8048f35: 53                   push   %ebx

 8048f36: 83 ec 18              sub    $0x18,%esp

 8048f39: e8 8e 02 00 00        call   80491cc <read_line>//读入一行

 8048f3e: c7 44 24 08 0a 00 00 movl   $0xa,0x8(%esp)

 8048f45: 00

 8048f46: c7 44 24 04 00 00 00 movl   $0x0,0x4(%esp)

 8048f4d: 00

 8048f4e: 89 04 24              mov    %eax,(%esp)//返回值作为参数之一

 8048f51: e8 7a f9 ff ff        call   80488d0 <strtol@plt>

 8048f56: 89 c3                mov    %eax,%ebx

 8048f58: 8d 40 ff              lea    -0x1(%eax),%eax

 8048f5b: 3d e8 03 00 00        cmp    $0x3e8,%eax//0x3e8=1000

 8048f60: 76 05                jbe    8048f67 <secret_phase+0x32>//以上语句说明输入一个十进制数且<=1000

 8048f62: e8 ee 01 00 00        call   8049155 <explode_bomb>

 8048f67: 89 5c 24 04           mov    %ebx,0x4(%esp)

 8048f6b: c7 04 24 88 c0 04 08 movl   $0x804c088,(%esp)//将输入数传入作为参数之一,另外一个为   0x24=36

 8048f72: e8 6d ff ff ff        call   8048ee4 <fun7>//将目光转到fun7

 8048f77: 83 f8 02              cmp    $0x2,%eax//函数返回值应该是2

 8048f7a: 74 05                je     8048f81 <secret_phase+0x4c>

 8048f7c: e8 d4 01 00 00        call   8049155 <explode_bomb>

 8048f81: c7 04 24 a8 a1 04 08 movl   $0x804a1a8,(%esp)

 8048f88: e8 63 f8 ff ff        call   80487f0 <puts@plt>

 8048f8d: e8 34 03 00 00        call   80492c6 <phase_defused>

 8048f92: 83 c4 18              add    $0x18,%esp

 8048f95: 5b                    pop    %ebx

 8048f96: c3                    ret    

 8048f97: 66 90                 xchg   %ax,%ax

 8048f99: 66 90                 xchg   %ax,%ax

 8048f9b: 66 90                 xchg   %ax,%ax

 8048f9d: 66 90                 xchg   %ax,%ax

 8048f9f: 90                    nop

//分析fun7

08048ee4 <fun7>:

 8048ee4: 53                   push   %ebx

 8048ee5: 83 ec 18              sub    $0x18,%esp

 8048ee8: 8b 54 24 20           mov    0x20(%esp),%edx

 8048eec: 8b 4c 24 24           mov    0x24(%esp),%ecx

 8048ef0: 85 d2                test   %edx,%edx//这里说明递归最深处返回值为0时,就退出递归并返回值

 8048ef2: 74 37                je     8048f2b <fun7+0x47>

 8048ef4: 8b 1a                mov    (%edx),%ebx

 8048ef6: 39 cb                cmp    %ecx,%ebx

 8048ef8: 7e 13                jle    8048f0d <fun7+0x29>

 8048efa: 89 4c 24 04           mov    %ecx,0x4(%esp)

 8048efe: 8b 42 04             mov    0x4(%edx),%eax

 8048f01: 89 04 24              mov    %eax,(%esp)

 8048f04: e8 db ff ff ff        call   8048ee4 <fun7>//如果*x>36,以(x+4)作为地址进入下一层递归

 8048f09: 01 c0                add    %eax,%eax  //返回值*=2

 8048f0b: eb 23                jmp    8048f30 <fun7+0x4c>

 8048f0d: b8 00 00 00 00        mov    $0x0,%eax

 8048f12: 39 cb                cmp    %ecx,%ebx

 8048f14: 74 1a                je     8048f30 <fun7+0x4c>

 8048f16: 89 4c 24 04           mov    %ecx,0x4(%esp)

 8048f1a: 8b 42 08             mov    0x8(%edx),%eax

 8048f1d: 89 04 24              mov    %eax,(%esp)

 8048f20: e8 bf ff ff ff        call   8048ee4 <fun7>//如果*x<=36,(x+8)作为地址进入下一层递归

 8048f25: 8d 44 00 01           lea    0x1(%eax,%eax,1),%eax//返回值=返回值*2+1

 8048f29: eb 05                jmp    8048f30 <fun7+0x4c>

 8048f2b: b8 ff ff ff ff            mov    $0xffffffff,%eax

 8048f30: 83 c4 18              add    $0x18,%esp

 8048f33: 5b                    pop    %ebx

 8048f34: c3                    ret    

因此可得:(key=22)

(2)运行结果:

总结:

phase 1:He is evil and fits easily into most overhead storage bins.

phase 2:1 2 4 8 16 32

phase 3:0 276

phase 4:0 11 DrEvil或1 11 DrEvil

phase 5:mfcdhg

phase 6:2 1 4 5 6 3

猜你喜欢

转载自blog.csdn.net/longzaizai_/article/details/124560551