LINUX

第二个lab,bomb lab,一个"legendary lab"(原话就是这样),通过看C的源码可以看出共有6个phase,每个phase其实就是一个拆弹的过程:

每一个phase里要求输入一个字符串,如果正确,这个phase的bomb就会被解除,并进入下一个phase。

很显然,phase的难度是逐步增加的,到后面单独一个phase的分析都快赶上lab1的工作量了... 分区写吧,一个一个来。

首先C的源码只是一个空壳,能看出调用phase的过程,但并不能帮助我们了解字符串应该是什么。

[cpp]  view plain  copy
  1. /*************************************************************************** 
  2.  * Dr. Evil's Insidious Bomb, Version 1.1 
  3.  * Copyright 2011, Dr. Evil Incorporated. All rights reserved. 
  4.  * 
  5.  * LICENSE: 
  6.  * 
  7.  * Dr. Evil Incorporated (the PERPETRATOR) hereby grants you (the 
  8.  * VICTIM) explicit permission to use this bomb (the BOMB).  This is a 
  9.  * time limited license, which expires on the death of the VICTIM. 
  10.  * The PERPETRATOR takes no responsibility for damage, frustration, 
  11.  * insanity, bug-eyes, carpal-tunnel syndrome, loss of sleep, or other 
  12.  * harm to the VICTIM.  Unless the PERPETRATOR wants to take credit, 
  13.  * that is.  The VICTIM may not distribute this bomb source code to 
  14.  * any enemies of the PERPETRATOR.  No VICTIM may debug, 
  15.  * reverse-engineer, run "strings" on, decompile, decrypt, or use any 
  16.  * other technique to gain knowledge of and defuse the BOMB.  BOMB 
  17.  * proof clothing may not be worn when handling this program.  The 
  18.  * PERPETRATOR will not apologize for the PERPETRATOR's poor sense of 
  19.  * humor.  This license is null and void where the BOMB is prohibited 
  20.  * by law. 
  21.  ***************************************************************************/  
  22.   
  23. #include <stdio.h>  
  24. #include <stdlib.h>  
  25. #include "support.h"  
  26. include "phases.h"  
  27.   
  28. /*  
  29.  * Note to self: Remember to erase this file so my victims will have no 
  30.  * idea what is going on, and so they will all blow up in a 
  31.  * spectaculary fiendish explosion. -- Dr. Evil  
  32.  */  
  33.   
  34. FILE *infile;  
  35.   
  36. int main(int argc, char *argv[])  
  37. {  
  38.     char *input;  
  39.   
  40.     /* Note to self: remember to port this bomb to Windows and put a  
  41.      * fantastic GUI on it. */  
  42.   
  43.     /* When run with no arguments, the bomb reads its input lines  
  44.      * from standard input. */  
  45.     if (argc == 1) {    
  46.     infile = stdin;  
  47.     }   
  48.   
  49.     /* When run with one argument <file>, the bomb reads from <file>  
  50.      * until EOF, and then switches to standard input. Thus, as you  
  51.      * defuse each phase, you can add its defusing string to <file> and 
  52.      * avoid having to retype it. */  
  53.     else if (argc == 2) {  
  54.     if (!(infile = fopen(argv[1], "r"))) {  
  55.         printf("%s: Error: Couldn't open %s\n", argv[0], argv[1]);  
  56.         exit(8);  
  57.     }  
  58.     }  
  59.   
  60.     /* You can't call the bomb with more than 1 command line argument. */  
  61.     else {  
  62.     printf("Usage: %s [<input_file>]\n", argv[0]);  
  63.     exit(8);  
  64.     }  
  65.   
  66.     /* Do all sorts of secret stuff that makes the bomb harder to defuse. */  
  67.     initialize_bomb();  
  68.   
  69.     printf("Welcome to my fiendish little bomb. You have 6 phases with\n");  
  70.     printf("which to blow yourself up. Have a nice day!\n");  
  71.   
  72.     /* Hmm...  Six phases must be more secure than one phase! */  
  73.     input = read_line();             /* Get input                   */  
  74.     phase_1(input);                  /* Run the phase               */  
  75.     phase_defused();                 /* Drat!  They figured it out! 
  76.                       * Let me know how they did it. */  
  77.     printf("Phase 1 defused. How about the next one?\n");  
  78.   
  79.     /* The second phase is harder.  No one will ever figure out 
  80.      * how to defuse this... */  
  81.     input = read_line();  
  82.     phase_2(input);  
  83.     phase_defused();  
  84.     printf("That's number 2.  Keep going!\n");  
  85.   
  86.     /* I guess this is too easy so far.  Some more complex code will 
  87.      * confuse people. */  
  88.     input = read_line();  
  89.     phase_3(input);  
  90.     phase_defused();  
  91.     printf("Halfway there!\n");  
  92.   
  93.     /* Oh yeah?  Well, how good is your math?  Try on this saucy problem! */  
  94.     input = read_line();  
  95.     phase_4(input);  
  96.     phase_defused();  
  97.     printf("So you got that one.  Try this one.\n");  
  98.       
  99.     /* Round and 'round in memory we go, where we stop, the bomb blows! */  
  100.     input = read_line();  
  101.     phase_5(input);  
  102.     phase_defused();  
  103.     printf("Good work!  On to the next...\n");  
  104.   
  105.     /* This phase will never be used, since no one will get past the 
  106.      * earlier ones.  But just in case, make this one extra hard. */  
  107.     input = read_line();  
  108.     phase_6(input);  
  109.     phase_defused();  
  110.   
  111.     /* Wow, they got it!  But isn't something... missing?  Perhaps 
  112.      * something they overlooked?  Mua ha ha ha ha! */  
  113.       
  114.     return 0;  
  115. }  

