CSAPP 3e: Bomb lab (phase_5)


 

調出phase_5函數:

0000000000401062 <phase_5>:
  401062:    53                       push   %rbx
  401063:    48 83 ec 20              sub    $0x20,%rsp
  401067:    48 89 fb                 mov    %rdi,%rbx
  40106a:    64 48 8b 04 25 28 00     mov    %fs:0x28,%rax    ;此處搞不懂
  401071:    00 00 
  401073:    48 89 44 24 18           mov    %rax,0x18(%rsp)
  401078:    31 c0                    xor    %eax,%eax
  40107a:    e8 9c 02 00 00           callq  40131b <string_length>    ;檢測字符串長度
  40107f:    83 f8 06                 cmp    $0x6,%eax
  401082:    74 4e                    je     4010d2 <phase_5+0x70>    ;如果字符串長度不為6,bomb。
  401084:    e8 b1 03 00 00           callq  40143a <explode_bomb>
  401089:    eb 47                    jmp    4010d2 <phase_5+0x70>
  40108b:    0f b6 0c 03              movzbl (%rbx,%rax,1),%ecx    ;%ecx=%eax+%ebx。
  40108f:    88 0c 24                 mov    %cl,(%rsp)        ;取%ecx得低8位,相當於%ecx & 0xff,並將值放入內存地址(%rsp)中
  401092:    48 8b 14 24              mov    (%rsp),%rdx
  401096:    83 e2 0f                 and    $0xf,%edx        ;聯系上幾行,相當於 %ecx & 0xf,並將運算值放入寄存器%edx。
  401099:    0f b6 92 b0 24 40 00     movzbl 0x4024b0(%rdx),%edx    ;根據%edx的值,從內存地址0x4024b0中將數據讀入%edx中
  4010a0:    88 54 04 10              mov    %dl,0x10(%rsp,%rax,1);再將讀入的數據轉移轉移到內存地址(%rsp+0x10+%rax)中
  4010a4:    48 83 c0 01              add    $0x1,%rax    ;%rax+=1
  4010a8:    48 83 f8 06              cmp    $0x6,%rax    ;當rax=6跳出循環,這里注意到6等於所需輸入的字符串長度
  4010ac:    75 dd                    jne    40108b <phase_5+0x29>
  4010ae:    c6 44 24 16 00           movb   $0x0,0x16(%rsp)    ;由之前關卡可知strings_not_equal函數的運行機制
  4010b3:    be 5e 24 40 00           mov    $0x40245e,%esi    ;%esi存儲答案字符串首地址
  4010b8:    48 8d 7c 24 10           lea    0x10(%rsp),%rdi    ;%rdi存儲被檢測字符串首地址。
  4010bd:    e8 76 02 00 00           callq  401338 <strings_not_equal>
  4010c2:    85 c0                    test   %eax,%eax    ;字符串一一符合則完成破解。
  4010c4:    74 13                    je     4010d9 <phase_5+0x77>    ;這一關重點是在0x4024b0與0x40245e兩個字符串之間的關系。
  4010c6:    e8 6f 03 00 00           callq  40143a <explode_bomb>
  4010cb:    0f 1f 44 00 00           nopl   0x0(%rax,%rax,1)
  4010d0:    eb 07                    jmp    4010d9 <phase_5+0x77>
  4010d2:    b8 00 00 00 00           mov    $0x0,%eax
  4010d7:    eb b2                    jmp    40108b <phase_5+0x29>
  4010d9:    48 8b 44 24 18           mov    0x18(%rsp),%rax
  4010de:    64 48 33 04 25 28 00     xor    %fs:0x28,%rax
  4010e5:    00 00 
  4010e7:    74 05                    je     4010ee <phase_5+0x8c>
  4010e9:    e8 42 fa ff ff           callq  400b30 <__stack_chk_fail@plt>
  4010ee:    48 83 c4 20              add    $0x20,%rsp
  4010f2:    5b                       pop    %rbx
  4010f3:    c3                       retq   

  主要內容在注釋中貼出來了,解讀如下:

  這一關要求輸入一個長度為6的字符串,但是字符串的內容與strings_not_equal函數中%esi存儲的地址的字符串不一樣,可以看到在這個函數之前有一個轉換過程,而且%edi存儲的地址是%rsp數據段的地址,這是要點。

  轉換過程是取得字符的最低4位,值在0-15之間,通過這個值來調取地址0x4024b0 中的字符,並存入%rsp數據段中,需要%rsp數據段中的字符串與%rsi總的字符串相同,才可以通過這一關。

  地址0x4024b0中的字符串:m a d u i e r s n f o t v b y l  (空格分開只是為了便於查看)

  地址%esi=0x40245e中的字符串:"flyers"

  觀察這兩個字符串的兩兩對應關系,要從混亂字符串中選出字符組成"flyers",需要選出的字符序號(從0開始)為 “9,15,4,5,6,7”,十六進制則是"9,f,e,5,6,7"

所以只要輸入字符串中對應位的字符的最低4位的數值等於"9,f,e,5,6,7",即可通過這一關。

  比如:通過查看ASCII值,可以得到

  字符最低位值:9  f  e  5  6  7

  對應可選字符:i  o  n  e  f  g

         y       u  v  w

 

  所以字符串"ionefg"是正確答案。(也可以是"yonefg"或者"yonuvw"都可以,只要字符串滿足最低位序號的要求均可以。)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM