深入理解计算机系统bomb_lab

前言:一个不会汇编的菜鸟强行做一个bomb_lab作业。

拖了两周才做好的bomb_lab,期间因为心情郁闷拖了一周?
现在来写一下“拆后感”。(这个博客早就想写,因为期中考试和懒又拖了两周,有点可惜一些细节记得不是特别清楚了)话不多说上代码(之前一大段编译准备栈什么的删了)
开始前的一些指令:
cd 路径 ->进入文件存放的目录下
./bomb_XXX 运行那个炸弹程序
objdump -d bomb_xxx > bomb_xxx.s 把反汇编代码放到文本框里好看一点。
gdb bomb_104 进入该程序的gdb调试

第一关热身,x/s 0x804a0a4
出来一句话:And they have no disregard for human life.
输入要和这句话相等,否则爆炸,这就是第一句。

08048b33 :
 8048b33:   83 ec 14                sub    $0x14,%esp
 8048b36:   68 a4 a0 04 08          push   $0x804a0a4             //突然一个奇怪的地址入栈,很可疑啊
 8048b3b:   ff 74 24 1c             pushl  0x1c(%esp)
 8048b3f:   e8 3b 05 00 00          call   804907f   函数名说明了问题
 8048b44:   83 c4 10                add    $0x10,%esp
 8048b47:   85 c0                   test   %eax,%eax
 8048b49:   74 05                   je     8048b50 0x1d> 
 8048b4b:   e8 26 06 00 00          call   8049176  //不相等就爆炸
 8048b50:   83 c4 0c                add    $0xc,%esp
 8048b53:   c3                      ret    

第二关代码不长,也只有一个循环,我是直接读代码的,由ebx++访问了所有参数,分析得出是斐波那契数列,
输入1 2 4 7 11 15过了。

08048b54 :
 8048b54:   53                      push   %ebx
 8048b55:   83 ec 30                sub    $0x30,%esp
 8048b58:   65 a1 14 00 00 00       mov    %gs:0x14,%eax
 8048b5e:   89 44 24 24             mov    %eax,0x24(%esp)
 8048b62:   31 c0                   xor    %eax,%eax
 8048b64:   8d 44 24 0c             lea    0xc(%esp),%eax
 8048b68:   50                      push   %eax
 8048b69:   ff 74 24 3c             pushl  0x3c(%esp)
 8048b6d:   e8 29 06 00 00          call   804919b   这边才开始输入,前面的代码不用管了(论函数名规范的重要性)
 8048b72:   83 c4 10                add    $0x10,%esp
 8048b75:   83 7c 24 04 00          cmpl   $0x0,0x4(%esp)        不懂,好像意思是第一个参数不为0,但试了一下0也是可以的,懵逼...
 8048b7a:   79 05                   jns    8048b81 0x2d>
 8048b7c:   e8 f5 05 00 00          call   8049176 
 8048b81:   bb 01 00 00 00          mov    $0x1,%ebx
 8048b86:   89 d8                   mov    %ebx,%eax
 8048b88:   03 04 9c                add    (%esp,%ebx,4),%eax     eax加上第一个参数的值   
 8048b8b:   39 44 9c 04             cmp    %eax,0x4(%esp,%ebx,4)  eax与第二个参数比较
 8048b8f:   74 05                   je     8048b96 0x42> 不等会爆炸
 8048b91:   e8 e0 05 00 00          call   8049176 
 8048b96:   83 c3 01                add    $0x1,%ebx               ebx++;
 8048b99:   83 fb 06                cmp    $0x6,%ebx               ebx<6的时候回去,原来是个循环
 8048b9c:   75 e8                   jne    8048b86 0x32>
 8048b9e:   8b 44 24 1c             mov    0x1c(%esp),%eax
 8048ba2:   65 33 05 14 00 00 00    xor    %gs:0x14,%eax
 8048ba9:   74 05                   je     8048bb0 0x5c>
 8048bab:   e8 e0 fb ff ff          call   8048790 <__stack_chk_fail@plt>
 8048bb0:   83 c4 28                add    $0x28,%esp
 8048bb3:   5b                      pop    %ebx
 8048bb4:   c3                      ret    

