Lab2 Bomb Lab

Lab2 Bomb Lab

如果你在找相关教程,看下面两个吧,我自己写的不咋地。尤其是第一个链接,大佬666

手把手教你拆解 CSAPP 的 炸弹实验室 BombLab - 知乎 (zhihu.com)

CSAPP:BombLab 详细解析_csapp bomblab-CSDN博客

一、目的

  1. 前言

开始这个实验的时候我只只知道要拆弹,看readme什么也没有,就一脸懵。就先直接运行程序。

$ ./bomb

然后随便输入字符串,直接bomb。然后网上随便找个题解看了下,大概要输入6个正确密码。然后又懵逼了,我怎么知道密码。

就当时脑袋蒙住了,几分钟后才反应我可以看代码啊。下面是文件解压后的内容:

bomb    // 二进制,不可直接查看,也是你要拆的“炸弹”
bomb.c  // bomb的源文件,辅助理解bomb代码
readme	// 没啥用,就一句话

所以只能从bomb.c入手,主要是看if,通过参数选择文件输入和命令行输入。

input = read_line();             
phase_1(input);                  
phase_defused(); 

读到这里就大概明白是要从phase_1中找到答案。后面的phase结构类似。

然后问题又来了,我要怎么明白phase_1中发生了什么。我从两个方面的到答案,①是我记得有官方的pdf,但我去看了下,大概是些activity,练习工具②是看别人的解答:使用 gdb 或 ddd 调试器,对二进制文件进行反汇编

①我发现离实验应用有点远,我想直接上手实验。于是直接把phase_1跟着一个帖子做了,然后大概明白了怎么做了。建议先看phase_1做一遍,再看下二补充

最后放上ppt上的翻译

应该怎么办
• 不明白一大块汇编代码是做什么的?用 GDB
• 需要弄清楚特定内存地址中的内容?用 GDB
• 无法追踪 4 到 6 个寄存器随时间的变化?用 GDB
• 不知道如何开始作业?阅读作业说明
• 需要了解如何使用某些 GDB 命令?查看作业说明、参加训练营
• 还有用的链接:http://csapp.cs.cmu.edu/3e/docs/gdbnotes-x86-64.pdf
• 不知道某条汇编指令是做什么的?看讲座幻灯片
• 对控制流或栈规则感到困惑?看讲座幻灯片

二、补充

默认会汇编,只是缺少工具使用的熟练度

1.基本

①gdb的粗略使用

开始GDB:
$ gdb	
(gdb) run 15213 

$ gdb <binary> ($ gdb ./a.out) // 输入gdb,然后指定要运行的可执行文件

$ gdb --args gcc -O2 -c foo.c	// 用--args传参

(gdb) quit [表达式]	
(gdb) q
// 表示在退出 GDB 之前要执行的表达式。你可以在这里指定任何合法的 GDB 表达式,比如打印变量的值、调用函数等操作。当你退出 GDB 时,这个表达式会被执行。

$ gdb -help OR $ gdb -h
常用命令:
断点
(gdb) break/b function_name
(gdb) break *0x…
(gdb) info b
(gdb) clear [location]

程序执行
(gdb) next/n:运行程序的下一行代码,不会进入函数内部
(gdb) step/s:运行程序的下一行代码并进入函数内部
(gdb) continue/c
(gdb) CTRL + c:停止执行

打印数值和检查内存
(gdb) print [any valid expression]
(gdb) x/nfu [内存地址]
n:检查接下来 n 个内存单元。
f(格式):可以表示为:
	d(十进制)、x(十六进制)、s(字符串)等。
u(单位):可以表示为:
	b(字节)、w(字/4 字节)等。

②如何查看反汇编

layout regs // 显示寄存器
layout asm // 显示反汇编窗口 

2.做完第一个之后

①输入用文件

就是说,第一阶段拆完了,拆第二段,但我不可能每次都输入第一段的答案。所以利用了bomb.c可以文件输入。

具体做法就是在该目录下创建一个input.txt,输入时./bomb input.txt或者(gdb) r input.txt就行。

