csapp - lab2

花了一天多时间, 做完了csapp很有名的bomb实验,感到有趣的同时受益匪浅。这个lab一共有6个阶段,越往后难度越大。个人觉得最后一个lab是最有趣的,涉及到了链表以及排序。

csapp官网下载bomb实验的相关资料,解压后利用objdump -d bomb > bomb.asm进行反汇编得到bomb.asm,再进行下面的六个阶段的拆炸弹过程。

phase_1

08048b20 <phase_1>:
 8048b20:   55                      push   %ebp
 8048b21:   89 e5                   mov    %esp,%ebp
 8048b23:   83 ec 08                sub    $0x8,%esp
 8048b26:   8b 45 08                mov    0x8(%ebp),%eax
 8048b29:   83 c4 f8                add    $0xfffffff8,%esp
 8048b2c:   68 c0 97 04 08          push   $0x80497c0
 8048b31:   50                      push   %eax
 8048b32:   e8 f9 04 00 00          call   8049030 <strings_not_equal>
 8048b37:   83 c4 10                add    $0x10,%esp
 8048b3a:   85 c0                   test   %eax,%eax
 8048b3c:   74 05                   je     8048b43 <phase_1+0x23>
 8048b3e:   e8 b9 09 00 00          call   80494fc <explode_bomb>
 8048b43:   89 ec                   mov    %ebp,%esp
 8048b45:   5d                      pop    %ebp
 8048b46:   c3                      ret    
 8048b47:   90                      nop

查看此函数和函数strings_not_equal很简单就可以看出是比较输入的字符串和位于0x80497c0的字符串是否相等,所以直接gdb后打断点查看该位置的字符串即可。

phase_2
08048b48 <phase_2>:
 8048b48:   55                      push   %ebp
 8048b49:   89 e5                   mov    %esp,%ebp
 8048b4b:   83 ec 20                sub    $0x20,%esp
 8048b4e:   56                      push   %esi
 8048b4f:   53                      push   %ebx
 8048b50:   8b 55 08                mov    0x8(%ebp),%edx
 8048b53:   83 c4 f8                add    $0xfffffff8,%esp
 8048b56:   8d 45 e8                lea    -0x18(%ebp),%eax
 8048b59:   50                      push   %eax
 8048b5a:   52                      push   %edx
 8048b5b:   e8 78 04 00 00          call   8048fd8 <read_six_numbers>
 8048b60:   83 c4 10                add    $0x10,%esp

 8048b63:   83 7d e8 01             cmpl   $0x1,-0x18(%ebp)
 8048b67:   74 05                   je     8048b6e <phase_2+0x26>
 8048b69:   e8 8e 09 00 00          call   80494fc <explode_bomb>
 8048b6e:   bb 01 00 00 00          mov    $0x1,%ebx
 8048b73:   8d 75 e8                lea    -0x18(%ebp),%esi
 8048b76:   8d 43 01                lea    0x1(%ebx),%eax
 8048b79:   0f af 44 9e fc          imul   -0x4(%esi,%ebx,4),%eax
 8048b7e:   39 04 9e                cmp    %eax,(%esi,%ebx,4)
 8048b81:   74 05                   je     8048b88 <phase_2+0x40>
 8048b83:   e8 74 09 00 00          call   80494fc <explode_bomb>
 8048b88:   43                      inc    %ebx
 8048b89:   83 fb 05                cmp    $0x5,%ebx
 8048b8c:   7e e8                   jle    8048b76 <phase_2+0x2e>

 8048b8e:   8d 65 d8                lea    -0x28(%ebp),%esp
 8048b91:   5b                      pop    %ebx
 8048b92:   5e                      pop    %esi
 8048b93:   89 ec                   mov    %ebp,%esp
 8048b95:   5d                      pop    %ebp
 8048b96:   c3                      ret    
 8048b97:   90                      nop