第三关有个switch因此代码很长,偷了个懒,找到一条可以不爆炸的路径就出去了(有多组解)。
一个答案是:3 l 240  路径,计算地址跳来跳去的有点累,注释也加了好几行。
08048bb5 :
 8048bb5:   83 ec 28                sub    $0x28,%esp
 8048bb8:   65 a1 14 00 00 00       mov    %gs:0x14,%eax
 8048bbe:   89 44 24 18             mov    %eax,0x18(%esp)
 8048bc2:   31 c0                   xor    %eax,%eax
 8048bc4:   8d 44 24 14             lea    0x14(%esp),%eax
 8048bc8:   50                      push   %eax
 8048bc9:   8d 44 24 13             lea    0x13(%esp),%eax
 8048bcd:   50                      push   %eax
 8048bce:   8d 44 24 18             lea    0x18(%esp),%eax
 8048bd2:   50                      push   %eax
 8048bd3:   68 f6 a0 04 08          push   $0x804a0f6           这个地址肯定有些门道, x/s 它得到 %d %c %d,这是输入的格式
 8048bd8:   ff 74 24 3c             pushl  0x3c(%esp)
 8048bdc:   e8 3f fc ff ff          call   8048820 <__isoc99_sscanf@plt>  这边调用输入函数
 8048be1:   83 c4 20                add    $0x20,%esp
 8048be4:   83 f8 02                cmp    $0x2,%eax                      不是很懂sscanf的返回值,这边大概是输入了太多的东西就爆炸
 8048be7:   7f 05                   jg     8048bee 0x39>
 8048be9:   e8 88 05 00 00          call   8049176 
 8048bee:   83 7c 24 04 07          cmpl   $0x7,0x4(%esp)  第一个参数来比较啦,比7大就爆炸
 8048bf3:   0f 87 fc 00 00 00       ja     8048cf5 0x140>//bomb!
 8048bf9:   8b 44 24 04             mov    0x4(%esp),%eax
 8048bfd:   ff 24 85 00 a1 04 08    jmp    *0x804a100(,%eax,4)//switch!!跳转表来了,根据eax(第一个输入的数)判断调到哪一行,看了一下哪个简单点,当时输入了个3继续往下走
 8048c04:   b8 6a 00 00 00          mov    $0x6a,%eax
 8048c09:   81 7c 24 08 4e 03 00    cmpl   $0x34e,0x8(%esp)
 8048c10:   00 
 8048c11:   0f 84 e8 00 00 00       je     8048cff 0x14a>
 8048c17:   e8 5a 05 00 00          call   8049176 
 8048c1c:   b8 6a 00 00 00          mov    $0x6a,%eax
 8048c21:   e9 d9 00 00 00          jmp    8048cff 0x14a>
 8048c26:   b8 67 00 00 00          mov    $0x67,%eax//from switch eax=1
 8048c2b:   81 7c 24 08 c9 01 00    cmpl   $0x1c9,0x8(%esp)
 8048c32:   00 
 8048c33:   0f 84 c6 00 00 00       je     8048cff 0x14a>
 8048c39:   e8 38 05 00 00          call   8049176 
 8048c3e:   b8 67 00 00 00          mov    $0x67,%eax
 8048c43:   e9 b7 00 00 00          jmp    8048cff 0x14a>
 8048c48:   b8 65 00 00 00          mov    $0x65,%eax
 8048c4d:   81 7c 24 08 62 02 00    cmpl   $0x262,0x8(%esp)
 8048c54:   00 
 8048c55:   0f 84 a4 00 00 00       je     8048cff 0x14a>
 8048c5b:   e8 16 05 00 00          call   8049176 
 8048c60:   b8 65 00 00 00          mov    $0x65,%eax
 8048c65:   e9 95 00 00 00          jmp    8048cff 0x14a>
 8048c6a:   b8 6c 00 00 00          mov    $0x6c,%eax// from eax=3         输入3到这儿了
 8048c6f:   81 7c 24 08 f0 00 00    cmpl   $0xf0,0x8(%esp)//240,get        原来3 对应的第二个数要等于240
 8048c76:   00 
 8048c77:   0f 84 82 00 00 00       je     8048cff 0x14a>
 8048c7d:   e8 f4 04 00 00          call   8049176 
 8048c82:   b8 6c 00 00 00          mov    $0x6c,%eax
 8048c87:   eb 76                   jmp    8048cff 0x14a>
 8048c89:   b8 78 00 00 00          mov    $0x78,%eax
 8048c8e:   81 7c 24 08 8e 00 00    cmpl   $0x8e,0x8(%esp)
 8048c95:   00 
 8048c96:   74 67                   je     8048cff 0x14a>
 8048c98:   e8 d9 04 00 00          call   8049176 
 8048c9d:   b8 78 00 00 00          mov    $0x78,%eax
 8048ca2:   eb 5b                   jmp    8048cff 0x14a>
 8048ca4:   b8 61 00 00 00          mov    $0x61,%eax
 8048ca9:   81 7c 24 08 b1 02 00    cmpl   $0x2b1,0x8(%esp)
 8048cb0:   00 
 8048cb1:   74 4c                   je     8048cff 0x14a>
 8048cb3:   e8 be 04 00 00          call   8049176 
 8048cb8:   b8 61 00 00 00          mov    $0x61,%eax
 8048cbd:   eb 40                   jmp    8048cff 0x14a>
 8048cbf:   b8 79 00 00 00          mov    $0x79,%eax
 8048cc4:   81 7c 24 08 3f 02 00    cmpl   $0x23f,0x8(%esp)
 8048ccb:   00 
 8048ccc:   74 31                   je     8048cff 0x14a>
 8048cce:   e8 a3 04 00 00          call   8049176 
 8048cd3:   b8 79 00 00 00          mov    $0x79,%eax
 8048cd8:   eb 25                   jmp    8048cff 0x14a>
 8048cda:   b8 6f 00 00 00          mov    $0x6f,%eax
 8048cdf:   81 7c 24 08 4c 02 00    cmpl   $0x24c,0x8(%esp)
 8048ce6:   00 
 8048ce7:   74 16                   je     8048cff 0x14a>
 8048ce9:   e8 88 04 00 00          call   8049176 
 8048cee:   b8 6f 00 00 00          mov    $0x6f,%eax
 8048cf3:   eb 0a                   jmp    8048cff 0x14a>
 8048cf5:   e8 7c 04 00 00          call   8049176 
 8048cfa:   b8 61 00 00 00          mov    $0x61,%eax
 8048cff:   3a 44 24 03             cmp    0x3(%esp),%al// %al-->l,get  eax = 3  到了这儿,可在此设断点:break *0x8048cff,info registers 查看当前寄存器状态,al中存着l,随便猜一下,%c是l
 8048d03:   74 05                   je     8048d0a 0x155>
 8048d05:   e8 6c 04 00 00          call   8049176 
 8048d0a:   8b 44 24 0c             mov    0xc(%esp),%eax
 8048d0e:   65 33 05 14 00 00 00    xor    %gs:0x14,%eax
 8048d15:   74 05                   je     8048d1c 0x167>
 8048d17:   e8 74 fa ff ff          call   8048790 <__stack_chk_fail@plt>
 8048d1c:   83 c4 1c                add    $0x1c,%esp
 8048d1f:   c3                      ret    