C源码告诉我们在每次调用phase函数之前,会先调用read_line()读取字符串

在这门课程的handout材料里,除了C源码外,还有一个可执行文件bomb,这个文件是解除炸弹的关键。

首先用objdump命令获得bomb的汇编代码,可以重定向进入一个txt文件存起来,方便查看

作为小白大量地不了解某汇编操作的作用... 所以备一个x86-64 Intel汇编指令集随时查找也是必要的(所以我的上传资源里多了这么个东西... 

首先,phase_1:

[plain]  view plain  copy
  1. 0000000000400ee0 <phase_1>:  
  2.   400ee0:   48 83 ec 08             sub    $0x8,%rsp  
  3.   400ee4:   be 00 24 40 00          mov    $0x402400,%esi  
  4.   400ee9:   e8 4a 04 00 00          callq  401338 <strings_not_equal>  
  5.   400eee:   85 c0                   test   %eax,%eax  
  6.   400ef0:   74 05                   je     400ef7 <phase_1+0x17>  
  7.   400ef2:   e8 43 05 00 00          callq  40143a <explode_bomb>  
  8.   400ef7:   48 83 c4 08             add    $0x8,%rsp  
  9.   400efb:   c3                      retq     
首先堆栈指针rsp的地址减去8,这是为了规定这一段程序所用的memory大小,到程序结束时可以看到rsp又加回了8表示这个程序已经出栈,这个套路到后面的phase也一样

rsi的低16位被赋予0x402400的值,接着调用一个strings_not_equal函数,从名字上能看出这个函数的作用是比较字符串的

返回值rax被按位做合取运算(test),查阅手册知道test操作会在两个操作数都为0时将Zero Flag设为0,这样才能满足下面的je语句的条件跳过400ef2这个引爆炸弹的函数

看下面strings_not_equal函数的汇编码,发现也确实在字符串相等时返回rax为0,那么我们只要找到在400ee9调用它时能返回0的字符串就好了

参见main函数的汇编码

[plain]  view plain  copy
  1. 400e32: e8 67 06 00 00          callq  40149e <read_line>  
  2. 400e37: 48 89 c7                mov    %rax,%rdi  
  3. 400e3a: e8 a1 00 00 00          callq  400ee0 <phase_1>          #phase_1   

在调用phase_1前,一条第一个参数rdi已经保存了rax,而rax在调用read_line后已经保存了我们输入的字符串地址

第二个参数rsi保存了0x402400这个地址,用x/s命令读取这个地址,发现那里确实存有一个字符串:Border relations with Canada have never been better.

gdb里执行bomb(当然首先给explode_bomb设好断点),输入这个字符串,第一个phase就通过了。

[plain]  view plain  copy
  1. 0000000000401338 <strings_not_equal>:  
  2.   401338:   41 54                   push   %r12  
  3.   40133a:   55                      push   %rbp  
  4.   40133b:   53                      push   %rbx  
  5.   40133c:   48 89 fb                mov    %rdi,%rbx  
  6.   40133f:   48 89 f5                mov    %rsi,%rbp  
  7.   401342:   e8 d4 ff ff ff          callq  40131b <string_length>  
  8.   401347:   41 89 c4                mov    %eax,%r12d  
  9.   40134a:   48 89 ef                mov    %rbp,%rdi  
  10.   40134d:   e8 c9 ff ff ff          callq  40131b <string_length>  
  11.   401352:   ba 01 00 00 00          mov    $0x1,%edx  
  12.   401357:   41 39 c4                cmp    %eax,%r12d  
  13.   40135a:   75 3f                   jne    40139b <strings_not_equal+0x63>  
  14.   40135c:   0f b6 03                movzbl (%rbx),%eax  
  15.   40135f:   84 c0                   test   %al,%al  
  16.   401361:   74 25                   je     401388 <strings_not_equal+0x50>  
  17.   401363:   3a 45 00                cmp    0x0(%rbp),%al  
  18.   401366:   74 0a                   je     401372 <strings_not_equal+0x3a>  
  19.   401368:   eb 25                   jmp    40138f <strings_not_equal+0x57>  
  20.   40136a:   3a 45 00                cmp    0x0(%rbp),%al  
  21.   40136d:   0f 1f 00                nopl   (%rax)  
  22.   401370:   75 24                   jne    401396 <strings_not_equal+0x5e>  
  23.   401372:   48 83 c3 01             add    $0x1,%rbx  
  24.   401376:   48 83 c5 01             add    $0x1,%rbp  
  25.   40137a:   0f b6 03                movzbl (%rbx),%eax  
  26.   40137d:   84 c0                   test   %al,%al  
  27.   40137f:   75 e9                   jne    40136a <strings_not_equal+0x32>  
  28.   401381:   ba 00 00 00 00          mov    $0x0,%edx  
  29.   401386:   eb 13                   jmp    40139b <strings_not_equal+0x63>  
  30.   401388:   ba 00 00 00 00          mov    $0x0,%edx  
  31.   40138d:   eb 0c                   jmp    40139b <strings_not_equal+0x63>  
  32.   40138f:   ba 01 00 00 00          mov    $0x1,%edx  
  33.   401394:   eb 05                   jmp    40139b <strings_not_equal+0x63>  
  34.   401396:   ba 01 00 00 00          mov    $0x1,%edx  
  35.   40139b:   89 d0                   mov    %edx,%eax  
  36.   40139d:   5b                      pop    %rbx  
  37.   40139e:   5d                      pop    %rbp  
  38.   40139f:   41 5c                   pop    %r12  
  39.   4013a1:   c3                      retq     

[plain]  view plain  copy
  1. 000000000040149e <read_line>:  
  2.   40149e:   48 83 ec 08             sub    $0x8,%rsp  
  3.   4014a2:   b8 00 00 00 00          mov    $0x0,%eax  
  4.   4014a7:   e8 4d ff ff ff          callq  4013f9 <skip>  
  5.   4014ac:   48 85 c0                test   %rax,%rax  
  6.   4014af:   75 6e                   jne    40151f <read_line+0x81>  
  7.   4014b1:   48 8b 05 90 22 20 00    mov    0x202290(%rip),%rax        # 603748 <stdin@@GLIBC_2.2.5>  
  8.   4014b8:   48 39 05 a9 22 20 00    cmp    %rax,0x2022a9(%rip)        # 603768 <infile>  
  9.   4014bf:   75 14                   jne    4014d5 <read_line+0x37>  
  10.   4014c1:   bf d5 25 40 00          mov    $0x4025d5,%edi  
  11.   4014c6:   e8 45 f6 ff ff          callq  400b10 <puts@plt>  
  12.   4014cb:   bf 08 00 00 00          mov    $0x8,%edi  
  13.   4014d0:   e8 4b f7 ff ff          callq  400c20 <exit@plt>  
  14.   4014d5:   bf f3 25 40 00          mov    $0x4025f3,%edi  
  15.   4014da:   e8 01 f6 ff ff          callq  400ae0 <getenv@plt>  
  16.   4014df:   48 85 c0                test   %rax,%rax  
  17.   4014e2:   74 0a                   je     4014ee <read_line+0x50>  
  18.   4014e4:   bf 00 00 00 00          mov    $0x0,%edi  
  19.   4014e9:   e8 32 f7 ff ff          callq  400c20 <exit@plt>  
  20.   4014ee:   48 8b 05 53 22 20 00    mov    0x202253(%rip),%rax        # 603748 <stdin@@GLIBC_2.2.5>  
  21.   4014f5:   48 89 05 6c 22 20 00    mov    %rax,0x20226c(%rip)        # 603768 <infile>  
  22.   4014fc:   b8 00 00 00 00          mov    $0x0,%eax  
  23.   401501:   e8 f3 fe ff ff          callq  4013f9 <skip>  
  24.   401506:   48 85 c0                test   %rax,%rax  
  25.   401509:   75 14                   jne    40151f <read_line+0x81>  
  26.   40150b:   bf d5 25 40 00          mov    $0x4025d5,%edi  
  27.   401510:   e8 fb f5 ff ff          callq  400b10 <puts@plt>  
  28.   401515:   bf 00 00 00 00          mov    $0x0,%edi  
  29.   40151a:   e8 01 f7 ff ff          callq  400c20 <exit@plt>  
  30.   40151f:   8b 15 3b 22 20 00       mov    0x20223b(%rip),%edx        # 603760 <num_input_strings>  
  31.   401525:   48 63 c2                movslq %edx,%rax  
  32.   401528:   48 8d 34 80             lea    (%rax,%rax,4),%rsi  
  33.   40152c:   48 c1 e6 04             shl    $0x4,%rsi  
  34.   401530:   48 81 c6 80 37 60 00    add    $0x603780,%rsi  
  35.   401537:   48 89 f7                mov    %rsi,%rdi  
  36.   40153a:   b8 00 00 00 00          mov    $0x0,%eax  
  37.   40153f:   48 c7 c1 ff ff ff ff    mov    $0xffffffffffffffff,%rcx  
  38.   401546:   f2 ae                   repnz scas %es:(%rdi),%al  
  39.   401548:   48 f7 d1                not    %rcx  
  40.   40154b:   48 83 e9 01             sub    $0x1,%rcx  
  41.   40154f:   83 f9 4e                cmp    $0x4e,%ecx  
  42.   401552:   7e 46                   jle    40159a <read_line+0xfc>  
  43.   401554:   bf fe 25 40 00          mov    $0x4025fe,%edi  
  44.   401559:   e8 b2 f5 ff ff          callq  400b10 <puts@plt>  
  45.   40155e:   8b 05 fc 21 20 00       mov    0x2021fc(%rip),%eax        # 603760 <num_input_strings>  
  46.   401564:   8d 50 01                lea    0x1(%rax),%edx  
  47.   401567:   89 15 f3 21 20 00       mov    %edx,0x2021f3(%rip)        # 603760 <num_input_strings>  
  48.   40156d:   48 98                   cltq     
  49.   40156f:   48 6b c0 50             imul   $0x50,%rax,%rax  
  50.   401573:   48 bf 2a 2a 2a 74 72    movabs $0x636e7572742a2a2a,%rdi  
  51.   40157a:   75 6e 63   
  52.   40157d:   48 89 b8 80 37 60 00    mov    %rdi,0x603780(%rax)  
  53.   401584:   48 bf 61 74 65 64 2a    movabs $0x2a2a2a64657461,%rdi  
  54.   40158b:   2a 2a 00   
  55.   40158e:   48 89 b8 88 37 60 00    mov    %rdi,0x603788(%rax)  
  56.   401595:   e8 a0 fe ff ff          callq  40143a <explode_bomb>  
  57.   40159a:   83 e9 01                sub    $0x1,%ecx  
  58.   40159d:   48 63 c9                movslq %ecx,%rcx  
  59.   4015a0:   48 63 c2                movslq %edx,%rax  
  60.   4015a3:   48 8d 04 80             lea    (%rax,%rax,4),%rax  
  61.   4015a7:   48 c1 e0 04             shl    $0x4,%rax  
  62.   4015ab:   c6 84 01 80 37 60 00    movb   $0x0,0x603780(%rcx,%rax,1)  
  63.   4015b2:   00   
  64.   4015b3:   83 c2 01                add    $0x1,%edx  
  65.   4015b6:   89 15 a4 21 20 00       mov    %edx,0x2021a4(%rip)        # 603760 <num_input_strings>  
  66.   4015bc:   48 89 f0                mov    %rsi,%rax  
  67.   4015bf:   48 83 c4 08             add    $0x8,%rsp  
  68.   4015c3:   c3                      retq   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值