第二个阶段是要输入6个数字作为答案满足后面的检查,先读入输入的6个数字read_six_numbers,再对这6个数字进行循环检查,第一个数字为1,从8048b63这一行可以看出来,后面的数字是根据前一个数字和索引加一相乘获得。

phase_3
08048b98 <phase_3>:
 8048b98:   55                      push   %ebp
 8048b99:   89 e5                   mov    %esp,%ebp
 8048b9b:   83 ec 14                sub    $0x14,%esp

 8048b9e:   53                      push   %ebx
 8048b9f:   8b 55 08                mov    0x8(%ebp),%edx
 8048ba2:   83 c4 f4                add    $0xfffffff4,%esp
 8048ba5:   8d 45 fc                lea    -0x4(%ebp),%eax     ;; int
 8048ba8:   50                      push   %eax                
 8048ba9:   8d 45 fb                lea    -0x5(%ebp),%eax     ;; char
 8048bac:   50                      push   %eax    
 8048bad:   8d 45 f4                lea    -0xc(%ebp),%eax     ;; int
 8048bb0:   50                      push   %eax
 8048bb1:   68 de 97 04 08          push   $0x80497de
 8048bb6:   52                      push   %edx
 8048bb7:   e8 a4 fc ff ff          call   8048860 <sscanf@plt>

 8048bbc:   83 c4 20                add    $0x20,%esp
 8048bbf:   83 f8 02                cmp    $0x2,%eax               ;; 参数个数必须大于2
 8048bc2:   7f 05                   jg     8048bc9 <phase_3+0x31>
 8048bc4:   e8 33 09 00 00          call   80494fc <explode_bomb>

 8048bc9:   83 7d f4 07             cmpl   $0x7,-0xc(%ebp)         ;; 第一个数字必须不大于7,注意这里使用的是无符号数字的比较
 8048bcd:   0f 87 b5 00 00 00       ja     8048c88 <phase_3+0xf0>

 8048bd3:   8b 45 f4                mov    -0xc(%ebp),%eax
 8048bd6:   ff 24 85 e8 97 04 08    jmp    *0x80497e8(,%eax,4)     ;; 根据第一个数字n3的值决定跳转地址,取值范围0-7

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

 8048be0:   b3 71                   mov    $0x71,%bl               ;; n1 = 0
 8048be2:   81 7d fc 09 03 00 00    cmpl   $0x309,-0x4(%ebp)
 8048be9:   0f 84 a0 00 00 00       je     8048c8f <phase_3+0xf7>
 8048bef:   e8 08 09 00 00          call   80494fc <explode_bomb>
 8048bf4:   e9 96 00 00 00          jmp    8048c8f <phase_3+0xf7>
 8048bf9:   8d b4 26 00 00 00 00    lea    0x0(%esi,%eiz,1),%esi

 8048c00:   b3 62                   mov    $0x62,%bl               ;; n1 = 1
 8048c02:   81 7d fc d6 00 00 00    cmpl   $0xd6,-0x4(%ebp)
 8048c09:   0f 84 80 00 00 00       je     8048c8f <phase_3+0xf7>
 8048c0f:   e8 e8 08 00 00          call   80494fc <explode_bomb>
 8048c14:   eb 79                   jmp    8048c8f <phase_3+0xf7>

 8048c16:   b3 62                   mov    $0x62,%bl               ;; n1 = 2
 8048c18:   81 7d fc f3 02 00 00    cmpl   $0x2f3,-0x4(%ebp)
 8048c1f:   74 6e                   je     8048c8f <phase_3+0xf7>
 8048c21:   e8 d6 08 00 00          call   80494fc <explode_bomb>
 8048c26:   eb 67                   jmp    8048c8f <phase_3+0xf7>

 8048c28:   b3 6b                   mov    $0x6b,%bl               ;; n1 = 3
 8048c2a:   81 7d fc fb 00 00 00    cmpl   $0xfb,-0x4(%ebp)
 8048c31:   74 5c                   je     8048c8f <phase_3+0xf7>
 8048c33:   e8 c4 08 00 00          call   80494fc <explode_bomb>
 8048c38:   eb 55                   jmp    8048c8f <phase_3+0xf7>
 8048c3a:   8d b6 00 00 00 00       lea    0x0(%esi),%esi

 8048c40:   b3 6f                   mov    $0x6f,%bl               ;; n1 = 4
 8048c42:   81 7d fc a0 00 00 00    cmpl   $0xa0,-0x4(%ebp)
 8048c49:   74 44                   je     8048c8f <phase_3+0xf7>
 8048c4b:   e8 ac 08 00 00          call   80494fc <explode_bomb>
 8048c50:   eb 3d                   jmp    8048c8f <phase_3+0xf7>

 8048c52:   b3 74                   mov    $0x74,%bl               ;; n1 = 5
 8048c54:   81 7d fc ca 01 00 00    cmpl   $0x1ca,-0x4(%ebp)
 8048c5b:   74 32                   je     8048c8f <phase_3+0xf7>
 8048c5d:   e8 9a 08 00 00          call   80494fc <explode_bomb>
 8048c62:   eb 2b                   jmp    8048c8f <phase_3+0xf7>

 8048c64:   b3 76                   mov    $0x76,%bl               ;; n1 = 6
 8048c66:   81 7d fc 0c 03 00 00    cmpl   $0x30c,-0x4(%ebp)
 8048c6d:   74 20                   je     8048c8f <phase_3+0xf7>
 8048c6f:   e8 88 08 00 00          call   80494fc <explode_bomb>
 8048c74:   eb 19                   jmp    8048c8f <phase_3+0xf7>

 8048c76:   b3 62                   mov    $0x62,%bl               ;; n1 = 7
 8048c78:   81 7d fc 0c 02 00 00    cmpl   $0x20c,-0x4(%ebp)
 8048c7f:   74 0e                   je     8048c8f <phase_3+0xf7>
 8048c81:   e8 76 08 00 00          call   80494fc <explode_bomb>
 8048c86:   eb 07                   jmp    8048c8f <phase_3+0xf7>

 8048c88:   b3 78                   mov    $0x78,%bl               
 8048c8a:   e8 6d 08 00 00          call   80494fc <explode_bomb>

 8048c8f:   3a 5d fb                cmp    -0x5(%ebp),%bl
 8048c92:   74 05                   je     8048c99 <phase_3+0x101>
 8048c94:   e8 63 08 00 00          call   80494fc <explode_bomb>
 8048c99:   8b 5d e8                mov    -0x18(%ebp),%ebx
 8048c9c:   89 ec                   mov    %ebp,%esp
 8048c9e:   5d                      pop    %ebp
 8048c9f:   c3                      ret 

