zoukankan      html  css  js  c++  java
  • CSAPP 3e: Bomb lab (phase_6)

      这一关很复杂,需要非常耐心。如果感觉容易在循环中绕晕,可以参考一下我最后附上的画图分析法2333,小把戏,不过挺有用的。

      先看函数phase_6:

    00000000004010f4 <phase_6>:
      4010f4:    41 56                    push   %r14
      4010f6:    41 55                    push   %r13
      4010f8:    41 54                    push   %r12
      4010fa:    55                       push   %rbp
      4010fb:    53                       push   %rbx
      4010fc:    48 83 ec 50              sub    $0x50,%rsp
      401100:    49 89 e5                 mov    %rsp,%r13
      401103:    48 89 e6                 mov    %rsp,%rsi
      401106:    e8 51 03 00 00           callq  40145c <read_six_numbers>    ;读取六个数字
      40110b:    49 89 e6                 mov    %rsp,%r14
      40110e:    41 bc 00 00 00 00        mov    $0x0,%r12d
      401114:    4c 89 ed                 mov    %r13,%rbp
      401117:    41 8b 45 00              mov    0x0(%r13),%eax        ;%r13的值在循环过程中有变化,%r13+=4.
      40111b:    83 e8 01                 sub    $0x1,%eax            
      40111e:    83 f8 05                 cmp    $0x5,%eax            ;每一个数字必须小于等于6,(x-1)<=5就是x<=6.
      401121:    76 05                    jbe    401128 <phase_6+0x34>
      401123:    e8 12 03 00 00           callq  40143a <explode_bomb>
      401128:    41 83 c4 01              add    $0x1,%r12d
      40112c:    41 83 fc 06              cmp    $0x6,%r12d
      401130:    74 21                    je     401153 <phase_6+0x5f>;检查完所有6个数字各不相同后跳出此循环。
      401132:    44 89 e3                 mov    %r12d,%ebx
      401135:    48 63 c3                 movslq %ebx,%rax                ;......
      401138:    8b 04 84                 mov    (%rsp,%rax,4),%eax        ;这一段循环操作要求所输入的6个数字中
      40113b:    39 45 00                 cmp    %eax,0x0(%rbp)            ;其中任何两个数字都不能等同,也就是需要输入
      40113e:    75 05                    jne    401145 <phase_6+0x51>    ;各不相同的六个数字。
      401140:    e8 f5 02 00 00           callq  40143a <explode_bomb>    ;
      401145:    83 c3 01                 add    $0x1,%ebx                ;
      401148:    83 fb 05                 cmp    $0x5,%ebx                ;
      40114b:    7e e8                    jle    401135 <phase_6+0x41>    ;......
      40114d:    49 83 c5 04              add    $0x4,%r13
      401151:    eb c1                    jmp    401114 <phase_6+0x20>
      401153:    48 8d 74 24 18           lea    0x18(%rsp),%rsi
      401158:    4c 89 f0                 mov    %r14,%rax                ;%rax=%r14=%rsp,在下面的循环中,%rax+=4.
      40115b:    b9 07 00 00 00           mov    $0x7,%ecx    ;注意这里的7.
      401160:    89 ca                    mov    %ecx,%edx                ;******
      401162:    2b 10                    sub    (%rax),%edx                ;这一段循环用7减去每个值,比如y=7-x,x为输入的
      401164:    89 10                    mov    %edx,(%rax)                ;原来的值,y为新值,新值y覆盖旧值x,存储地址从
      401166:    48 83 c0 04              add    $0x4,%rax                ;第一个数的(%rsp)到最后一个数(%rsp+0x18).
      40116a:    48 39 f0                 cmp    %rsi,%rax                ;
      40116d:    75 f1                    jne    401160 <phase_6+0x6c>    ;******
      40116f:    be 00 00 00 00           mov    $0x0,%esi
      401174:    eb 21                    jmp    401197 <phase_6+0xa3>    ;+++++++++
      401176:    48 8b 52 08              mov    0x8(%rdx),%rdx            ;这一段循环是依据上一段循环之后的新值y,将地址
      40117a:    83 c0 01                 add    $0x1,%eax                ;0x6032d0上的六个地址值依次写入地址(%rsp+0x20+2*%rsi)
      40117d:    39 c8                    cmp    %ecx,%eax                ;%rsi+=4; 例如,如果如果第一个数是1,第二个数是2,则
      40117f:    75 f5                    jne    401176 <phase_6+0x82>    ;(%rsp+0x20)处存储0x6032d0处的地址本身0x6032d0
      401181:    eb 05                    jmp    401188 <phase_6+0x94>    ;(%rsp+0x28)处存储0x6032d0上的第1个地址值0x6032e0
      401183:    ba d0 32 60 00           mov    $0x6032d0,%edx            ;其他值请参考地址0x6032d0处的6个16字节的十六进制数。
      401188:    48 89 54 74 20           mov    %rdx,0x20(%rsp,%rsi,2)    ;eg:第一个16字节的数为(小端法显示)
      40118d:    48 83 c6 04              add    $0x4,%rsi                ;0x6032d0:    4c 01 00 00 01 00 00 00    前8字节
      401191:    48 83 fe 18              cmp    $0x18,%rsi                ;0x6032d8:    e0 32 60 00 00 00 00 00    后8字节
      401195:    74 14                    je     4011ab <phase_6+0xb7>    ;描述为long类型则为
      401197:    8b 0c 34                 mov    (%rsp,%rsi,1),%ecx        ;0x6032d0:    0x000000010000014c        前8字节
      40119a:    83 f9 01                 cmp    $0x1,%ecx                ;0x6032d8:    0x00000000006032e0        后8字节
      40119d:    7e e4                    jle    401183 <phase_6+0x8f>    ;
      40119f:    b8 01 00 00 00           mov    $0x1,%eax                ;
      4011a4:    ba d0 32 60 00           mov    $0x6032d0,%edx            ;
      4011a9:    eb cb                    jmp    401176 <phase_6+0x82>    ;++++++++++
      4011ab:    48 8b 5c 24 20           mov    0x20(%rsp),%rbx
      4011b0:    48 8d 44 24 28           lea    0x28(%rsp),%rax
      4011b5:    48 8d 74 24 50           lea    0x50(%rsp),%rsi
      4011ba:    48 89 d9                 mov    %rbx,%rcx
      4011bd:    48 8b 10                 mov    (%rax),%rdx
      4011c0:    48 89 51 08              mov    %rdx,0x8(%rcx)
      4011c4:    48 83 c0 08              add    $0x8,%rax
      4011c8:    48 39 f0                 cmp    %rsi,%rax
      4011cb:    74 05                    je     4011d2 <phase_6+0xde>
      4011cd:    48 89 d1                 mov    %rdx,%rcx
      4011d0:    eb eb                    jmp    4011bd <phase_6+0xc9>
      4011d2:    48 c7 42 08 00 00 00     movq   $0x0,0x8(%rdx)
      4011d9:    00 
      4011da:    bd 05 00 00 00           mov    $0x5,%ebp
      4011df:    48 8b 43 08              mov    0x8(%rbx),%rax        ;//////
      4011e3:    8b 00                    mov    (%rax),%eax            ;这一段循环比较五次大小,
      4011e5:    39 03                    cmp    %eax,(%rbx)            ;假设地址(%rsp+0x20)存储的值为0x6032d0
      4011e7:    7d 05                    jge    4011ee <phase_6+0xfa>;假设地址(%rsp+0x28)存储的值为0x6032e0
      4011e9:    e8 4c 02 00 00           callq  40143a <explode_bomb>;则需要地址(0x6032d0)处的值x大于等于
      4011ee:    48 8b 5b 08              mov    0x8(%rbx),%rbx        ;地址(0x6032e0)处的值y。否则bomb.
      4011f2:    83 ed 01                 sub    $0x1,%ebp            ;
      4011f5:    75 e8                    jne    4011df <phase_6+0xeb>;//////
      4011f7:    48 83 c4 50              add    $0x50,%rsp
      4011fb:    5b                       pop    %rbx
      4011fc:    5d                       pop    %rbp
      4011fd:    41 5c                    pop    %r12
      4011ff:    41 5d                    pop    %r13
      401201:    41 5e                    pop    %r14
      401203:    c3                       retq   

      在注释中说了输入要求,输入6个各不相同的数,每个数都要小于6,然后每个数都被7减,新值 y 覆盖旧值 x ,用新值进行了后续的操作。

    其中操作重点是对地址0x6032d0处的6个16字节的数的操作。

     用x/12x 0x603200查看0x6032d0处的数据

    0x6032d0:    0x000000010000014c    0x00000000006032e0
    0x6032e0:    0x00000002000000a8    0x00000000006032f0
    0x6032f0:    0x000000030000039c    0x0000000000603300
    0x603300:    0x00000004000002b3    0x0000000000603310
    0x603310:    0x00000005000001dd    0x0000000000603320
    0x603320:    0x00000006000001bb    0x0000000000000000

      注意这是小端法显示,也就是说,0x6032d0处的字节值为4c,0x6032d1处的字节值为01,组合形成014c。

    仔细理解代码之后可以发现,通关要求是:依据被7减之后的新值y,将0x6032d0,0x6032e0等地址值从地址(%rsp+0x20)开始向后写入。然后要求比较大小,比如:

      假设地址(%rsp+0x20)存储的值为0x6032d0,假设地址(%rsp+0x28)存储的值为0x6032e0,则需要地址(0x6032d0)处的值x大于等于,地址(0x6032e0)处的值y。否则bomb。

    也就是说,我们需要比较十六进制值"  (1) 14c  (2) a8  (3) 39c  (4) 2b3  (5) 1dd  (6) 1bb  "这六个数字的大小,从大到小排序。

      然后查看排序后的序号变化"  (3) 39c  (4) 2b3  (5) 1dd  (6) 1bb  (1) 14c  (2) a8  ",十六进制转成十进制进行比较,这里只是便于观察序号变化才没有转换。

      由此可知,被7减后的新值y按顺序为  "3  4  5  6  1  2"

      而被7减之前的旧值x按顺序应为    "4  3  2  1  6  5"

    这就是我们需要按顺序输入的六个各不相同的数字,输入"4 3 2 1 6 5"即可通过本关(中间空格隔开)。

    最后附上我当时这一关的解题手稿,画出逻辑图之后就感觉更加清爽了,更加容易理解思路,省的总在循环上绕死。

      逻辑图笨拙式手稿

      之后是分析手稿

  • 相关阅读:
    二、MyBatis教程之三—多参数的获取方式
    js 编写一道程序题输入长和宽之后点击按钮可弹出长方形面积。
    js 收银元小程序
    文字特效text-shadow HTML+css
    跳动的心 有阴影 跳动
    table框的切换
    jquery选择器是什么?
    随机数Math.random()
    双色球随机数字
    Angularjs 算法//姓名//自定义标签
  • 原文地址:https://www.cnblogs.com/xihuyouyu/p/7544514.html
Copyright © 2011-2022 走看看