第四关代码不长,可是它调用一个递归函数,功力尚浅,看晕了。。。很无耻地看到数据范围不是很大,忍不住穷举得出了结果
6 6。这个答案也是6。有时间要把递归推一推。
08048d20 :
 8048d20:   56                      push   %esi
 8048d21:   53                      push   %ebx
 8048d22:   83 ec 04                sub    $0x4,%esp
 8048d25:   8b 4c 24 10             mov    0x10(%esp),%ecx
 8048d29:   8b 5c 24 14             mov    0x14(%esp),%ebx
 8048d2d:   8b 74 24 18             mov    0x18(%esp),%esi
 8048d31:   89 f0                   mov    %esi,%eax
 8048d33:   29 d8                   sub    %ebx,%eax
 8048d35:   89 c2                   mov    %eax,%edx
 8048d37:   c1 ea 1f                shr    $0x1f,%edx//>>31
 8048d3a:   01 d0                   add    %edx,%eax
 8048d3c:   d1 f8                   sar    %eax
 8048d3e:   8d 14 18                lea    (%eax,%ebx,1),%edx
 8048d41:   39 ca                   cmp    %ecx,%edx
 8048d43:   7e 15                   jle    8048d5a 0x3a>//over
 8048d45:   83 ec 04                sub    $0x4,%esp
 8048d48:   83 ea 01                sub    $0x1,%edx
 8048d4b:   52                      push   %edx
 8048d4c:   53                      push   %ebx
 8048d4d:   51                      push   %ecx
 8048d4e:   e8 cd ff ff ff          call   8048d20 
 8048d53:   83 c4 10                add    $0x10,%esp
 8048d56:   01 c0                   add    %eax,%eax
 8048d58:   eb 1e                   jmp    8048d78 0x58>
 8048d5a:   b8 00 00 00 00          mov    $0x0,%eax
 8048d5f:   39 ca                   cmp    %ecx,%edx
 8048d61:   7d 15                   jge    8048d78 0x58>
 8048d63:   83 ec 04                sub    $0x4,%esp
 8048d66:   56                      push   %esi
 8048d67:   83 c2 01                add    $0x1,%edx
 8048d6a:   52                      push   %edx
 8048d6b:   51                      push   %ecx
 8048d6c:   e8 af ff ff ff          call   8048d20 
 8048d71:   83 c4 10                add    $0x10,%esp
 8048d74:   8d 44 00 01             lea    0x1(%eax,%eax,1),%eax
 8048d78:   83 c4 04                add    $0x4,%esp
 8048d7b:   5b                      pop    %ebx
 8048d7c:   5e                      pop    %esi
 8048d7d:   c3                      ret    