先使用print (char*)查看0x80497de代表的字符串格式,得到%d %c %d,再往下看,得到输入的三个值以后,需要知道三个值的取值,避免炸弹爆炸。查看0x80497e8+4*n3(n1<=7)地址的16进制值,代表的是8个跳转地址0x8048be0, 0x8048c00 ...。选择其中一个跳转,我选择的是0,从$0x309,-0x4(%ebp)可以得到第三个参数的值,再看0x8048c8f处的代码,可以得到第二个字符类型的值是0x71,查ascii表即可得到该字符。至此,第三阶段拆弹完毕。

phase_4
    08048ca0 <func4>:
 8048ca0:   55                      push   %ebp
 8048ca1:   89 e5                   mov    %esp,%ebp
 8048ca3:   83 ec 10                sub    $0x10,%esp

 8048ca6:   56                      push   %esi
 8048ca7:   53                      push   %ebx
 8048ca8:   8b 5d 08                mov    0x8(%ebp),%ebx       ;; (%ebx) = v1

 8048cab:   83 fb 01                cmp    $0x1,%ebx
 8048cae:   7e 20                   jle    8048cd0 <func4+0x30> ;; 有符号小于等于1,则v1 = 1
 8048cb0:   83 c4 f4                add    $0xfffffff4,%esp
 8048cb3:   8d 43 ff                lea    -0x1(%ebx),%eax
 8048cb6:   50                      push   %eax
 8048cb7:   e8 e4 ff ff ff          call   8048ca0 <func4>
 8048cbc:   89 c6                   mov    %eax,%esi
 8048cbe:   83 c4 f4                add    $0xfffffff4,%esp
 8048cc1:   8d 43 fe                lea    -0x2(%ebx),%eax
 8048cc4:   50                      push   %eax
 8048cc5:   e8 d6 ff ff ff          call   8048ca0 <func4>
 8048cca:   01 f0                   add    %esi,%eax
 8048ccc:   eb 07                   jmp    8048cd5 <func4+0x35>
 8048cce:   89 f6                   mov    %esi,%esi

 8048cd0:   b8 01 00 00 00          mov    $0x1,%eax            ;; 如果v1 = 1,(%eax)= 1,返回
 8048cd5:   8d 65 e8                lea    -0x18(%ebp),%esp

 8048cd8:   5b                      pop    %ebx
 8048cd9:   5e                      pop    %esi
 8048cda:   89 ec                   mov    %ebp,%esp
 8048cdc:   5d                      pop    %ebp
 8048cdd:   c3                      ret    
 8048cde:   89 f6                   mov    %esi,%esi

