CSAPP-bomb实验

CSAPP-bomb实验

纪念一下bomb实验
在这里插入图片描述
看汇编代码感觉要注意以下几点:
1、一个过程开头一般是sub sp,用来分配栈空间
2、然后保存寄存器
3、如果过程A中还调用了其他过程B,那么在调用前会有参数的传递;可以配合过程B的代码和过程A中的参数传递看懂寄存器的意义
4、以$开头的是立即数,就是10进制数,下文中有6304464这样的数作为地址偏移量,(我一开始以为是16进制)这个地址加8就是6304472
phase1

0000000000400ee0 <phase_1>://从地址4203520处读字符串,与输入的字符串比较,如果一样,则通过
  400ee0: 48 83 ec 08                  	subq	$8, %rsp
  400ee4: be 00 24 40 00               	movl	$4203520, %esi //内存中字符串的起始地址,在gdb中用 x/sb 4203520可以查看
  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

phase2

0000000000400efc <phase_2>://输入6个int型数字,答案是首项为1,公比为2的等比数列
  400efc: 55                           	pushq	%rbp
  400efd: 53                           	pushq	%rbx
  400efe: 48 83 ec 28                  	subq	$40, %rsp
  400f02: 48 89 e6                     	movq	%rsp, %rsi //当前sp存入si中,作为read_six_number的输入参数,输入的6个数字会依次存在si开始向上(地址增大)的地方
  400f05: e8 52 05 00 00               	callq	0x40145c <read_six_numbers>
  400f0a: 83 3c 24 01                  	cmpl	$1, (%rsp) //判断第一个数是不是1,不是则explode
  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 //相当于乘2
  400f1c: 39 03                        	cmpl	%eax, (%rbx) //判断当前数是不是前一个数的2倍
  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

phase3

0000000000400f43 <phase_3>://输入两个数,有7组答案
  400f43: 48 83 ec 18                  	subq	$24, %rsp
  400f47: 48 8d 4c 24 0c               	leaq	12(%rsp), %rcx //存第二个数的地址
  400f4c: 48 8d 54 24 08               	leaq	8(%rsp), %rdx //存第一个数的地址
  400f51: be cf 25 40 00               	movl	$4203983, %esi
  400f56: b8 00 00 00 00               	movl	$0, %eax //eax是用来存scanf读入数据的个数的
  400f5b: e8 90 fc ff ff               	callq	0x400bf0 <__isoc99_sscanf@plt>
  400f60: 83 f8 01                     	cmpl	$1, %eax //读入数的数量要大于1
  400f63: 7f 05                        	jg	0x400f6a <phase_3+0x27>
  400f65: e8 d0 04 00 00               	callq	0x40143a <explode_bomb>
  400f6a: 83 7c 24 08 07               	cmpl	$7, 8(%rsp) //第一个数要小于等于7
  400f6f: 77 3c                        	ja	0x400fad <phase_3+0x6a>
  400f71: 8b 44 24 08                  	movl	8(%rsp), %eax
  400f75: ff 24 c5 70 24 40 00         	jmpq	*4203632(,%rax,8) //注意4203632地址处的数为0x400f7c,就是跳转到下一行,加上偏移量8*第一个数,只要第二个数和下面的数对应即可
  400f7c: b8 cf 00 00 00               	movl	$207, %eax
  400f81: eb 3b                        	jmp	0x400fbe <phase_3+0x7b>
  400f83: b8 c3 02 00 00               	movl	$707, %eax
  400f88: eb 34                        	jmp	0x400fbe <phase_3+0x7b>
  400f8a: b8 00 01 00 00               	movl	$256, %eax
  400f8f: eb 2d                        	jmp	0x400fbe <phase_3+0x7b>
  400f91: b8 85 01 00 00               	movl	$389, %eax
  400f96: eb 26                        	jmp	0x400fbe <phase_3+0x7b>
  400f98: b8 ce 00 00 00               	movl	$206, %eax
  400f9d: eb 1f                        	jmp	0x400fbe <phase_3+0x7b>
  400f9f: b8 aa 02 00 00               	movl	$682, %eax
  400fa4: eb 18                        	jmp	0x400fbe <phase_3+0x7b>
  400fa6: b8 47 01 00 00               	movl	$327, %eax
  400fab: eb 11                        	jmp	0x400fbe <phase_3+0x7b>
  400fad: e8 88 04 00 00               	callq	0x40143a <explode_bomb>
  400fb2: b8 00 00 00 00               	movl	$0, %eax
  400fb7: eb 05                        	jmp	0x400fbe <phase_3+0x7b>
  400fb9: b8 37 01 00 00               	movl	$311, %eax
  400fbe: 3b 44 24 0c                  	cmpl	12(%rsp), %eax
  400fc2: 74 05                        	je	0x400fc9 <phase_3+0x86>
  400fc4: e8 71 04 00 00               	callq	0x40143a <explode_bomb>
  400fc9: 48 83 c4 18                  	addq	$24, %rsp
  400fcd: c3                           	retq

