深入理解计算机系统lab2

一、实验目的

  1. 通过objdump命令对bomb文件进行反汇编从而得到汇编代码
  2. 进一步将C语言代码与汇编代码进行联系理解,从而更深刻地理解汇编代码和其中的各种操作
  3. 通过GDB对汇编代码进行调试和分析,包括逐步运行汇编代码、断点设置、查看寄存器和内存内容等操作,从而进一步的熟悉操作。

二、实验内容与实验步骤

先使用objdump -d bomb > bomb_assembly.S将bomb文件进行反汇编,并将反汇编代码保存到bomb_assembly.S文件中,再进行调试。

1.phase1
0000000000400ee0 <phase_1>:
  400ee0: 48 83 ec 08                  	subq	$8, %rsp
  400ee4: be 00 24 40 00               	movl	$4203520, %esi
  400ee9: e8 4a 04 00 00               	callq	0x401338 <strings_not_equal>
  400eee: 85 c0                        	testl	%eax, %eax
  400ef0: 74 05                        	je	0x400ef7 <phase_1+0x17>
  400ef2: e8 43 05 00 00               	callq	0x40143a <explode_bomb>
  400ef7: 48 83 c4 08                  	addq	$8, %rsp
  400efb: c3                           	retq

(1)使用gdb运行程序然后设置断点。

在这里插入图片描述
(2)查看寄存器%rsi中保存的内容,在mov指令前其中为输入的字符串,得到phase1答案为:Border relations with Canada have never been better.

在这里插入图片描述

2.phase2

对汇编代码进行分析:

0000000000400efc <phase_2>:
  400efc: 55                           	pushq	%rbp
  400efd: 53                           	pushq	%rbx
  400efe: 48 83 ec 28                  	subq	$40, %rsp
  400f02: 48 89 e6                     	movq	%rsp, %rsi
  400f05: e8 52 05 00 00               	callq	0x40145c <read_six_numbers>
  400f0a: 83 3c 24 01                  	cmpl	$1, (%rsp)
  400f0e: 74 20                        	je	0x400f30 <phase_2+0x34>
  400f10: e8 25 05 00 00               	callq	0x40143a <explode_bomb>
  400f15: eb 19                        	jmp	0x400f30 <phase_2+0x34>
  400f17: 8b 43 fc                     	movl	-4(%rbx), %eax
  400f1a: 01 c0                        	addl	%eax, %eax
  400f1c: 39 03                        	cmpl	%eax, (%rbx)
  400f1e: 74 05                        	je	0x400f25 <phase_2+0x29>
  400f20: e8 15 05 00 00               	callq	0x40143a <explode_bomb>
  400f25: 48 83 c3 04                  	addq	$4, %rbx
  400f29: 48 39 eb                     	cmpq	%rbp, %rbx
  400f2c: 75 e9                        	jne	0x400f17 <phase_2+0x1b>
  400f2e: eb 0c                        	jmp	0x400f3c <phase_2+0x40>
  400f30: 48 8d 5c 24 04               	leaq	4(%rsp), %rbx
  400f35: 48 8d 6c 24 18               	leaq	24(%rsp), %rbp
  400f3a: eb db                        	jmp	0x400f17 <phase_2+0x1b>
  400f3c: 48 83 c4 28                  	addq	$40, %rsp
  400f40: 5b                           	popq	%rbx
  400f41: 5d                           	popq	%rbp
  400f42: c3                           	retq

从代码中可以看出第二个炸弹由 6 个数字组成,
且分别保存在%rsp, %rsp+4, %rsp+8, …, %rsp+20 中
根据 0x0000000000400f0a <+14>: cmpl $0x1,(%rsp) 得出第一个数字为 1
根据 0x0000000000400f17 <+27>: mov -0x4(%rbx), %eax
0x0000000000400f1a <+30>:add %eax, %eax
0x0000000000400f1c <+32>:cmp %eax,(%rbx) 得出后一个数是前一个数的两倍
答案为:1 2 4 8 16 32

3.phase3

先分析汇编代码