08048ce0 <phase_4>:
 8048ce0:   55                      push   %ebp
 8048ce1:   89 e5                   mov    %esp,%ebp
 8048ce3:   83 ec 18                sub    $0x18,%esp

 8048ce6:   8b 55 08                mov    0x8(%ebp),%edx
 8048ce9:   83 c4 fc                add    $0xfffffffc,%esp
 8048cec:   8d 45 fc                lea    -0x4(%ebp),%eax        ;; 假设值为v1
 8048cef:   50                      push   %eax
 8048cf0:   68 08 98 04 08          push   $0x8049808             ;; (0x8049808) = "%d"
 8048cf5:   52                      push   %edx                   ;; 输入值的地址
 8048cf6:   e8 65 fb ff ff          call   8048860 <sscanf@plt>

 8048cfb:   83 c4 10                add    $0x10,%esp
 8048cfe:   83 f8 01                cmp    $0x1,%eax
 8048d01:   75 06                   jne    8048d09 <phase_4+0x29> ;; 参数个数为1,否则爆炸

 8048d03:   83 7d fc 00             cmpl   $0x0,-0x4(%ebp)        ;; 将v1和0比较,带符号数比较,需要大于0
 8048d07:   7f 05                   jg     8048d0e <phase_4+0x2e>
 8048d09:   e8 ee 07 00 00          call   80494fc <explode_bomb>

 8048d0e:   83 c4 f4                add    $0xfffffff4,%esp
 8048d11:   8b 45 fc                mov    -0x4(%ebp),%eax
 8048d14:   50                      push   %eax
 8048d15:   e8 86 ff ff ff          call   8048ca0 <func4>

 8048d1a:   83 c4 10                add    $0x10,%esp
 8048d1d:   83 f8 37                cmp    $0x37,%eax             ;; 不等于0x37就爆炸
 8048d20:   74 05                   je     8048d27 <phase_4+0x47>

 8048d22:   e8 d5 07 00 00          call   80494fc <explode_bomb>
 8048d27:   89 ec                   mov    %ebp,%esp
 8048d29:   5d                      pop    %ebp
 8048d2a:   c3                      ret    
 8048d2b:   90                      nop

这里的phase_4函数调用了func_4函数,而func_4是fibinacci函数,所以这个炸弹还是很简单的,只需要求到func_4(x) = 0x37 = 55的数字x就可以了。