phase4

0000000000400fce <func4>:
  400fce: 48 83 ec 08                  	subq	$8, %rsp
  400fd2: 89 d0                        	movl	%edx, %eax //dx存的14
  400fd4: 29 f0                        	subl	%esi, %eax //si存的0,所以ax为14
  400fd6: 89 c1                        	movl	%eax, %ecx
  400fd8: c1 e9 1f                     	shrl	$31, %ecx //逻辑右移31,cx为0
  400fdb: 01 c8                        	addl	%ecx, %eax //ax依然14
  400fdd: d1 f8                        	sarl	%eax //右移1,ax变7
  400fdf: 8d 0c 30                     	leal	(%rax,%rsi), %ecx //cx为7
  400fe2: 39 f9                        	cmpl	%edi, %ecx  //di存的第一个数
  400fe4: 7e 0c                        	jle	0x400ff2 <func4+0x24> //第一个数小于等于7
  400fe6: 8d 51 ff                     	leal	-1(%rcx), %edx
  400fe9: e8 e0 ff ff ff               	callq	0x400fce <func4>
  400fee: 01 c0                        	addl	%eax, %eax
  400ff0: eb 15                        	jmp	0x401007 <func4+0x39>
  400ff2: b8 00 00 00 00               	movl	$0, %eax
  400ff7: 39 f9                        	cmpl	%edi, %ecx
  400ff9: 7d 0c                        	jge	0x401007 <func4+0x39> //第一个数大于等于7,所以只能为7
  400ffb: 8d 71 01                     	leal	1(%rcx), %esi
  400ffe: e8 cb ff ff ff               	callq	0x400fce <func4>
  401003: 8d 44 00 01                  	leal	1(%rax,%rax), %eax
  401007: 48 83 c4 08                  	addq	$8, %rsp
  40100b: c3                           	retq

000000000040100c <phase_4>://输入2个数字
  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 //eax置零,调用scanf后返回读入的数据个数
  401024: e8 c7 fb ff ff               	callq	0x400bf0 <__isoc99_sscanf@plt>
  401029: 83 f8 02                     	cmpl	$2, %eax //从这看出来要输入两个数字,不等于2就explode
  40102c: 75 07                        	jne	0x401035 <phase_4+0x29>
  40102e: 83 7c 24 08 0e               	cmpl	$14, 8(%rsp) //第一个数小于等于14
  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 //上面3行是传递参数给func4
  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> //第二个数等于0
  401058: e8 dd 03 00 00               	callq	0x40143a <explode_bomb>
  40105d: 48 83 c4 18                  	addq	$24, %rsp
  401061: c3                           	retq

phase5