0000000000400f43 <phase_3>: 
400f43: 48 83 ec 18     sub    $0x18,%rsp//分配栈内存 
400f47: 48 8d 4c 24 0c  lea    0xc(%rsp),%rcx//对%rcx进行取址
400f4c: 48 8d 54 24 08  lea    0x8(%rsp),%rdx//对%rdx进行取址
400f51: be cf 25 40 00  mov    $0x4025cf,%esi//将内存地址赋给%esi
400f56: b8 00 00 00 00  mov    $0x0,%eax//将%eax清空 
400f5b: e8 90 fc ff ff  callq  400bf0 <__isoc99_sscanf@plt>//调用
400f60: 83 f8 01        cmp    $0x1,%eax//将函数返回值与1进行比较 
400f63: 7f 05           jg     400f6a <phase_3+0x27>//若大于则跳转 至400f6a 
400f65: e8 d0 04 00 00  callq  40143a <explode_bomb>//否则炸弹爆炸

在mov指令执行前,%esi和%eax中存储的是输入的字符串,而在mov后%esi中存储为“%d %d”,所以输入为两个整数
在这里插入图片描述
继续分析代码

400f6a: 83 7c 24 08 07       cmpl  $0x7,0x8(%rsp)//将第一个数与7进行比较
400f6f: 77 3c                ja    400fad <phase_3+0x6a>//若超过则跳转 至400fad,炸弹爆炸 
400f71: 8b 44 24 08          mov   0x8(%rsp),%eax//将第一个数赋值给%eax
400f75: ff 24 c5 70 24 40 00 jmpq  *0x402470(,%rax,8)//进入switch语句 的跳转表,跳转至jt[%rax],内存地址0x402470存储跳转表

由此部分可知本关的代码为switch语句,输入的第一个整数的范围是0~7,跳转表为
在这里插入图片描述
400f7c为case 0,400fb9为case 1,400f83为case 2,400f8a为case 3,400f91为case 4,400f98为case 5,400f9f为case 6,400fa6为case 7

400f7c: b8 cf 00 00 00 mov $0xcf,%eax//赋值%eax为207 
400f81: eb 3b jmp 400fbe <phase_3+0x7b>//跳转至 400fbe
400f83: b8 c3 02 00 00 mov $0x2c3,%eax//赋值为707 
400f88: eb 34 jmp 400fbe <phase_3+0x7b>//跳转至比较 
400f8a: b8 00 01 00 00 mov $0x100,%eax//赋值为256 
400f8f: eb 2d jmp 400fbe <phase_3+0x7b>//跳转至比较 
400f91: b8 85 01 00 00 mov $0x185,%eax//赋值为389 
400f96: eb 26 jmp 400fbe <phase_3+0x7b>//跳转 
400f98: b8 ce 00 00 00 mov $0xce,%eax//赋值为206 
400f9d: eb 1f jmp 400fbe <phase_3+0x7b>//跳转 
400f9f: b8 aa 02 00 00 mov $0x2aa,%eax//赋值为682 
400fa4: eb 18 jmp 400fbe <phase_3+0x7b>//跳转 
400fa6: b8 47 01 00 00 mov $0x147,%eax//赋值为327 
400fab: eb 11 jmp 400fbe <phase_3+0x7b>//跳转 
400fad: e8 88 04 00 00 callq 40143a <explode_bomb>//炸弹爆炸 
400fb2: b8 00 00 00 00 mov $0x0,%eax//赋值%eax为0 
400fb7: eb 05 jmp 400fbe <phase_3+0x7b>//跳转至比较 
400fb9: b8 37 01 00 00 mov $0x137,%eax//赋值%eax为311 
400fbe: 3b 44 24 0c cmp 0xc(%rsp),%eax//第二个数与%eax进行比较 
400fc2: 74 05 je 400fc9 <phase_3+0x86>//相等则跳转至 400fc9,释放栈内存,返回
400fc4: e8 71 04 00 00 callq 40143a <explode_bomb>//否则炸弹爆炸 
400fc9: 48 83 c4 18 add $0x18,%rsp//释放栈内存 
400fcd: c3 retq