phase_5
08048d2c <phase_5>:
 8048d2c:   55                      push   %ebp
 8048d2d:   89 e5                   mov    %esp,%ebp
 8048d2f:   83 ec 10                sub    $0x10,%esp
 8048d32:   56                      push   %esi
 8048d33:   53                      push   %ebx

 8048d34:   8b 5d 08                mov    0x8(%ebp),%ebx
 8048d37:   83 c4 f4                add    $0xfffffff4,%esp
 8048d3a:   53                      push   %ebx
 8048d3b:   e8 d8 02 00 00          call   8049018 <string_length>       ;; 获取输入的字符串长度,放在%eax8048d40:   83 c4 10                add    $0x10,%esp
 8048d43:   83 f8 06                cmp    $0x6,%eax
 8048d46:   74 05                   je     8048d4d <phase_5+0x21>        ;; 字符串长度为6
 8048d48:   e8 af 07 00 00          call   80494fc <explode_bomb>
 8048d4d:   31 d2                   xor    %edx,%edx
 8048d4f:   8d 4d f8                lea    -0x8(%ebp),%ecx
 8048d52:   be 20 b2 04 08          mov    $0x804b220,%esi
 8048d57:   8a 04 1a                mov    (%edx,%ebx,1),%al
 8048d5a:   24 0f                   and    $0xf,%al
 8048d5c:   0f be c0                movsbl %al,%eax

 8048d5f:   8a 04 30                mov    (%eax,%esi,1),%al
 8048d62:   88 04 0a                mov    %al,(%edx,%ecx,1)
 8048d65:   42                      inc    %edx
 8048d66:   83 fa 05                cmp    $0x5,%edx
 8048d69:   7e ec                   jle    8048d57 <phase_5+0x2b>
 8048d6b:   c6 45 fe 00             movb   $0x0,-0x2(%ebp)
 8048d6f:   83 c4 f8                add    $0xfffffff8,%esp

 8048d72:   68 0b 98 04 08          push   $0x804980b
 8048d77:   8d 45 f8                lea    -0x8(%ebp),%eax
 8048d7a:   50                      push   %eax
 8048d7b:   e8 b0 02 00 00          call   8049030 <strings_not_equal>
 8048d80:   83 c4 10                add    $0x10,%esp
 8048d83:   85 c0                   test   %eax,%eax
 8048d85:   74 05                   je     8048d8c <phase_5+0x60>
 8048d87:   e8 70 07 00 00          call   80494fc <explode_bomb>
 8048d8c:   8d 65 e8                lea    -0x18(%ebp),%esp

 8048d8f:   5b                      pop    %ebx
 8048d90:   5e                      pop    %esi
 8048d91:   89 ec                   mov    %ebp,%esp
 8048d93:   5d                      pop    %ebp
 8048d94:   c3                      ret    
 8048d95:   8d 76 00                lea    0x0(%esi),%esi

push $0x804980b和后面的call 8049030 <strings_not_equal>是为了比较两个字符串是否相等,查看地址0x804980b的字节码,会得到6个字节码c0 c1 c2 c3 c4 c5。而和这6个字节相比较的字符串是通过mov %al,(%edx,%ecx,1)循环写入的。而这里的%al则是来自mov (%eax,%esi,1),%al,这里的%esi的值是0x804b220,该地址后面的字节可以通过x/2w 0x804b220获取,其实就是根据我们输入的字符的低字节作为mov (%eax,%esi,1),%al%eax,即索引值,获取我们想要的字符,理解之后就可以根据上面的分析很容易得到想要的字符低位字节,再在ascii表中选择字符就可以了,答案不是唯一的。

