第二个lab,bomb lab,一个"legendary lab"(原话就是这样),通过看C的源码可以看出共有6个phase,每个phase其实就是一个拆弹的过程:
每一个phase里要求输入一个字符串,如果正确,这个phase的bomb就会被解除,并进入下一个phase。
很显然,phase的难度是逐步增加的,到后面单独一个phase的分析都快赶上lab1的工作量了... 分区写吧,一个一个来。
首先C的源码只是一个空壳,能看出调用phase的过程,但并不能帮助我们了解字符串应该是什么。
/***************************************************************************
* Dr. Evil's Insidious Bomb, Version 1.1
* Copyright 2011, Dr. Evil Incorporated. All rights reserved.
*
* LICENSE:
*
* Dr. Evil Incorporated (the PERPETRATOR) hereby grants you (the
* VICTIM) explicit permission to use this bomb (the BOMB). This is a
* time limited license, which expires on the death of the VICTIM.
* The PERPETRATOR takes no responsibility for damage, frustration,
* insanity, bug-eyes, carpal-tunnel syndrome, loss of sleep, or other
* harm to the VICTIM. Unless the PERPETRATOR wants to take credit,
* that is. The VICTIM may not distribute this bomb source code to
* any enemies of the PERPETRATOR. No VICTIM may debug,
* reverse-engineer, run "strings" on, decompile, decrypt, or use any
* other technique to gain knowledge of and defuse the BOMB. BOMB
* proof clothing may not be worn when handling this program. The
* PERPETRATOR will not apologize for the PERPETRATOR's poor sense of
* humor. This license is null and void where the BOMB is prohibited
* by law.
***************************************************************************/
#include
#include
#include "support.h"
include "phases.h"
/*
* Note to self: Remember to erase this file so my victims will have no
* idea what is going on, and so they will all blow up in a
* spectaculary fiendish explosion. -- Dr. Evil
*/
FILE *infile;
int main(int argc, char *argv[])
{
char *input;
/* Note to self: remember to port this bomb to Windows and put a
* fantastic GUI on it. */
/* When run with no arguments, the bomb reads its input lines
* from standard input. */
if (argc == 1) {
infile = stdin;
}
/* When run with one argument , the bomb reads from
* until EOF, and then switches to standard input. Thus, as you
* defuse each phase, you can add its defusing string to and
* avoid having to retype it. */
else if (argc == 2) {
if (!(infile = fopen(argv[1], "r"))) {
printf("%s: Error: Couldn't open %s\n", argv[0], argv[1]);
exit(8);
}
}
/* You can't call the bomb with more than 1 command line argument. */
else {
printf("Usage: %s []\n", argv[0]);
exit(8);
}
/* Do all sorts of secret stuff that makes the bomb harder to defuse. */
initialize_bomb();
printf("Welcome to my fiendish little bomb. You have 6 phases with\n");
printf("which to blow yourself up. Have a nice day!\n");
/* Hmm... Six phases must be more secure than one phase! */
input = read_line(); /* Get input */
phase_1(input); /* Run the phase */
phase_defused(); /* Drat! They figured it out!
* Let me know how they did it. */
printf("Phase 1 defused. How about the next one?\n");
/* The second phase is harder. No one will ever figure out
* how to defuse this... */
input = read_line();
phase_2(input);
phase_defused();
printf("That's number 2. Keep going!\n");
/* I guess this is too easy so far. Some more complex code will
* confuse people. */
input = read_line();
phase_3(input);
phase_defused();
printf("Halfway there!\n");
/* Oh yeah? Well, how good is your math? Try on this saucy problem! */
input = read_line();
phase_4(input);
phase_defused();
printf("So you got that one. Try this one.\n");
/* Round and 'round in memory we go, where we stop, the bomb blows! */
input = read_line();
phase_5(input);
phase_defused();
printf("Good work! On to the next...\n");
/* This phase will never be used, since no one will get past the
* earlier ones. But just in case, make this one extra hard. */
input = read_line();
phase_6(input);
phase_defused();
/* Wow, they got it! But isn't something... missing? Perhaps
* something they overlooked? Mua ha ha ha ha! */
return 0;
}
C源码告诉我们在每次调用phase函数之前,会先调用read_line()读取字符串
在这门课程的handout材料里,除了C源码外,还有一个可执行文件bomb,这个文件是解除炸弹的关键。
首先用objdump命令获得bomb的汇编代码,可以重定向进入一个txt文件存起来,方便查看
作为小白大量地不了解某汇编操作的作用... 所以备一个x86-64 Intel汇编指令集随时查找也是必要的(所以我的上传资源里多了这么个东西...
0000000000400ee0 :
400ee0: 48 83 ec 08 sub $0x8,%rsp
400ee4: be 00 24 40 00 mov $0x402400,%esi
400ee9: e8 4a 04 00 00 callq 401338
400eee: 85 c0 test %eax,%eax
400ef0: 74 05 je 400ef7
400ef2: e8 43 05 00 00 callq 40143a
400ef7: 48 83 c4 08 add $0x8,%rsp
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函数的汇编码
400e32: e8 67 06 00 00 callq 40149e
400e37: 48 89 c7 mov %rax,%rdi
400e3a: e8 a1 00 00 00 callq 400ee0 #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就通过了。
0000000000401338 :
401338: 41 54 push %r12
40133a: 55 push %rbp
40133b: 53 push %rbx
40133c: 48 89 fb mov %rdi,%rbx
40133f: 48 89 f5 mov %rsi,%rbp
401342: e8 d4 ff ff ff callq 40131b
401347: 41 89 c4 mov %eax,%r12d
40134a: 48 89 ef mov %rbp,%rdi
40134d: e8 c9 ff ff ff callq 40131b
401352: ba 01 00 00 00 mov $0x1,%edx
401357: 41 39 c4 cmp %eax,%r12d
40135a: 75 3f jne 40139b
40135c: 0f b6 03 movzbl (%rbx),%eax
40135f: 84 c0 test %al,%al
401361: 74 25 je 401388
401363: 3a 45 00 cmp 0x0(%rbp),%al
401366: 74 0a je 401372
401368: eb 25 jmp 40138f
40136a: 3a 45 00 cmp 0x0(%rbp),%al
40136d: 0f 1f 00 nopl (%rax)
401370: 75 24 jne 401396
401372: 48 83 c3 01 add $0x1,%rbx
401376: 48 83 c5 01 add $0x1,%rbp
40137a: 0f b6 03 movzbl (%rbx),%eax
40137d: 84 c0 test %al,%al
40137f: 75 e9 jne 40136a
401381: ba 00 00 00 00 mov $0x0,%edx
401386: eb 13 jmp 40139b
401388: ba 00 00 00 00 mov $0x0,%edx
40138d: eb 0c jmp 40139b
40138f: ba 01 00 00 00 mov $0x1,%edx
401394: eb 05 jmp 40139b
401396: ba 01 00 00 00 mov $0x1,%edx
40139b: 89 d0 mov %edx,%eax
40139d: 5b pop %rbx
40139e: 5d pop %rbp
40139f: 41 5c pop %r12
4013a1: c3 retq
000000000040149e :
40149e: 48 83 ec 08 sub $0x8,%rsp
4014a2: b8 00 00 00 00 mov $0x0,%eax
4014a7: e8 4d ff ff ff callq 4013f9
4014ac: 48 85 c0 test %rax,%rax
4014af: 75 6e jne 40151f
4014b1: 48 8b 05 90 22 20 00 mov 0x202290(%rip),%rax # 603748
4014b8: 48 39 05 a9 22 20 00 cmp %rax,0x2022a9(%rip) # 603768
4014bf: 75 14 jne 4014d5
4014c1: bf d5 25 40 00 mov $0x4025d5,%edi
4014c6: e8 45 f6 ff ff callq 400b10
4014cb: bf 08 00 00 00 mov $0x8,%edi
4014d0: e8 4b f7 ff ff callq 400c20
4014d5: bf f3 25 40 00 mov $0x4025f3,%edi
4014da: e8 01 f6 ff ff callq 400ae0
4014df: 48 85 c0 test %rax,%rax
4014e2: 74 0a je 4014ee
4014e4: bf 00 00 00 00 mov $0x0,%edi
4014e9: e8 32 f7 ff ff callq 400c20
4014ee: 48 8b 05 53 22 20 00 mov 0x202253(%rip),%rax # 603748
4014f5: 48 89 05 6c 22 20 00 mov %rax,0x20226c(%rip) # 603768
4014fc: b8 00 00 00 00 mov $0x0,%eax
401501: e8 f3 fe ff ff callq 4013f9
401506: 48 85 c0 test %rax,%rax
401509: 75 14 jne 40151f
40150b: bf d5 25 40 00 mov $0x4025d5,%edi
401510: e8 fb f5 ff ff callq 400b10
401515: bf 00 00 00 00 mov $0x0,%edi
40151a: e8 01 f7 ff ff callq 400c20
40151f: 8b 15 3b 22 20 00 mov 0x20223b(%rip),%edx # 603760
401525: 48 63 c2 movslq %edx,%rax
401528: 48 8d 34 80 lea (%rax,%rax,4),%rsi
40152c: 48 c1 e6 04 shl $0x4,%rsi
401530: 48 81 c6 80 37 60 00 add $0x603780,%rsi
401537: 48 89 f7 mov %rsi,%rdi
40153a: b8 00 00 00 00 mov $0x0,%eax
40153f: 48 c7 c1 ff ff ff ff mov $0xffffffffffffffff,%rcx
401546: f2 ae repnz scas %es:(%rdi),%al
401548: 48 f7 d1 not %rcx
40154b: 48 83 e9 01 sub $0x1,%rcx
40154f: 83 f9 4e cmp $0x4e,%ecx
401552: 7e 46 jle 40159a
401554: bf fe 25 40 00 mov $0x4025fe,%edi
401559: e8 b2 f5 ff ff callq 400b10
40155e: 8b 05 fc 21 20 00 mov 0x2021fc(%rip),%eax # 603760
401564: 8d 50 01 lea 0x1(%rax),%edx
401567: 89 15 f3 21 20 00 mov %edx,0x2021f3(%rip) # 603760
40156d: 48 98 cltq
40156f: 48 6b c0 50 imul $0x50,%rax,%rax
401573: 48 bf 2a 2a 2a 74 72 movabs $0x636e7572742a2a2a,%rdi
40157a: 75 6e 63
40157d: 48 89 b8 80 37 60 00 mov %rdi,0x603780(%rax)
401584: 48 bf 61 74 65 64 2a movabs $0x2a2a2a64657461,%rdi
40158b: 2a 2a 00
40158e: 48 89 b8 88 37 60 00 mov %rdi,0x603788(%rax)
401595: e8 a0 fe ff ff callq 40143a
40159a: 83 e9 01 sub $0x1,%ecx
40159d: 48 63 c9 movslq %ecx,%rcx
4015a0: 48 63 c2 movslq %edx,%rax
4015a3: 48 8d 04 80 lea (%rax,%rax,4),%rax
4015a7: 48 c1 e0 04 shl $0x4,%rax
4015ab: c6 84 01 80 37 60 00 movb $0x0,0x603780(%rcx,%rax,1)
4015b2: 00
4015b3: 83 c2 01 add $0x1,%edx
4015b6: 89 15 a4 21 20 00 mov %edx,0x2021a4(%rip) # 603760
4015bc: 48 89 f0 mov %rsi,%rax
4015bf: 48 83 c4 08 add $0x8,%rsp
4015c3: c3 retq