该部分为switch内部语句,对于每一个case,其内容为如下形式

switch (x) 
{ 
	case 0: 
		if (n != n1) //explode 
			break; 
	case 1: //结构同上 
}

通过查看跳转表得出对应的整数组合:0 207,1 311,2 707,3 256,4 389,5 206,6 682,7 327为八个答案
在这里插入图片描述

4.phase4
000000000040100c <phase_4>:
  40100c: 48 83 ec 18                  	subq	$24, %rsp
  401010: 48 8d 4c 24 0c               	leaq	12(%rsp), %rcx
  401015: 48 8d 54 24 08               	leaq	8(%rsp), %rdx
  40101a: be cf 25 40 00               	movl	$4203983, %esi
  40101f: b8 00 00 00 00               	movl	$0, %eax
  401024: e8 c7 fb ff ff               	callq	0x400bf0 <__isoc99_sscanf@plt>
  401029: 83 f8 02                     	cmpl	$2, %eax
  40102c: 75 07                        	jne	0x401035 <phase_4+0x29>
  40102e: 83 7c 24 08 0e               	cmpl	$14, 8(%rsp)
  401033: 76 05                        	jbe	0x40103a <phase_4+0x2e>
  401035: e8 00 04 00 00               	callq	0x40143a <explode_bomb>
  40103a: ba 0e 00 00 00               	movl	$14, %edx
  40103f: be 00 00 00 00               	movl	$0, %esi
  401044: 8b 7c 24 08                  	movl	8(%rsp), %edi
  401048: e8 81 ff ff ff               	callq	0x400fce <func4>
  40104d: 85 c0                        	testl	%eax, %eax
  40104f: 75 07                        	jne	0x401058 <phase_4+0x4c>
  401051: 83 7c 24 0c 00               	cmpl	$0, 12(%rsp)
  401056: 74 05                        	je	0x40105d <phase_4+0x51>
  401058: e8 dd 03 00 00               	callq	0x40143a <explode_bomb>
  40105d: 48 83 c4 18                  	addq	$24, %rsp
  401061: c3                           	retq

设 fun4 的两个参数分别为 x,y
根据 fun4 之后的反汇编代码,很容易看出只有当 fun4()返回值为 0 且 y = 0,才能解除炸弹。逐步调试,直到第 10 行,比较%edi 和 %ecx 的值。
(gdb) print/d $ecx
$17 = 7
查看%ecx 寄存器的值,并把这个值作为 x。
答案为:7 0

5.phase5

分析代码

0000000000401062 <phase_5>: 
401062: 53 push %rbx//入栈 
401063: 48 83 ec 20 sub $0x20,%rsp//分配栈内存 
401067: 48 89 fb mov %rdi,%rbx//用%rdi赋值给%rbx,内容为 输入的字符串 
40106a: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax//用%fs:0x28给%rax赋值 
401071: 00 00 
401073: 48 89 44 24 18 mov %rax,0x18(%rsp)//将%rax的内容存入栈 
401078: 31 c0 xor %eax,%eax//%rax的低四字节进行异或清零 
40107a: e8 9c 02 00 00 callq 40131b <string_length>//调用函数 string_length 
40107f: 83 f8 06 cmp $0x6,%eax//将返回值和6进行比较 
401082: 74 4e je 4010d2 <phase_5+0x70>//若相等则跳转 至4010d2 
401084: e8 b1 03 00 00 callq 40143a <explode_bomb>//否则炸弹爆炸

此处%rdi中存储的字符串长度为6
在这里插入图片描述
分析跳转后的代码

4010d2: b8 00 00 00 00 mov $0x0,%eax//将%eax赋值为0 
4010d7: eb b2 jmp 40108b <phase_5+0x29>//跳转至 40108b 
40108b: 0f b6 0c 03 movzbl (%rbx,%rax,1),%ecx//将%rbx+%rax的 第四字节赋值给%ecx,并清零其高四字节 
//此时%ecx当中存储的是输入的字符串的第%rax+1个字符,即string[%rax]

