CS:APP BombLab详解

BombLab 实验详解

2024/10/22

一、文件/工具

  • bomb38(可执行文件名)
  • bomb.c
  • gdb

二、准备工作

1. 生成反汇编文件

执行:

objdump-d bomb38 > bomb38.asm

获得反汇编文件bomb38.asm,便于整体阅读。

2. 阅读bomb.c

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 <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. */
    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 [<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! */
    
    return 0;
}

通过阅读bomb.c,可以知道拆弹过程共分7阶段,phase_1~6以及最后的隐藏阶段。每一阶段系统从输入中读一行字符串,输入可以是标准输入stdin或从命令行参数中指定的文件中获得。我们在程序目录下新建一个文本文档solution.txt作为运行时的命令行参数,每解开一阶段,将该阶段的答案追加到其中。注意,将每一题的答案写入solution.txt后,行尾需要有一个换行符。

3. 用到的C库函数

phase_1~6中用到的不熟悉的C库函数有sscanfstrtol

  • sscanf

    声明

    int sscanf(const char *str, const char *format, ...)
    

    参数

    sscanfscanf相似,只是scanf的字符串源为标准输入,而sscanf的字符串源是传入的第一个参数str

    第二个参数为解读格式,后面的附加参数即为解读后的变量要存储的地址。

    返回值

    如果成功,该函数返回成功匹配和赋值的个数,否则返回EOF

  • strtol(即string to long)

    声明

    long strtol(const char *str, char **endptr, int base)
    

    参数

    str为要转换成long类型的字符串,endptr的值由函数指向str中有效数字后的下一个字符(如果字符串是纯数字*endptr == '\0'),base决定把str转为几进制。

    返回值

    返回转换成的long类型值。如果输入字符串不是纯数字,返回0

4 . 常用gdb命令

参考yanbinghu.com/2019/04/20/41283.html

5. 约定

把寄存器%rdi,%rsi,…中存放的变量依次称为arg1,arg2,…。

三、实验过程

phase_1

00000000000015e7 <phase_1>:
    15e7:	f3 0f 1e fa          	endbr64 
    15eb:	48 83 ec 08          	sub    $0x8,%rsp				# 维护栈帧
    15ef:	48 8d 35 5a 1b 00 00 	lea    0x1b5a
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值