CSAPP:bomblab
bomblab
Bomblab拆弹实录
准备工作
调试环境:
云主机Linux环境+GDB
ssh客户端:
xshell+xftp/putty+psftp
- xshell+xftp:上传和下载文件有可视化操作界面,直接拖拽就可以上传。但是在gdb调试的时候,输入了的数据不能修改,按回车会输入^H,有的时候会手误就要重新开始。
- putty+psftp:上传文件用scp命令(例如:scp hello.c xx@xxx.75.241.219/home/xx/lab0;scp -r 拷贝目录),下载文件可以用psftp。假设要下载到本地目录E:,在psftp中运行lcd E:\定位本地目录,putty切换到云主机目录之后,get 文件名即可下载。
Linux相关命令 :
- cd document切换到文件夹; cd …返回上一级目录;ls显示文件夹中的文件;pwd当前目录位置
- 解压:tar -xf all.tar,tar -zxvf filename.tar.gz
- cat filename 显示文件内容
- vim filename查看/编辑文件内容,i进入编辑模式,esc退出编辑模式,:wq保存并退出,:q没修改直接退出。
- 复制文件:cp document/file newdocument/newfile
- 重命名:mv oldname newname
GDB调试:
- 进入GDB调试状态,gdb filename;或先运行gdb再运行file filename
- info b看断点情况;b(reak) 行号/函数名 打断点;d (elete) 行号/函数名 删除断点
- i r看寄存器的值。info reg esp看%esp里存储了什么。print $eax。print (char*) $ebx。
- x/s 0xffff5330 打印该地址存储的字符串;x/16x 地址 答应之后16个字节的数字。
- s单步执行(不会进入被调用的函数内部),si单步执行(会进入被调用的函数内部)。c接着运行到下一个断点。
- display /ni $pc。用si调试每行都会显示下一行的汇编语言。
题目求解
phase_1:地址字符串
比较字符串是否相等,查看地址中预设的字符串即可。
phase_2:循环
读入六个数字做判断,读懂汇编语言,知道后一个数等于前两个数的加和即可。
phase_3:switch <7 每个数对应一个值
是一个switch函数,输入1-7会跳转到不同的地址,和事先存入的数字进行比较。有多个答案。
phase_4:
递归调用了func4()。首先输入的数字小于等于4。输入4,之后经过递归调用该函数得到216,最后和输入的第一个数字进行比较,所以第一个数字为216,第二个数字为4。应该有不同的答案。
// int func4(edi ,esi,ebx){//edi last,ebx last
%ebx=0x10(%esp) //8 //变成上次的eax,即7
%edi=0x14(%esp) //第二个参数
if ebx== 0 then return 0;
eax=edi
if ebx==1 then return eax
eax=ebx-1.
从头递归。
esi=edi+eax
ebx=ebx-2
从头递归。
eax=eax+esi
return eax
}
phase_5:
%ebx存放字符串。
x/100x 0x804a040 看这个地址之后存放了什么。理解地址代表的含义是关键。每个输入的字符取十六进制ASCII码的后一位*4+该地址,找到对应的数字,累加到%ecx。最后%ecx要等于41。反推出要输入的字母。
0:02;1:a;2:6;3:1;4:c;5:0x10;6:9;7:3;8:4;9:7;10:e;11:5;12:b;13:8;14:f;15:d
Prstux 2+6+1+12+16+4=41
phase_6:
读入6个数字,六个数字都<=6,六个数字互不相等。程序里事先存储了6个节点,六个节点有各自的编号,最后要从小到大输出,否则就爆炸。输入的6个数字代表,节点从小到大排列的顺序。
phase_6太长了,理解了好久,做到最后还挺崩溃的,只能说大胆假设,小心求证。理解地址代表的含义同样是关键,看到node要发挥想象力。
5 3 2 1 4 6
0x1d5
0x325
0x391
0x1c6
0x3a5
0xef
secret_phase:
secret phase要触发,首先要在phase_4处多输入一个字符串DrEvil。
首先输入的数字要小于等于1000,然后secret调用func7(),经过func7()之后必须为0。传入一个地址0x804c088,查看它就可以解开题目中预先存储的数据。整个条件判断类似二叉树的结构,要和根节点的值一致且要执行到末端,否则返回-1。又是递归。
这只是简要版解题思路,图片后续再补~
解开一个要缓一缓,然后发现跟后一个phase比起来,前一个简直是小case。发现做到最后最重要的其实是心态。
最后,有高级语言真好。