08048d7e :
 8048d7e:   83 ec 1c                sub    $0x1c,%esp
 8048d81:   65 a1 14 00 00 00       mov    %gs:0x14,%eax
 8048d87:   89 44 24 0c             mov    %eax,0xc(%esp)
 8048d8b:   31 c0                   xor    %eax,%eax
 8048d8d:   8d 44 24 08             lea    0x8(%esp),%eax
 8048d91:   50                      push   %eax
 8048d92:   8d 44 24 08             lea    0x8(%esp),%eax
 8048d96:   50                      push   %eax
 8048d97:   68 6f a2 04 08          push   $0x804a26f
 8048d9c:   ff 74 24 2c             pushl  0x2c(%esp)
 8048da0:   e8 7b fa ff ff          call   8048820 <__isoc99_sscanf@plt>  同样的x/s 0x804a26f 得到输入的是%d %d
 8048da5:   83 c4 10                add    $0x10,%esp
 8048da8:   83 f8 02                cmp    $0x2,%eax  输入了太多的数直接爆炸
 8048dab:   75 07                   jne    8048db4 0x36>//bomb
 8048dad:   83 7c 24 04 0e          cmpl   $0xe,0x4(%esp)   第一个数大于14会爆炸
 8048db2:   76 05                   jbe    8048db9 0x3b>//lowOrequ
 8048db4:   e8 bd 03 00 00          call   8049176 
 8048db9:   83 ec 04                sub    $0x4,%esp
 8048dbc:   6a 0e                   push   $0xe
 8048dbe:   6a 00                   push   $0x0
 8048dc0:   ff 74 24 10             pushl  0x10(%esp)  第二个数作为参数,要递归了
 8048dc4:   e8 57 ff ff ff          call   8048d20 
 8048dc9:   83 c4 10                add    $0x10,%esp
 8048dcc:   83 f8 06                cmp    $0x6,%eax
 8048dcf:   75 07                   jne    8048dd8 0x5a>//!=6,bomb
 8048dd1:   83 7c 24 08 06          cmpl   $0x6,0x8(%esp) 第一个数必须要等于6
 8048dd6:   74 05                   je     8048ddd 0x5f>
 8048dd8:   e8 99 03 00 00          call   8049176 //!=6,bomb
 8048ddd:   8b 44 24 0c             mov    0xc(%esp),%eax
 8048de1:   65 33 05 14 00 00 00    xor    %gs:0x14,%eax
 8048de8:   74 05                   je     8048def 0x71>
 8048dea:   e8 a1 f9 ff ff          call   8048790 <__stack_chk_fail@plt>
 8048def:   83 c4 1c                add    $0x1c,%esp
 8048df2:   c3                      ret    