phase_6
    08048d98 <phase_6>:
 8048d98:   55                      push   %ebp
 8048d99:   89 e5                   mov    %esp,%ebp
 8048d9b:   83 ec 4c                sub    $0x4c,%esp
 8048d9e:   57                      push   %edi
 8048d9f:   56                      push   %esi
 8048da0:   53                      push   %ebx

 8048da1:   8b 55 08                mov    0x8(%ebp),%edx
 8048da4:   c7 45 cc 6c b2 04 08    movl   $0x804b26c,-0x34(%ebp)
 8048dab:   83 c4 f8                add    $0xfffffff8,%esp
 8048dae:   8d 45 e8                lea    -0x18(%ebp),%eax
 8048db1:   50                      push   %eax
 8048db2:   52                      push   %edx
 8048db3:   e8 20 02 00 00          call   8048fd8 <read_six_numbers>

 8048db8:   31 ff                   xor    %edi,%edi
 8048dba:   83 c4 10                add    $0x10,%esp
 8048dbd:   8d 76 00                lea    0x0(%esi),%esi
 ;; 下面这段证明6个数字为1-6,顺序不知,不过6个数字不能重复
 8048dc0:   8d 45 e8                lea    -0x18(%ebp),%eax
 8048dc3:   8b 04 b8                mov    (%eax,%edi,4),%eax
 8048dc6:   48                      dec    %eax                      ;; 证明不能为0,否则无符号数比较后不跳转
 8048dc7:   83 f8 05                cmp    $0x5,%eax
 8048dca:   76 05                   jbe    8048dd1 <phase_6+0x39>    ;; 无符号低于或等于5
 8048dcc:   e8 2b 07 00 00          call   80494fc <explode_bomb>
 8048dd1:   8d 5f 01                lea    0x1(%edi),%ebx
 8048dd4:   83 fb 05                cmp    $0x5,%ebx
 8048dd7:   7f 23                   jg     8048dfc <phase_6+0x64>
 8048dd9:   8d 04 bd 00 00 00 00    lea    0x0(,%edi,4),%eax
 8048de0:   89 45 c8                mov    %eax,-0x38(%ebp)
 8048de3:   8d 75 e8                lea    -0x18(%ebp),%esi
 8048de6:   8b 55 c8                mov    -0x38(%ebp),%edx
 8048de9:   8b 04 32                mov    (%edx,%esi,1),%eax
 8048dec:   3b 04 9e                cmp    (%esi,%ebx,4),%eax
 8048def:   75 05                   jne    8048df6 <phase_6+0x5e>
 8048df1:   e8 06 07 00 00          call   80494fc <explode_bomb>
 8048df6:   43                      inc    %ebx
 8048df7:   83 fb 05                cmp    $0x5,%ebx
 8048dfa:   7e ea                   jle    8048de6 <phase_6+0x4e>
 8048dfc:   47                      inc    %edi
 8048dfd:   83 ff 05                cmp    $0x5,%edi
 8048e00:   7e be                   jle    8048dc0 <phase_6+0x28>

 8048e02:   31 ff                   xor    %edi,%edi
 8048e04:   8d 4d e8                lea    -0x18(%ebp),%ecx
 8048e07:   8d 45 d0                lea    -0x30(%ebp),%eax
 8048e0a:   89 45 c4                mov    %eax,-0x3c(%ebp)
 8048e0d:   8d 76 00                lea    0x0(%esi),%esi

 8048e10:   8b 75 cc                mov    -0x34(%ebp),%esi
 8048e13:   bb 01 00 00 00          mov    $0x1,%ebx
 8048e18:   8d 04 bd 00 00 00 00    lea    0x0(,%edi,4),%eax
 8048e1f:   89 c2                   mov    %eax,%edx
 8048e21:   3b 1c 08                cmp    (%eax,%ecx,1),%ebx
 8048e24:   7d 12                   jge    8048e38 <phase_6+0xa0>
 8048e26:   8b 04 0a                mov    (%edx,%ecx,1),%eax
 8048e29:   8d b4 26 00 00 00 00    lea    0x0(%esi,%eiz,1),%esi
 8048e30:   8b 76 08                mov    0x8(%esi),%esi
 8048e33:   43                      inc    %ebx
 8048e34:   39 c3                   cmp    %eax,%ebx
 8048e36:   7c f8                   jl     8048e30 <phase_6+0x98>
 8048e38:   8b 55 c4                mov    -0x3c(%ebp),%edx
 8048e3b:   89 34 ba                mov    %esi,(%edx,%edi,4)
 8048e3e:   47                      inc    %edi
 8048e3f:   83 ff 05                cmp    $0x5,%edi
 8048e42:   7e cc                   jle    8048e10 <phase_6+0x78>

 8048e44:   8b 75 d0                mov    -0x30(%ebp),%esi
 8048e47:   89 75 cc                mov    %esi,-0x34(%ebp)
 8048e4a:   bf 01 00 00 00          mov    $0x1,%edi
 8048e4f:   8d 55 d0                lea    -0x30(%ebp),%edx

 8048e52:   8b 04 ba                mov    (%edx,%edi,4),%eax
 8048e55:   89 46 08                mov    %eax,0x8(%esi)
 8048e58:   89 c6                   mov    %eax,%esi
 8048e5a:   47                      inc    %edi
 8048e5b:   83 ff 05                cmp    $0x5,%edi
 8048e5e:   7e f2                   jle    8048e52 <phase_6+0xba>

 8048e60:   c7 46 08 00 00 00 00    movl   $0x0,0x8(%esi)
 8048e67:   8b 75 cc                mov    -0x34(%ebp),%esi
 8048e6a:   31 ff                   xor    %edi,%edi
 8048e6c:   8d 74 26 00             lea    0x0(%esi,%eiz,1),%esi

 8048e70:   8b 56 08                mov    0x8(%esi),%edx
 8048e73:   8b 06                   mov    (%esi),%eax
 8048e75:   3b 02                   cmp    (%edx),%eax
 8048e77:   7d 05                   jge    8048e7e <phase_6+0xe6>
 8048e79:   e8 7e 06 00 00          call   80494fc <explode_bomb>
 8048e7e:   8b 76 08                mov    0x8(%esi),%esi
 8048e81:   47                      inc    %edi
 8048e82:   83 ff 04                cmp    $0x4,%edi
 8048e85:   7e e9                   jle    8048e70 <phase_6+0xd8>

 8048e87:   8d 65 a8                lea    -0x58(%ebp),%esp
 8048e8a:   5b                      pop    %ebx
 8048e8b:   5e                      pop    %esi
 8048e8c:   5f                      pop    %edi
 8048e8d:   89 ec                   mov    %ebp,%esp
 8048e8f:   5d                      pop    %ebp
 8048e90:   c3                      ret    
 8048e91:   8d 76 00                lea    0x0(%esi),%esi
  • 先利用函数read_six_numbers读入6个数字,根据bomb的条件可以得到6个数字为不重复的1-6,因为如果数字为0,dec %eax得到的二进制位0xffffffff, 从cmp $0x5,%eaxjbe 8048dd1 <phase_6+0x39>可以得出是无符号比较,所以不会跳转引起bomb;
  • 0x8048e100x8048e42的汇编语句必须联系地址为0x804b26c的情况才能得出结论,使用gdb获取该地址存储的值,可以得到该处是一个链表的node节点,再假设一组1-6的随机分布代入该段汇编,可以得出实际上有2个数组,分别命名为input[]和addr[]。input数组存储的是我们输入的6个数字,而addr数组则是存储input数组相应位置所对应的链表索引。举个例子,如果input[] = {5, 2, 1, 4, 3, 6},那么b[0]所对应的就是链表的第5个node,该node的第二个字存储的其实就是0x5;
  • 最后将addr[]数组元素即链表地址所对应的链表进行重新连接排序,根据最后避免bomb的条件很容易可以看出链表数据是倒序排列,根据0x804b26c处的链表信息可以得出最后的索引顺序。至此,第六阶段也结束了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值