②汇编输出到文件

$ objdump -d [name of executable] > [any file name]

将可执行文件的汇编代码保存到指定的文件中

Tips:不要用TUI,炸弹可能因为这个爆炸

3.补充

提示:
使用库函数的 man 手册。虽然你可以查看 snprintf() 的汇编代码,但我们向你保证使用 man 手册($ man snprintf)会比解析系统调用的汇编代码更容易

工具:
GBD

$ objdump -d [可执行文件名称] > [任意文件名]
• 将可执行文件的汇编代码保存到指定文件中。
• 请随意在您喜爱的文本编辑器中对汇编代码进行注释。

三、实践

1.phase_1(当尝试)

我是跟着这个做的——>手把手教你拆解 CSAPP 的 炸弹实验室 BombLab - 知乎 (zhihu.com)

① gdb bomb
② b explode_bomb:设置断点,即使当我们错误输入时也能阻止炸弹爆炸
③b phase_1: 从 bomb.c 中可以知道,phase_1(input) 处理输入字符串,故我们在此函数入口处设置断点
④r 运行程序

随便输入一些字符,layout asm 显示反汇编窗口

在这里插入图片描述

显然字符串传入phase_1后,后面调用了一个strings_not_equal函数,看名字应该是匹配输入字符串和正确的字符串,显然我们输入的字符串是不对的,程序就调用explode_bomb,引爆炸弹。

可以看出0x402400是正确字符串,因为第一个参数显然是我们自己的输入%rdi中,所以%esi存第二个参数正确字符串。

用 x/s 0x402400即可查看正确字符串

在这里插入图片描述

2.phase_2

再phase_2打断点,(gdb) r input.txt,如图
在这里插入图片描述

%rdi是我们输入的字符串,可以看到call read_six_numbers,%ris为第二个参数,从%rsp中来。后面cmpl如果不跳转回call explode_bomb。所以先尝试在read_six_numbers打断点

在这里插入图片描述

我错了,本来我想直接看的,但直接眼花缭乱,还是自己老实反汇编吧,老实点分析

在这里插入图片描述

然后也没看懂到底是在干什么。先试试看赋给esi内存地址是什么

在这里插入图片描述

然后又懵逼了,怎么是六个整数。

然后看了下别人的答案,大概是从字符串中读入6个整数,存到对应的内存中,至于前面为什么那么乱,也是为了能够直接利用phase_2函数的栈指针来连续地访问这6个数字。
CSAPP | Lab2-Bomb Lab 深入解析 - 知乎 (zhihu.com)

