实验资源下载地址:csapp.cs.cmu.edu/3e/labs.html 请先查看writeup
解压后
当我们运行bomb时,发现该程序要求我们输入行,如果输入错误,程序就会返回BOOM!!!提示我们失败了.
所以我们的目标是输入正确的行.以解开bomb程序.
实验前先详细阅读bomb.c
//bomb.c
/***************************************************************************
* 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.
***************************************************************************/
/***************************************************************************
*邪恶博士的阴险炸弹,1.1版
*版权所有2011,邪恶博士公司。保留所有权利。
*
*许可证:
*
邪恶博士公司(肇事者)特此授予您(受害者)使用此炸弹(炸弹)的明确许可。这是一个有时间限制的许可证,在受害者死亡时到期。
肇事者对受害者的伤害、沮丧、精神错乱、bug、腕管综合征、睡眠不足或其他伤害不承担任何责任。除非肇事者想邀功,也就是说。
受害者不得将此炸弹源码分发给肇事者的任何敌人。任何受害者不得调试、逆向工程、运行“字符串”、反编译、解密或使用任何其他技
术来获得炸弹的知识并拆除炸弹。
处理本程序时不得穿着防爆服。肇事者不会为肇事者的幽默感差道歉。在法律禁止使用炸弹的情况下,本许可证无效。
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#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. */
/*自我提醒:记得把这个炸弹移植到Windows上,并在上面放一个很棒的GUI。*/
/* When run with no arguments, the bomb reads its input lines
* from standard input. */
/*当不带参数运行时,炸弹会从标准输入中读取其输入行。*/
if (argc == 1) {
infile = stdin;
}
/* When run with one argument <file>, the bomb reads from <file>
* until EOF, and then switches to standard input. Thus, as you
* defuse each phase, you can add its defusing string to <file> and
* avoid having to retype it. */
/*当使用一个参数<file>运行时,炸弹从<file>读取直到EOF,然后切换到标准输入。
因此,当您拆除每个阶段时,您可以将其拆除字符串添加到<file>并避免重新键入它。*/
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. */
/*您不能使用超过1个命令行参数调用炸弹。*/
else {
printf("Usage: %s [<input_file>]\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! */
/*哇,他们明白了!但是不是有什么东西……丢失了吗?也许他们忽略了什么?mua哈哈哈哈哈!*/
return 0;
}
bomb文件是一个bomb.c编译后的程序,我们由于缺失一些头文件,所以无法编译bomb.c
让我们反编译bomb,以理清程序的具体实现,从而分析出我们要输入的行:
objdump -d bomb > bomb.txt
阶段一函数,我们可以看到在call strings_not_equal之前传入了一个参数 0x402400我们不知道这是什么,接着看.
call strings_not_equal之后 传入的%esi和%rsi是同一个寄存器,所以参数 0x402400被传到%rbp了,下面我们又看到(%rbp)很明显了,加载了0x402400,也就是0x402400是一个地址,此时我们希望在运行bomb的时候看一下0x402400地址上是什么东西.这里自然就想到书中和实验网页writeup中提到的gdb调试器了.
gdb bomb
加个断点,只需要断在%esi接收到参数0x402400之后即可
(gdb)b strings_not_equal
以字符串形式输出地址上的数据:
(gdb)x/s 0x402400
关于gdb的命令,自己在网上查着,每个用一用就会了.
不查不知道一查吓一跳,原来是个字符串啊.我们再联想一下这个函数的名字strings_not_equal.不难猜到这是一个比较字符串的函数.我们把查到的字符串保存在a.txt文件中,然后传入bomb,这里先按ctrl+d退出gdb在运行bomb方便一些.
./bomb a.txt
解开阶段一.