此时%ecx中存储的是输入字符串的第%rax+1个字符,即string[%rax],但x/s命令不可访问
在这里插入图片描述
继续分析

40108f: 88 0c 24 mov %cl,(%rsp)//将%cl的地址放入栈顶 
401092: 48 8b 14 24 mov (%rsp),%rdx//将栈顶的内容赋值给%rdx, 即%cl 
401096: 83 e2 0f and $0xf,%edx//将0xf与%edx的内容进行与操 作,即保留其低4位,清空高位 
401099: 0f b6 92 b0 24 40 00 movzbl 0x4024b0(%rdx),%edx//对%edx进行赋值 为0x4024b0+%rdx,并清空高4字节

0x4024b0内容为一个字符串: “maduiersnfotvbylSo you think you can stop the bomb with ctrl-c, do you?”,所以此时%edx中存储的是0x4024b0的字符串的第%rdx个字符,所以认为这段代码应该是将%ecx中字符的ASCII码的低s四位存入%rdx
在这里插入图片描述
继续分析

4010a0: 88 54 04 10 mov %dl,0x10(%rsp,%rax,1)//将%dl的值存 入栈中%rsp+16+%rax的位置 
4010a4: 48 83 c0 01 add $0x1,%rax//++%rax 
4010a8: 48 83 f8 06 cmp $0x6,%rax//将%rax与6进行比较 
4010ac: 75 dd jne 40108b <phase_5+0x29>//若不相等则跳 转至40108b,循环操作

将存有字符的%edx的最低一字节放入栈中对应位置,当%rax小于6时进行循环操作,所以%rax=0-5会进行六次操作,得到六个字符存入栈中连续的位置,%rsp+16~%rsp+21,生成了一个含有六个字符的字符串,这六个字符串分别与输入字符串的低4位ASCII码在0x4024b0的字符串对应下标字符对应

继续分析

4010ae: c6 44 24 16 00 movb $0x0,0x16(%rsp)//将%rsp+22最低字节 赋值位0 
4010b3: be 5e 24 40 00 mov $0x40245e,%esi//将%esi赋值为 0x40245e的内容 
4010b8: 48 8d 7c 24 10 lea 0x10(%rsp),%rdi//%rdi取址为%rsp+16 
4010bd: e8 76 02 00 00 callq 401338 <strings_not_equal>//调用函 数strings_not_equal,字符串相同时返回0,不同时返回1 
4010c2: 85 c0 test %eax,%eax//测试返回值 
4010c4: 74 13 je 4010d9 <phase_5+0x77>//返回为0则跳 转至4010d9 
4010c6: e8 6f 03 00 00 callq 40143a <explode_bomb>//否则炸弹爆炸
4010d9: 48 8b 44 24 18 mov 0x18(%rsp),%rax//将%rsp+24地址赋值 给%rax 
4010de: 64 48 33 04 25 28 00 xor %fs:0x28,%rax//将%fs:0x28与%rax进行 异或
4010e5: 00 00 
4010e7: 74 05 je 4010ee <phase_5+0x8c>//若相等则跳转 至4010ee 
4010e9: e8 42 fa ff ff callq 400b30 <__stack_chk_fail@plt>//否 则调用函数__stack_chk_fail@plt 
4010ee: 48 83 c4 20 add $0x20,%rsp//释放栈内存 
4010f2: 5b pop %rbx//%rbx出栈 
4010f3: c3 retq

这段代码将0x40245e的内容赋值给%esi,查看该内存位置的内容,发现其为一个长度为六的字符串: “flyers”,之后将%rdi取址%rsp+16,即在上一步骤中获得的字符串的首地址,然后调用函数strings_not_equal,该函数对两个字符串进行比较,相等时返回0,否则返回1,当返回1时炸弹引爆,返回0时经过进一步操作完成本关。
综上可知本关的输入是长度为六的字符串,该字符串每个字符的ASCII码的低四位在0x4024b0的字符串中对应确定一个字符,组成新的长度为6的字符串,该字符串与0x40245e的字符串相同。
在“flyers”中每个字符分别位于“maduiersnfotvbylSo you think you can stop the bomb with ctrlc, do you?”第9,15,14,5,6,7位,四位二进制表示为1001,1111,1110,0101,0110,0111,对应可取字符i,o,n,e,f,g
所以答案为:ionefg
在这里插入图片描述