第五关!代码看起来不是很长但其实不是那么容易的,输入的数对应数组中相应索引下表的元素,它们加起来要等于一个值才不会爆炸,答案应该是不唯一的,我找了个和相等的串,OK了
这边GDB开始显示威力了,看不懂的可以在循环开始和末尾设断点,每次查看寄存器,猜一猜哪个寄存器保存什么变量,做什么事等等。
PS:语句不熟练,一开始不知道这数组有多少个元素,print *0xXXXX,print (*0xXXX+4)一个一个试出来的数组元素,好累。
后来网上看到原来print *0x8048...@16就可以看这个地址开始的数组的连续16个元素,不过那位大神是怎么知道共有16 元素的呢?按道理10 足矣...
找到一个恰好的:444427
08048df3 :
 8048df3:   53                      push   %ebx
 8048df4:   83 ec 14                sub    $0x14,%esp
 8048df7:   8b 5c 24 1c             mov    0x1c(%esp),%ebx
 8048dfb:   53                      push   %ebx
 8048dfc:   e8 5f 02 00 00          call   8049060 
 8048e01:   83 c4 10                add    $0x10,%esp
 8048e04:   83 f8 06                cmp    $0x6,%eax
 8048e07:   74 05                   je     8048e0e 0x1b>  到这儿可以看出要求输入一个长度为6string
 8048e09:   e8 68 03 00 00          call   8049176 
 8048e0e:   89 d8                   mov    %ebx,%eax
 8048e10:   83 c3 06                add    $0x6,%ebx
 8048e13:   b9 00 00 00 00          mov    $0x0,%ecx
 8048e18:   0f b6 10                movzbl (%eax),%edx//loop begin一个循环,要求和。。。这里不是很懂edx是怎么更新的,随便输入了一组数,设断点看寄存器发现他就是依次输入的数字...谜
 8048e1b:   83 e2 0f                and    $0xf,%edx
 8048e1e:   03 0c 95 20 a1 04 08    add    0x804a120(,%edx,4),%ecx   又是一个特殊地址,这是数组寻址的套路,ecx保存和,数组中对应下标的数加到ecx里面了
 8048e25:   83 c0 01                add    $0x1,%eax//p *0x804a120@16 show array {2, 10, 6, 1, 12, 16, 9, 3, 4, 7, 14, 5, 11, 8, 15, 13}我喜欢这个语句

 8048e28:   39 d8                   cmp    %ebx,%eax//eax存着6,可以看寄存器得到,也可以理解为它是那个函数的返回值,string 的长度是6嘛
 8048e2a:   75 ec                   jne    8048e18 0x25>//loop
 8048e2c:   83 f9 39                cmp    $0x39,%ecx//let --0x39看来和要求等于57,ok
 8048e2f:   74 05                   je     8048e36 0x43>
 8048e31:   e8 40 03 00 00          call   8049176 
 8048e36:   83 c4 08                add    $0x8,%esp
 8048e39:   5b                      pop    %ebx
 8048e3a:   c3                      ret    