0000000000401062 <phase_5>://输入长度为6的字符串,分别取他们的低四位作为偏移量(0-15),在另一已知字符串中查找字符作为替换,生成新的字符串并要和密码串一致
  401062: 53                           	pushq	%rbx
  401063: 48 83 ec 20                  	subq	$32, %rsp
  401067: 48 89 fb                     	movq	%rdi, %rbx //di存储了输入字符串的首地址,字符串以/0结尾
  40106a: 64 48 8b 04 25 28 00 00 00   	movq	%fs:40, %rax
  401073: 48 89 44 24 18               	movq	%rax, 24(%rsp)
  401078: 31 c0                        	xorl	%eax, %eax//ax置零,是string_length的返回值保存处
  40107a: e8 9c 02 00 00               	callq	0x40131b <string_length>
  40107f: 83 f8 06                     	cmpl	$6, %eax //输入字符串长度必须为6
  401082: 74 4e                        	je	0x4010d2 <phase_5+0x70>
  401084: e8 b1 03 00 00               	callq	0x40143a <explode_bomb>
  401089: eb 47                        	jmp	0x4010d2 <phase_5+0x70>
  40108b: 0f b6 0c 03                  	movzbl	(%rbx,%rax), %ecx
  40108f: 88 0c 24                     	movb	%cl, (%rsp)
  401092: 48 8b 14 24                  	movq	(%rsp), %rdx
  401096: 83 e2 0f                     	andl	$15, %edx //以上4行是取输入字符串每一个字符的低4位,放在dx中
  401099: 0f b6 92 b0 24 40 00         	movzbl	4203696(%rdx), %edx //用dx作为偏移量,取4203696+偏移量处的字符
  4010a0: 88 54 04 10                  	movb	%dl, 16(%rsp,%rax) //生成新字符串,放置在运行时栈中
  4010a4: 48 83 c0 01                  	addq	$1, %rax
  4010a8: 48 83 f8 06                  	cmpq	$6, %rax
  4010ac: 75 dd                        	jne	0x40108b <phase_5+0x29>
  4010ae: c6 44 24 16 00               	movb	$0, 22(%rsp) //保存在栈中的字符串要以\0结尾
  4010b3: be 5e 24 40 00               	movl	$4203614, %esi //密码字符串首地址
  4010b8: 48 8d 7c 24 10               	leaq	16(%rsp), %rdi //栈中字符串首地址,是函数string-not-equal的输入参数
  4010bd: e8 76 02 00 00               	callq	0x401338 <strings_not_equal>//判断两个字符串是否相等,所以我们可以根据密码串构造输入串,输入串不唯一(只要ascii低4位一样即可)
  4010c2: 85 c0                        	testl	%eax, %eax
  4010c4: 74 13                        	je	0x4010d9 <phase_5+0x77>
  4010c6: e8 6f 03 00 00               	callq	0x40143a <explode_bomb>
  4010cb: 0f 1f 44 00 00               	nopl	(%rax,%rax)
  4010d0: eb 07                        	jmp	0x4010d9 <phase_5+0x77>
  4010d2: b8 00 00 00 00               	movl	$0, %eax
  4010d7: eb b2                        	jmp	0x40108b <phase_5+0x29>
  4010d9: 48 8b 44 24 18               	movq	24(%rsp), %rax
  4010de: 64 48 33 04 25 28 00 00 00   	xorq	%fs:40, %rax
  4010e7: 74 05                        	je	0x4010ee <phase_5+0x8c>
  4010e9: e8 42 fa ff ff               	callq	0x400b30 <__stack_chk_fail@plt>
  4010ee: 48 83 c4 20                  	addq	$32, %rsp
  4010f2: 5b                           	popq	%rbx
  4010f3: c3                           	retq

phase6

00000000004010f4 <phase_6>://一个已知的存储int数据的链表,你将他从大到小排序,生成6个数字,分别表示排序后数组中的数对应在原数组的位置,
  4010f4: 41 56                        	pushq	%r14 //然后用7分别减它们,就是答案
  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 //si输入参数,下面读6个数字
  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>//jbe(无符号)判断这个数是不是在1-6之间,为了排除0,用的先减1再看是不是小于等于5
  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>//外循环控制:每一个数都要做上述操作:在1-6之间?和其他数不等?
  401153: 48 8d 74 24 18               	leaq	24(%rsp), %rsi //si为循环边界
  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>//以上是拿7去减输入的数字
  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。//大于1的话需要循环去找相应的地址(:-)
  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  //1的话就是直接放首地址6304464  (:-)
  4011a4: ba d0 32 60 00               	movl	$6304464, %edx //6304464为链表首地址,注意这个链表结构是,低地址放int数,高地址放下一个节点地址
  4011a9: eb cb                        	jmp	0x401176 <phase_6+0x82>//比如,6304464开始的4个字节为int数,6304472开始的8字节为下一个节点的地址
  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>//所以答案就是,从6304464开始用gdb看一下链表,生成6个数字
  4011ee: 48 8b 5b 08                  	movq	8(%rbx), %rbx  //分别表示从大到小排序后的数对应在原数组的位置,再用7减,就是输入的正确答案
  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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值