6.phase6
00000000004010f4 <phase_6>:
  4010f4: 41 56                        	pushq	%r14
  4010f6: 41 55                        	pushq	%r13
  4010f8: 41 54                        	pushq	%r12
  4010fa: 55                           	pushq	%rbp
  4010fb: 53                           	pushq	%rbx
  4010fc: 48 83 ec 50                  	subq	$80, %rsp
  401100: 49 89 e5                     	movq	%rsp, %r13
  401103: 48 89 e6                     	movq	%rsp, %rsi
  401106: e8 51 03 00 00               	callq	0x40145c <read_six_numbers>
  40110b: 49 89 e6                     	movq	%rsp, %r14
  40110e: 41 bc 00 00 00 00            	movl	$0, %r12d
  401114: 4c 89 ed                     	movq	%r13, %rbp
  401117: 41 8b 45 00                  	movl	(%r13), %eax
  40111b: 83 e8 01                     	subl	$1, %eax
  40111e: 83 f8 05                     	cmpl	$5, %eax
  401121: 76 05                        	jbe	0x401128 <phase_6+0x34>
  401123: e8 12 03 00 00               	callq	0x40143a <explode_bomb>
  401128: 41 83 c4 01                  	addl	$1, %r12d
  40112c: 41 83 fc 06                  	cmpl	$6, %r12d
  401130: 74 21                        	je	0x401153 <phase_6+0x5f>
  401132: 44 89 e3                     	movl	%r12d, %ebx
  401135: 48 63 c3                     	movslq	%ebx, %rax
  401138: 8b 04 84                     	movl	(%rsp,%rax,4), %eax
  40113b: 39 45 00                     	cmpl	%eax, (%rbp)
  40113e: 75 05                        	jne	0x401145 <phase_6+0x51>
  401140: e8 f5 02 00 00               	callq	0x40143a <explode_bomb>
  401145: 83 c3 01                     	addl	$1, %ebx
  401148: 83 fb 05                     	cmpl	$5, %ebx
  40114b: 7e e8                        	jle	0x401135 <phase_6+0x41>
  40114d: 49 83 c5 04                  	addq	$4, %r13
  401151: eb c1                        	jmp	0x401114 <phase_6+0x20>
  401153: 48 8d 74 24 18               	leaq	24(%rsp), %rsi
  401158: 4c 89 f0                     	movq	%r14, %rax
  40115b: b9 07 00 00 00               	movl	$7, %ecx
  401160: 89 ca                        	movl	%ecx, %edx
  401162: 2b 10                        	subl	(%rax), %edx
  401164: 89 10                        	movl	%edx, (%rax)
  401166: 48 83 c0 04                  	addq	$4, %rax
  40116a: 48 39 f0                     	cmpq	%rsi, %rax
  40116d: 75 f1                        	jne	0x401160 <phase_6+0x6c>
  40116f: be 00 00 00 00               	movl	$0, %esi
  401174: eb 21                        	jmp	0x401197 <phase_6+0xa3>
  401176: 48 8b 52 08                  	movq	8(%rdx), %rdx
  40117a: 83 c0 01                     	addl	$1, %eax
  40117d: 39 c8                        	cmpl	%ecx, %eax
  40117f: 75 f5                        	jne	0x401176 <phase_6+0x82>
  401181: eb 05                        	jmp	0x401188 <phase_6+0x94>
  401183: ba d0 32 60 00               	movl	$6304464, %edx
  401188: 48 89 54 74 20               	movq	%rdx, 32(%rsp,%rsi,2)
  40118d: 48 83 c6 04                  	addq	$4, %rsi
  401191: 48 83 fe 18                  	cmpq	$24, %rsi
  401195: 74 14                        	je	0x4011ab <phase_6+0xb7>
  401197: 8b 0c 34                     	movl	(%rsp,%rsi), %ecx
  40119a: 83 f9 01                     	cmpl	$1, %ecx
  40119d: 7e e4                        	jle	0x401183 <phase_6+0x8f>
  40119f: b8 01 00 00 00               	movl	$1, %eax
  4011a4: ba d0 32 60 00               	movl	$6304464, %edx
  4011a9: eb cb                        	jmp	0x401176 <phase_6+0x82>
  4011ab: 48 8b 5c 24 20               	movq	32(%rsp), %rbx
  4011b0: 48 8d 44 24 28               	leaq	40(%rsp), %rax
  4011b5: 48 8d 74 24 50               	leaq	80(%rsp), %rsi
  4011ba: 48 89 d9                     	movq	%rbx, %rcx
  4011bd: 48 8b 10                     	movq	(%rax), %rdx
  4011c0: 48 89 51 08                  	movq	%rdx, 8(%rcx)
  4011c4: 48 83 c0 08                  	addq	$8, %rax
  4011c8: 48 39 f0                     	cmpq	%rsi, %rax
  4011cb: 74 05                        	je	0x4011d2 <phase_6+0xde>
  4011cd: 48 89 d1                     	movq	%rdx, %rcx
  4011d0: eb eb                        	jmp	0x4011bd <phase_6+0xc9>
  4011d2: 48 c7 42 08 00 00 00 00      	movq	$0, 8(%rdx)
  4011da: bd 05 00 00 00               	movl	$5, %ebp
  4011df: 48 8b 43 08                  	movq	8(%rbx), %rax
  4011e3: 8b 00                        	movl	(%rax), %eax
  4011e5: 39 03                        	cmpl	%eax, (%rbx)
  4011e7: 7d 05                        	jge	0x4011ee <phase_6+0xfa>
  4011e9: e8 4c 02 00 00               	callq	0x40143a <explode_bomb>
  4011ee: 48 8b 5b 08                  	movq	8(%rbx), %rbx
  4011f2: 83 ed 01                     	subl	$1, %ebp
  4011f5: 75 e8                        	jne	0x4011df <phase_6+0xeb>
  4011f7: 48 83 c4 50                  	addq	$80, %rsp
  4011fb: 5b                           	popq	%rbx
  4011fc: 5d                           	popq	%rbp
  4011fd: 41 5c                        	popq	%r12
  4011ff: 41 5d                        	popq	%r13
  401201: 41 5e                        	popq	%r14
  401203: c3                           	retq