这算是BOSS关了,从上午做到快晚饭的时候。难点在于输入的东西变换了多次,中间没有call bomb,调试就比较难搞(或许是我技巧不够).输入的数与7做差再对应链表,形成一个递减序列才行(渣渣递增还是递减也看不出,又看了寄存器),答案是唯一的:1 6 3 2 4 5
08048e3b :
 8048e3b:   56                      push   %esi
 8048e3c:   53                      push   %ebx
 8048e3d:   83 ec 4c                sub    $0x4c,%esp
 8048e40:   65 a1 14 00 00 00       mov    %gs:0x14,%eax
 8048e46:   89 44 24 44             mov    %eax,0x44(%esp)
 8048e4a:   31 c0                   xor    %eax,%eax
 8048e4c:   8d 44 24 14             lea    0x14(%esp),%eax
 8048e50:   50                      push   %eax
 8048e51:   ff 74 24 5c             pushl  0x5c(%esp)
 8048e55:   e8 41 03 00 00          call   804919b //ha这是输入了
 8048e5a:   83 c4 10                add    $0x10,%esp
 8048e5d:   be 00 00 00 00          mov    $0x0,%esi//initial
 8048e62:   8b 44 b4 0c             mov    0xc(%esp,%esi,4),%eax//guess,n
 8048e66:   83 e8 01                sub    $0x1,%eax
 8048e69:   83 f8 05                cmp    $0x5,%eax//every<=6  为什么要减一再和5比较而不直接和6比较?我也不知道
 8048e6c:   76 05                <= jbe    8048e73 0x38>//b1
 8048e6e:   e8 03 03 00 00          call   8049176   //bomb
 8048e73:   83 c6 01                add    $0x1,%esi
 8048e76:   83 fe 06                cmp    $0x6,%esi//for countloop
 8048e79:   74 1b                   je     8048e96 0x5b>//out!这样就可以出去了,意思大概是6个数都要<=6,不禁想到了穷举,但这是六个数还是算了。。。
 8048e7b:   89 f3                   mov    %esi,%ebx
 8048e7d:   8b 44 9c 0c             mov    0xc(%esp,%ebx,4),%eax
 8048e81:   39 44 b4 08             cmp    %eax,0x8(%esp,%esi,4)
 8048e85:   75 05                   jne    8048e8c 0x51>//b3
 8048e87:   e8 ea 02 00 00          call   8049176   //bomb
 8048e8c:   83 c3 01                add    $0x1,%ebx
 8048e8f:   83 fb 05                cmp    $0x5,%ebx
 8048e92:   7e e9                   jle    8048e7d 0x42>//back 
 8048e94:   eb cc                   jmp    8048e62 0x27>//back  这边的循环看不是很懂,不过试了几个数据也没在这儿爆了,可能是检测输入的是不是6个数吧
 8048e96:   8d 44 24 0c             lea    0xc(%esp),%eax   //newBegin 输入之后从这里开始玩了
 8048e9a:   8d 5c 24 24             lea    0x24(%esp),%ebx  //notknow 80
 8048e9e:   b9 07 00 00 00          mov    $0x7,%ecx//b2
 8048ea3:   89 ca                   mov    %ecx,%edx
 8048ea5:   2b 10                   sub    (%eax),%edx
 8048ea7:   89 10                   mov    %edx,(%eax)  这边把7减去你每个输入的数,再存到原来位置,寄存器看了半天才想到,这边全是寄存器有点难,具体怎么实现也感觉很玄
 8048ea9:   83 c0 04                add    $0x4,%eax//examine
 8048eac:   39 c3                   cmp    %eax,%ebx
 8048eae:   75 f3            traver jne    8048ea3 0x68>
 8048eb0:   bb 00 00 00 00          mov    $0x0,%ebx
 8048eb5:   eb 16                   jmp    8048ecd 0x92>//forward
 8048eb7:   8b 52 08                mov    0x8(%edx),%edx//next node 刚开始不知道node的存储发现直接print node2 也可以看node2的数值哈哈哈{846,354,422,537,501,963}这是六个node的值
 8048eba:   83 c0 01                add    $0x1,%eax
 8048ebd:   39 c8                   cmp    %ecx,%eax  这是在->next找到对应node啊,当时看不懂不过调试也猜出来了
 8048ebf:   75 f6                   jne    8048eb7 0x7c>//loop/b
 8048ec1:   89 54 b4 24             mov    %edx,0x24(%esp,%esi,4)//find
 8048ec5:   83 c3 01                add    $0x1,%ebx
 8048ec8:   83 fb 06                cmp    $0x6,%ebx
 8048ecb:   74 17                   je     8048ee4 0xa9>//forward
 8048ecd:   89 de                   mov    %ebx,%esi  0,0        //newStart
 8048ecf:   8b 4c 9c 0c             mov    0xc(%esp,%ebx,4),%ecx
 8048ed3:   b8 01 00 00 00          mov    $0x1,%eax
 8048ed8:   ba 3c c1 04 08          mov    $0x804c13c,%edx//?? 好奇地x/x了一下,显示node1: 0x4e看来别有洞天了
 8048edd:   83 f9 01                cmp    $0x1,%ecx
 8048ee0:   7f d5                   jg     8048eb7 0x7c> //findNode!
 8048ee2:   eb dd                   jmp    8048ec1 0x86>
 8048ee4:   8b 5c 24 24             mov    0x24(%esp),%ebx   //firstNode
 8048ee8:   8d 44 24 24             lea    0x24(%esp),%eax
 8048eec:   8d 74 24 38             lea    0x38(%esp),%esi
 8048ef0:   89 d9                   mov    %ebx,%ecx
 8048ef2:   8b 50 04                mov    0x4(%eax),%edx    //break
 8048ef5:   89 51 08                mov    %edx,0x8(%ecx)
 8048ef8:   83 c0 04                add    $0x4,%eax
 8048efb:   89 d1                   mov    %edx,%ecx
 8048efd:   39 c6                   cmp    %eax,%esi
 8048eff:   75 f1                   jne    8048ef2 0xb7>  //loop
 8048f01:   c7 42 08 00 00 00 00    movl   $0x0,0x8(%edx)
 8048f08:   be 05 00 00 00          mov    $0x5,%esi
 8048f0d:   8b 43 08                mov    0x8(%ebx),%eax       //last
 8048f10:   8b 00                   mov    (%eax),%eax
 8048f12:   39 03                   cmp    %eax,(%ebx)  好长,有点忘了,好像是看寄存器,发现对应的node值被保存到了一些寄存器,然后循环比较,一言不合就爆炸!
 8048f14:   7d 05                   jge    8048f1b 0xe0>//要>=下一个才不会爆炸,是递减序列
 8048f16:   e8 5b 02 00 00          call   8049176   //bomb
 8048f1b:   8b 5b 08                mov    0x8(%ebx),%ebx//next Node?
 8048f1e:   83 ee 01                sub    $0x1,%esi
 8048f21:   75 ea              !=0  jne    8048f0d 0xd2> //countloop
 8048f23:   8b 44 24 3c             mov    0x3c(%esp),%eax
 8048f27:   65 33 05 14 00 00 00    xor    %gs:0x14,%eax
 8048f2e:   74 05                   je     8048f35 0xfa>
 8048f30:   e8 5b f8 ff ff          call   8048790 <__stack_chk_fail@plt>
 8048f35:   83 c4 44                add    $0x44,%esp
 8048f38:   5b                      pop    %ebx
 8048f39:   5e                      pop    %esi
 8048f3a:   c3                      ret    

