csapp深入理解计算机系统 bomb lab(1)phase_1

实验目的:进一步了解机器级代码,提高汇编语言、调试器和逆向工程等方面原理与技能的掌握。

实验环境:C、linux

实验获取:进入csapp官网,点击linux/x86-64 binary bomb下载实验压缩包。

实验说明:一共有6个关卡,每个关卡可以输入一串字符,只有输入正确才能拆出炸弹。

只有可执行程序,不知道六个关卡函数具体的代码都是什么。

可以应用反汇编技术把可执行程序转化为汇编程序。通过阅读汇编程序,推断出程序的具体作用,从而给出正确的密码输入。

​​​​​​s​​​​CS:APP3e, Bryant and O'Hallaron

csapp深入理解计算机系统 bomb lab(1)phase_1_第1张图片

解压:tar -xvf bomb.tar

从bomb.c可以看出phase_1接受一个输入,需要反汇编推测phase_1对input做了什么处理。

csapp深入理解计算机系统 bomb lab(1)phase_1_第2张图片

反汇编整个程序:

objdump -d bomb > bomb.txt

bomb.txt可以查看bomb的汇编代码

csapp深入理解计算机系统 bomb lab(1)phase_1_第3张图片

gdb进入调式模式

gdb bomb

csapp深入理解计算机系统 bomb lab(1)phase_1_第4张图片

在phase_1函数打断点

(gdb)break phase_1

运行到断点处

(gdb)run

csapp深入理解计算机系统 bomb lab(1)phase_1_第5张图片

可以看到断点在0x400ee0,从汇编文件中可以找到phase_1的汇编代码

csapp深入理解计算机系统 bomb lab(1)phase_1_第6张图片

此外,还可以在gdb中查看phase_1的汇编代码

disas phase_1

csapp深入理解计算机系统 bomb lab(1)phase_1_第7张图片

在使用 test %eax, %eax 指令后,通常会检查标志位,以确定 %eax 中的值是否为零。如果结果为零,则零标志位会被设置为 1,表示 %eax 中的值为零;如果结果不为零,则零标志位会被清除为 0,表示 %eax 中的值不为零。

如果%eax不为0,执行explode_bomb函数,所以只有当string_not_equal返回的值为0,才可以解开炸弹。

查看string_not_equal的汇编代码

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       	call   40131b 
  401347:	41 89 c4             	mov    %eax,%r12d
  40134a:	48 89 ef             	mov    %rbp,%rdi
  40134d:	e8 c9 ff ff ff       	call   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                   	ret    
  1. 该函数保存了一些寄存器的值(%r12%rbp%rbx)并将参数传递到寄存器中(%rdi%rsi
  2. 两次调用 string_length 函数,分别计算了两个输入字符串的长度,将长度分别存储在 %r12d%eax 中。
  3. 对比字符串长度,如果长度不相等 (jne 40139b),则直接返回 1,表示字符串不相等。
  4. 如果字符串长度相等,接着执行逐字符比较的部分: 首先检查 %rbx 指向的字符是否为字符串结束符(\0),如果是,则直接返回 0,表示字符串相等。 如果不是结束符,则比较 %rbx%rbp 指向的字符。如果不相等,立即返回 1,表示字符串不相等。如果相等,则继续比较下一个字符。循环执行字符比较的过程,直到找到不相等的字符或者两个字符串都到达结尾为止。最后,根据比较结果,将 1 或 0 存储在 %eax 中作为返回值,表示字符串是否不相等。最后,恢复被保存的寄存器值,并通过 ret 指令返回函数。

查看0x402400地址的值,就是要和输入比较的值。

炸弹一被拆除! 

你可能感兴趣的:(linux,运维,服务器)