至于怎么输入,下面有一条链接sscanf的call命令,我用man,然后看不懂:(,最后还是百度解决。

显然因为我输入的是随便的字符串,在call read_six_numbers肯定会炸,所以我把input.txt中的第二行随便改为6个数字。

在这里插入图片描述

就跳过了call explode_bomb,

在这里插入图片描述

读入6个数字后,后面显然表示数组第一位为1,然后跳转到下面

在这里插入图片描述

显然要逐个比较,要有个循环。①为第一次比较后回到loop,②比较重要,%eax和(%rbx)比较相等就继续比较,不相等就会调用炸弹。③为出口%rbp和%rbx是否相等,%rbp在第一次比较后就设置为高位栈

核心%eax和(%rbx)比较,看比较前做了什么,%rbx显然为栈上自己输入的因为每次都+4;%eax就+27和+30做了事,显示等于前一个数,然后两倍。由此可知该数组每个数字都为前面的两倍。所以答案是"1 2 4 8 16 32."

3.phase_3

修改input.txt,用gdb调试,在phase_3打断点

在这里插入图片描述

第一个call explode_bomb前将%eax和0x1比较,要%eax中的值>0x1才能避免炸弹。前面将%eax赋值为0,然后call sscanf,第一个参数%rdi是我们输入的字符串,第二个参数为%esi,因为sscanf(const char *str, const char *format, …),所以查看%esi便可确定格式

在这里插入图片描述

为两个整数,结合前面sub指令,两个整数应该在%rsp+0x8和%rsp+0xc上,分别赋给%rcx赫尔%rdx。然后继续往下找

在这里插入图片描述

所以第一个整数为小于等于7,然后赋给%eax,然后后面好多无条件跳转,有点像switch,然后灵感来了。根据第一个整数值跳转情况,改变eax的值。

在这里插入图片描述

看样子,跳转后的值要和第二位整数值相同。再回去看跳转,是8*%rax,所以有一个跳转表,x/16x 0x402470 查看从地址 0x402470 处开始的 8 个地址值手把手教你拆解 CSAPP 的 炸弹实验室 BombLab - 知乎 (zhihu.com).里面说得很明白。

血的教训:指令表示直接跳转到 0x402470 + M*8 所存储的地址处(而不是 0x402470 + M*8 处!!!)

然后就随便设第一个数小于等于7,第二个数根据跳转位置取。比如0 207

4.phase_4

同样,改input.txt,再phase_4打断点,调试

在这里插入图片描述

跟phase_3开局有点像,不过第一个炸弹避免要同时①②

在这里插入图片描述

同理,第一个整数要小于等于0xe

在这里插入图片描述

然后调用func4函数,参数edi为第一个整数,esi为0,edx为0xe。然后要求返回值为0,且第二位整数为0。所以尝试在func4打断点,且第二位整数设为0.

在这里插入图片描述

是个递归,得找到出口。有两个出口。

// 参数a b c(分别%edi %esi %edx); ret(%eax); d(%ecx)
ret = c - b
d = ret
d >>= 31
ret += d
ret >>= 1
d = b+ret

if(d>=a)
{
	ret = 0;
	d = a;
	return;
}else
{
	c = R[%rcx] - 1
	call func4()
	ret = 0;
	if()...
	......
}

手把手教你拆解 CSAPP 的 炸弹实验室 BombLab - 知乎 (zhihu.com) <——还是别人讲得好,主要是我感觉我太会分析这个递归,也是看别人答案懂的

答案为7 0

5.phase_5

老操作,打断点,调试

在这里插入图片描述

字符串长度应该为6
在这里插入图片描述

感觉是个循环,41和117间,两个出口,中间一个炸弹,一次回跳。

①那里%eax存的是总的字符串是否相等,不相等直接bomb,相等跳出。所以会到程序找对%rdi和%rsi相关的

在这里插入图片描述

对%esi只有一处,显然那里就是正确答案吗?(我也被坑到了)。回忆下前面做了些什么。

在这里插入图片描述

%rbx入栈,%rsp-0x20,先开辟空间,%rbx=%rdi自己输入的字符串。%eax=0然后循环计数,一开始 %rbx 中存储的是用户输入字符串,逐个取出字符,只保留最低四位后存放在 %rdx 中,然后又存回去(%ecx存每个字符,%c1是其低位)。就是只要每个字符的低四位,作为某个字符串(下图)的下标。

CSAPP:BombLab 详细解析_csapp bomblab-CSDN博客这篇也不错

所以事情是这样的,答案确实是flyers,毕竟strings_not_equal是拿它去比较,但你的输入字符串会被程序选取一部分去比较,选取规则如上。

在这里插入图片描述

然后就是对应字母算下标当做低四位,再返回ascii码表找。我就借鉴别人答案ionefg

6.phase_6

老操作,打断点,调试。然后发现好长,打算$ objdump -d [name of executable] > [any file name]把改段输入到文本文件中,然后逐一分析。

objdump -d bomb | grep -A50 "<phase_6>:" > phase_6.txt

我觉得手动模拟每一段+手写画图可能会清晰很多

在这里插入图片描述

在这里插入图片描述

第一段从 4010f4——> 40110b——> 40112,第一段是初始状态,第二段证明第一位整数必须小于等于6

在这里插入图片描述

①②遍历第二个到第六个数字,要求它们均与第一个数字不相等,不然就引爆炸弹。然后%r13=%rsp+0x3后又跳上去了。重复证明第整数必须小于等于6,故 6 个数字是 1、2、3 、4、5、6 的排列组合之一。一个双重循环。

在这里插入图片描述

后面我用我直接b * 401153,然后跳出循环,但寄存器的值不清楚,于是我用layout regs辅助看。又是一个循环a[i] = 7 - a[i]。

然后直接像后跳到+163,一下子给我整蒙了,无条件跳转,后面还有往前跳+130,估计又是个循环,继续先模拟,然后我不会了。0x40116f0x4011a9这一段看得我脑壳秃。存的是地址

在这里插入图片描述

对0x6032d0手把手教你拆解 CSAPP 的 炸弹实验室 BombLab - 知乎 (zhihu.com)分析,在那里1-6顺序链表存着。

在这里插入图片描述

然后后面就是连接操作

在这里插入图片描述

最后这里应该是个逐个比较,注意是取四个字节,要求是a对应的节点内容>b…(b…>c…依次类推)。根据“L/001”中节点中大小排序,就是node3 node4 node5 node6 node1 node2,看样子应该是3 4 5 6 1 2,但前面a[i]=7-a[i],复原就是4 3 2 1 6 5

三、小结

1.感觉自己好水,总是忍不住看别人的题解。phase_1-phase_6我没有一个是独立做出来的。到phase_6的时候我意识到自己的问题,耐心不够。于是在phase_6那段,好好沉下心花了2个小时左右分析了0x40116f0x4011a9还有后面的构造。然后又浮躁了。我感觉给我最大的收获是发现自己的浮躁(要区分拖沓)。知道后面还有个隐藏关卡,但就是耐不下性子,只能作罢。我觉得这个系列实验有必要再做一次,但不是现在。

2.然后就是技能上的收获。①是知识点汇编②是gdb等工具的使用熟练度++。

数据治理是确保数据准确性、可靠性、安全性、可用性和完整性的体系和框架。它定义了组织内部如何使用、存储、保护和共享数据的规则和流程。数据治理的重要性随着数字化转型的加速而日益凸显,它能够提高决策效率、增强业务竞争力、降低风险,并促进业务创新。有效的数据治理体系可以确保数据在采集、存储、处理、共享和保护等环节的合规性和有效性。 数据质量管理是数据治理中的关键环节,它涉及数据质量评估、数据清洗、标准化和监控。高质量的数据能够提升业务决策的准确性,优化业务流程,并挖掘潜在的商业价值。随着大数据和人工智能技术的发展,数据质量管理在确保数据准确性和可靠性方面的作用愈发重要。企业需要建立完善的数据质量管理和校验机制,并通过数据清洗和标准化提高数据质量。 数据安全与隐私保护是数据治理中的另一个重要领域。随着数据量的快速增长和互联网技术的迅速发展,数据安全与隐私保护面临前所未有的挑战。企业需要加强数据安全与隐私保护的法律法规和技术手段,采用数据加密、脱敏和备份恢复等技术手段,以及加强培训和教育,提高安全意识和技能水平。 数据流程管理与监控是确保数据质量、提高数据利用率、保护数据安全的重要环节。有效的数据流程管理可以确保数据流程的合规性和高效性,而实时监控则有助于及时发现并解决潜在问题。企业需要设计合理的数据流程架构,制定详细的数据管理流程规范,并运用数据审计和可视化技术手段进行监控。 数据资产管理是将数据视为组织的重要资产,通过有效的管理和利用,为组织带来经济价值。数据资产管理涵盖数据的整个生命周期,包括数据的创建、存储、处理、共享、使用和保护。它面临的挑战包括数据量的快速增长、数据类型的多样化和数据更新的迅速性。组织需要建立完善的数据管理体系,提高数据处理和分析能力,以应对这些挑战。同时,数据资产的分类与评估、共享与使用规范也是数据资产管理的重要组成部分,需要制定合理的标准和规范,确保数据共享的安全性和隐私保护,以及建立合理的利益分配和权益保障机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值