结合phase_2可知,本关输入也为六个数字,且第一个输入的数字要小于等于6
401128-401151部分通过循环操作,确定输入的六个数字互不相同,且都小于等于6,所以这六个整数取址范围为1~6
401153-40116d部分将输入的每个数在栈中替换为7-该数,即%rsp到%rsp+20中的n1, n2, n3, n4, n5, n6, n7变为了7-n1, 7-n2, 7-n3, 7-n4, 7-n5, 7-n6, 7-n7,处理完后跳出该循环
40116f-40117f部分中有一个内存部分0x6032d0,查看后发现其内部为一个链表,node1 = 332,node2 =
168,node3 = 924,node4 = 691,node5 = 477,node6 = 443,操作中通过栈中的六个数字作
为序列对链表元素进行入栈操作,存储在%rsp+32~%rsp+32+40的栈内存中
在这里插入图片描述
4011ab-4011cb该部分将入栈后的链表元素按照入栈的顺序进行重新的链表连接
4011d2-401203部分将栈内存中的链表节点内容进行比较,当前一个节点的内容小于等于后一个节点的值时炸弹引爆,所以节点的内容按照降序排列,即节点入栈的顺序需要按照其内容的值从大到小进行入栈,已知924 > 691 > 477 > 443 > 332 > 168,所以节点入栈的顺序为3,4,5,6,1,2,每个下标对应了7-n,所以输入的六个数字为4 3 2 1 6 5
所以答案为:4 3 2 1 6 5
在这里插入图片描述

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值