做到这儿心力憔悴,隐藏关卡没有再尝试了,于是我可耻地删了相关代码,下面是一些被调用的函数的代码,GDB中disas 函数名也可以看到

08049060 :
 8049060:   8b 54 24 04             mov    0x4(%esp),%edx
 8049064:   80 3a 00                cmpb   $0x0,(%edx)
 8049067:   74 10                   je     8049079 0x19>
 8049069:   b8 00 00 00 00          mov    $0x0,%eax
 804906e:   83 c0 01                add    $0x1,%eax
 8049071:   80 3c 02 00             cmpb   $0x0,(%edx,%eax,1)
 8049075:   75 f7                   jne    804906e 0xe>
 8049077:   f3 c3                   repz ret 
 8049079:   b8 00 00 00 00          mov    $0x0,%eax
 804907e:   c3                      ret    

0804907f :
 804907f:   57                      push   %edi
 8049080:   56                      push   %esi
 8049081:   53                      push   %ebx
 8049082:   8b 5c 24 10             mov    0x10(%esp),%ebx
 8049086:   8b 74 24 14             mov    0x14(%esp),%esi
 804908a:   53                      push   %ebx
 804908b:   e8 d0 ff ff ff          call   8049060 
 8049090:   89 c7                   mov    %eax,%edi
 8049092:   89 34 24                mov    %esi,(%esp)
 8049095:   e8 c6 ff ff ff          call   8049060 
 804909a:   83 c4 04                add    $0x4,%esp
 804909d:   ba 01 00 00 00          mov    $0x1,%edx
 80490a2:   39 c7                   cmp    %eax,%edi
 80490a4:   75 38                   jne    80490de 0x5f>
 80490a6:   0f b6 03                movzbl (%ebx),%eax
 80490a9:   84 c0                   test   %al,%al
 80490ab:   74 1e                   je     80490cb 0x4c>
 80490ad:   3a 06                   cmp    (%esi),%al
 80490af:   74 06                   je     80490b7 0x38>
 80490b1:   eb 1f                   jmp    80490d2 0x53>
 80490b3:   3a 06                   cmp    (%esi),%al
 80490b5:   75 22                   jne    80490d9 0x5a>
 80490b7:   83 c3 01                add    $0x1,%ebx
 80490ba:   83 c6 01                add    $0x1,%esi
 80490bd:   0f b6 03                movzbl (%ebx),%eax
 80490c0:   84 c0                   test   %al,%al
 80490c2:   75 ef                   jne    80490b3 0x34>
 80490c4:   ba 00 00 00 00          mov    $0x0,%edx
 80490c9:   eb 13                   jmp    80490de 0x5f>
 80490cb:   ba 00 00 00 00          mov    $0x0,%edx
 80490d0:   eb 0c                   jmp    80490de 0x5f>
 80490d2:   ba 01 00 00 00          mov    $0x1,%edx
 80490d7:   eb 05                   jmp    80490de 0x5f>
 80490d9:   ba 01 00 00 00          mov    $0x1,%edx
 80490de:   89 d0                   mov    %edx,%eax
 80490e0:   5b                      pop    %ebx
 80490e1:   5e                      pop    %esi
 80490e2:   5f                      pop    %edi
 80490e3:   c3                      ret    



08049176 :
 8049176:   83 ec 18                sub    $0x18,%esp
 8049179:   68 43 a2 04 08          push   $0x804a243
 804917e:   e8 3d f6 ff ff          call   80487c0 @plt>
 8049183:   c7 04 24 4c a2 04 08    movl   $0x804a24c,(%esp)
 804918a:   e8 31 f6 ff ff          call   80487c0 @plt>
 804918f:   c7 04 24 08 00 00 00    movl   $0x8,(%esp)
 8049196:   e8 55 f6 ff ff          call   80487f0 @plt>

0804919b :
 804919b:   83 ec 0c                sub    $0xc,%esp
 804919e:   8b 44 24 14             mov    0x14(%esp),%eax
 80491a2:   8d 50 14                lea    0x14(%eax),%edx
 80491a5:   52                      push   %edx
 80491a6:   8d 50 10                lea    0x10(%eax),%edx
 80491a9:   52                      push   %edx
 80491aa:   8d 50 0c                lea    0xc(%eax),%edx
 80491ad:   52                      push   %edx
 80491ae:   8d 50 08                lea    0x8(%eax),%edx
 80491b1:   52                      push   %edx
 80491b2:   8d 50 04                lea    0x4(%eax),%edx
 80491b5:   52                      push   %edx
 80491b6:   50                      push   %eax
 80491b7:   68 63 a2 04 08          push   $0x804a263
 80491bc:   ff 74 24 2c             pushl  0x2c(%esp)
 80491c0:   e8 5b f6 ff ff          call   8048820 <__isoc99_sscanf@plt>
 80491c5:   83 c4 20                add    $0x20,%esp
 80491c8:   83 f8 05                cmp    $0x5,%eax
 80491cb:   7f 05                   jg     80491d2 0x37>
 80491cd:   e8 a4 ff ff ff          call   8049176 
 80491d2:   83 c4 0c                add    $0xc,%esp
 80491d5:   c3                      ret    



终于做完了,感谢网上实验报告的作者!(可耻地看了一点你们的套路),感谢LJL告知的语句,感谢自己的努力!
./bomb_xxx solution 重定向输入,不用自己一行一行敲密码啦。
深入理解计算机系统bomb_lab_第1张图片

不足之处欢迎指正!

你可能感兴趣的:(计算机系统实践)