CSAPP 3e: Bomb lab (secret_phase)

來源:互聯網
上載者:User

標籤:秘密   lod   font   char   結束   http   str   nop   .com   

  這是秘密關卡,需要通過主動調用secret_phase函數才能觸發,可以通過call secret 或者jump *0x地址來調用。

  貼出函數:(fun7函數部分沒有注釋,後邊續上了手寫的圖來解析這個函數了)

0000000000401204 <fun7>:  401204:    48 83 ec 08              sub    $0x8,%rsp  401208:    48 85 ff                 test   %rdi,%rdi          40120b:    74 2b                    je     401238 <fun7+0x34>;如果%rdi==0,ret。  40120d:    8b 17                    mov    (%rdi),%edx  40120f:    39 f2                    cmp    %esi,%edx  401211:    7e 0d                    jle    401220 <fun7+0x1c>  401213:    48 8b 7f 08              mov    0x8(%rdi),%rdi  401217:    e8 e8 ff ff ff           callq  401204 <fun7>  40121c:    01 c0                    add    %eax,%eax  40121e:    eb 1d                    jmp    40123d <fun7+0x39>  401220:    b8 00 00 00 00           mov    $0x0,%eax  401225:    39 f2                    cmp    %esi,%edx  401227:    74 14                    je     40123d <fun7+0x39>  401229:    48 8b 7f 10              mov    0x10(%rdi),%rdi  40122d:    e8 d2 ff ff ff           callq  401204 <fun7>  401232:    8d 44 00 01              lea    0x1(%rax,%rax,1),%eax  401236:    eb 05                    jmp    40123d <fun7+0x39>  401238:    b8 ff ff ff ff           mov    $0xffffffff,%eax  40123d:    48 83 c4 08              add    $0x8,%rsp  401241:    c3                       retq   0000000000401242 <secret_phase>:  401242:    53                       push   %rbx  401243:    e8 56 02 00 00           callq  40149e <read_line>;傳回值%rax為所輸入字串的首地址  401248:    ba 0a 00 00 00           mov    $0xa,%edx    ;strtol函數參數,令函數將字串讀取為10進位  40124d:    be 00 00 00 00           mov    $0x0,%esi    ;NULL,strtol函數參數  401252:    48 89 c7                 mov    %rax,%rdi    ;字串首地址,作為參數  401255:    e8 76 f9 ff ff           callq  400bd0 <[email protected]>  40125a:    48 89 c3                 mov    %rax,%rbx    ;%rax為strtol函數傳回值,是一個long int型數字  40125d:    8d 40 ff                 lea    -0x1(%rax),%eax    ;要求(%rax-1)值小於0x3e8 (1000)。  401260:    3d e8 03 00 00           cmp    $0x3e8,%eax  401265:    76 05                    jbe    40126c <secret_phase+0x2a>  401267:    e8 ce 01 00 00           callq  40143a <explode_bomb>  40126c:    89 de                    mov    %ebx,%esi        ;%esi等於strtol函數返回的那個long int型數字  40126e:    bf f0 30 60 00           mov    $0x6030f0,%edi    ;fun7函數用到的一個地址  401273:    e8 8c ff ff ff           callq  401204 <fun7>  401278:    83 f8 02                 cmp    $0x2,%eax        ;要求fun7函數傳回值為2,否則Bomb.  40127b:    74 05                    je     401282 <secret_phase+0x40>  40127d:    e8 b8 01 00 00           callq  40143a <explode_bomb>  401282:    bf 38 24 40 00           mov    $0x402438,%edi  401287:    e8 84 f8 ff ff           callq  400b10 <[email protected]>  40128c:    e8 33 03 00 00           callq  4015c4 <phase_defused>  401291:    5b                       pop    %rbx  401292:    c3                       retq     401293:    90                       nop  401294:    90                       nop  401295:    90                       nop  401296:    90                       nop  401297:    90                       nop  401298:    90                       nop  401299:    90                       nop  40129a:    90                       nop  40129b:    90                       nop  40129c:    90                       nop  40129d:    90                       nop  40129e:    90                       nop  40129f:    90                       nop

  先研究secret_phase函數,它先調用了read_line函數,通過gdb追蹤運行發現,運行read_line函數後,%rax與%rsi的值都是所輸入字串的首地址,%rcx為所輸入字串的長度。

在call read_line之後的三行都是對調用strtol函數進行參數賦值,mov $0xa,%edx指示strtol函數將字串轉換成十進位值輸出。對strtol函數的用法是(具體的百度一下你就知道):

/**************************************************************/
表標頭檔: #include <stdlib.h>
定義函數: long int strtol(const char *nptr, char **endptr, int base)
函數說明: strtol()會將參數nptr字串根據參數base來轉換成長整型數。參數base範圍從2至36,或0。參數base代表採用的進位方式,如base值為10則採用10進位(字串以10進位表示),若base值為16則採用16進位(字串以16進位表示)。當base值為0時則是採用10進位做轉換,但遇到如‘‘0x‘‘前置字元則會使用16進位做轉換。一開始strtol()會掃描參數nptr字串,跳過前面的空白字元,直到遇上數字或正負符號才開始做轉換,再遇到非數字或字串結束時(‘‘\0‘‘)結束轉換,並將結果返回。若參數endptr不為NULL,則會將遇到不合條件而終止的nptr中的字元指標由endptr返回。

傳回值:   返迴轉換後的長整型數,否則返回ERANGE並將錯誤碼存入errno中

比如:

     char a[] = "100";
     char b[] = "100";
     char c[] = "ffff";
     printf("a = %d\n", strtol(a, NULL, 10)); //100
     printf("b = %d\n", strtol(b, NULL, 2));    //4
     printf("c = %d\n", strtol(c, NULL, 16)); //65535

/*****************************************************************/

  這裡將輸入的字串轉換成了十進位值,然後在func7函數中校正所輸入的值是否正確,具體過程則需要研究fun7函數。

注意:裡路徑C中少些了一個call fun7;

  在func7中,%rsi的值一直都是所輸入的被轉換之後的值。

 按照圖中所示路徑b--->c--->d 計算:

  第一次 b:  %edx=(%rdi); %rdi的值為0x6030f0; 所以%edx的值為0x24

說明%rsi小於0x24;(%rsi的值就是輸入且被轉換之後的值)

  第二次 c:   %rdi=(%rdi+0x8); 得%rdi==0x603110;然後調用了fun7自身,%edx=(%rdi); 此時%edx的值為 0x8;

說明%rsi雖然小於0x24,卻不等於0x8,而大於0x8;

  第三次 d:  注意此時%rdi值為0x603110, 然後%rdi=(%rdi+0x10); 新的%rdi的值為0x603150; 之後調用自身fun7,%edx=(%rdi); %edx值為0x16;

此時可以逐步返回了,說明%rsi的值就是0x16,即10進位的22;

 

這樣,read_line函數中輸入的字串被轉換為10進位值後應該為22;所以,"22"就是正確答案。

"22"被轉換成十進位後值為22,即0x16,符合在fun7函數中的計算結果。

驗證:(call調用出錯,所以用jump 跳轉調用,0x401242是secret_phase函數入口)

 

Wow!

I‘ve defused the secret stage! 

Congraduations!!!

CSAPP 3e: Bomb lab (secret_phase)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.