Csapp_lab2

 

 

 

实验报告

 

实 验(三)

 

 

题 目 Binary Bomb

二进制炸弹    

专 业 英才自动化

学   号 

班   级 

学 生 

指 导 教 师 

实 验 地 点 

实 验 日 期 

 

计算学部

 

目 录

 

1实验基本信息    - 3 -

1.1 实验目的    - 3 -

1.2 实验环境与工具    - 3 -

1.2.1 硬件环境    - 3 -

1.2.2 软件环境    - 3 -

1.2.3 开发工具    - 3 -

1.3 实验预习    - 3 -

2实验环境建立    - 5 -

2.1 UbuntuCodeBlocks反汇编(10分)    - 5 -

2.2 UbuntuEDB运行环境建立(10分)    - 5 -

3各阶段炸弹破解与分析    - 7 -

3.1 阶段1的破解与分析    - 7 -

3.2 阶段2的破解与分析    - 7 -

3.3 阶段3的破解与分析    - 8 -

3.4 阶段4的破解与分析    - 8 -

3.5 阶段5的破解与分析    - 9 -

3.6 阶段6的破解与分析    - 10 -

3.7 阶段7的破解与分析(隐藏阶段)    - 12 -

4总结    - 14 -

4.1 请总结本次实验的收获    - 14 -

4.2 请给出对本次实验内容的建议    - 14 -

参考文献    - 15 -

 

 

 

 

第1章 实验基本信息

 

1.1 实验目的

熟练掌握计算机系统的ISA指令系统与寻址方式

熟练掌握Linux下调试器的反汇编调试跟踪分析机器语言的方法

增强对程序机器级表示、汇编语言、调试器和逆向工程等的理解

1.2 实验环境与工具

1.2.1 硬件环境

Cpu: AMD Ryzen 5800H

Gpu: Nvidia RTX 3070

1.2.2 软件环境

    版本    Windows 11 专业版

版本    21H2

操作系统版本    22000.613

体验    Windows 功能体验包 1000.22000.613.0

 

虚拟机:vmware16pro

虚拟系统:ubuntu 20.04

1.2.3 开发工具

Visual studio, codeblocks, gdb, edb

1.3 实验预习

上实验课前,必须认真预习实验指导书(PPTPDF

了解实验的目的、实验环境与软硬件工具、实验操作步骤,复习与实验有关的理论知识。

请写出C语言下包含字符串比较、循环、分支(含switch)、函数调用、递归、指针、结构、链表等的例子程序sample.c

生成执行程序sample.out

gcc SCodeBlocksGDBOBJDUMP等,反汇编,比较。

列出每一部分的C语言对应的汇编语言。

修改编译选项-O (缺省2)O0O1O3Og-m32/m64。再次查看生成的汇编语言与原来的区别。

注意O1之后缺省无栈帧,RBP为普通寄存器。用 -fno-omit-frame-pointer加上栈指针。

GDB命令详解tui模式 ^XA切换 layout改变等等

有目的地学习: VS的功能,GDB命令用什么?

 

 

 

第2章 实验环境建立

 

2.1 Ubuntu下CodeBlocks反汇编(10分)

CodeBlocks运行hello.c。反汇编查看printf函数的实现。

要求:CASM、内存(显示hello等内容)、堆栈(call printf前)、寄存器同时在一个窗口。

 

2-1 UbuntuCodeBlocks反汇编截图

 

2.2 Ubuntu下EDB运行环境建立(10分)

EDB调试hello.c的执行文件,截图,要求同2.1

2-2 UbuntuEDB截图

 

 

第3章 各阶段炸弹破解与分析

每阶段30分,密码10分,分析20分,总分不超过80分

3.1 阶段1的破解与分析

密码如下:When a problem comes along, you must zip it!

破解过程:phase_1调用了strings_not_equal函数来检查输入的字符串和密码之间是否相等,并且把地址$0x403150作为参数给该函数,推测密码就在该地址内。

3.2 阶段2的破解与分析

密码如下:0 1 3 6 10 15(答案不唯一,为首项大于等于0且相邻两项差依次递增的数列)

破解过程:观察反汇编的phase_2。初始几句是常规的栈保护,直到出现

    callq 4018da <read_six_numbers>

说明调用了read_six_numbers函数来读取六个数,猜测密码为六个数,而%rsi为作为参数传递给该函数,寄存着%rsp的值,说明六个数存储的地址从栈顶开始。

cmpl $0x0,(%rsp)        0与第一个数比较,小于0则引爆,说明第一个数大于等于0。之后进入循环,注意关键语句

add (%rsp,%rdx,4),%ecx

cmp %ecx,(%rsp,%rax,4)

je 401430 <phase_2+0x26>

%ecx每个循环都在按1递增,这三句比较了后项与前项是否相差%ecx,则可以得知密码为首项大于等于0,相邻两项差从1递增的六项数列。

首项为1时拆炸弹

首项为0时拆炸弹

3.3 阶段3的破解与分析

密码如下:0 984(或1 5112 5303 7154 1735 5676 2837 384

破解过程:    mov $0x40330f,%esi

%esi存储的地址作为参数给sscanf函数,通过查询发现该地址存储的参数为,说明密码由两个数构成。

mov 0xc(%rsp),%eax

cmp $0x7,%eax

ja 4014c8 <phase_3+0x75>

检验第一个数小于等于7

jmpq *0x4031b0(,%rax,8)说明跳转表存储在0x4031b0中,查看该地址

发现跳转表存储着8中情况对应的跳转地址,经过计算就是答案。

3.4 阶段4的破解与分析

密码如下:8 35

破解过程:    mov $0x40330f,%esi

该地址作为参数传递过sscanf函数,查看,发现密码应该为两个数。

mov 0xc(%rsp),%eax

test %eax,%eax

js 401543 <phase_4+0x2f>

cmp $0xe,%eax    

jle 401548 <phase_4+0x34>

这五句说明第一个数在114之间

mov $0xe,%edx    

mov $0x0,%esi

mov 0xc(%rsp),%edi    

callq 4014e2 <func4>

这三个寄存器的值作为参数传递给func4,而观察func4可以写出其代码

  1.  int a = 0;  
  2.  int edx = 0;  
  3.  int edi = 0;  
  4.  int esi = 0;  
  5. int func4() {  
  6.     a = edx;  
  7.     a = a - esi;  
  8.     int b = a;  
  9.     b = b >> 31;  
  10.     b = b + a;  
  11.     b = b >> 1;  
  12.     b = b + esi;  
  13.     if (b > edi) {  
  14.         edx = b - 1;  
  15.         func4();  
  16.         b = b + a;  
  17.     }  
  18.     else if (b < edi) {  
  19.         esi = b + 1;  
  20.         func4();  
  21.         b = b + a;  
  22.     }  
  23.     a = b;  
  24.     return a;  
  25. }  

cmp $0x23,%eax要求返回值为35,经过尝试8满足条件。

    cmpl $0x23,0x8(%rsp)要求第二个值为35,则密码为8 35.

3.5 阶段5的破解与分析

密码如下:

ans1

) 9 I Y i y

ans2

/ ? O _ o

ans3

. > N ^ n ~

ans4

% 5 E U e u

ans5

& 6 F V f v

ans6

' 7 G W g w

6个字符的各种可能横向列出,可任意选择)

破解过程:

3.6 阶段6的破解与分析

密码如下:1 4 6 2 5 3

破解过程:phase_6的代码可以分为几个大块。

第一个大块是个双层循环,作用是确定输入的六个数只能是123456的排列组合。

第二块的作用是按照输入的数字将节点储存在栈顶。例如第一个数输入4则在栈顶储存node4,第二个数输入2则在栈顶的下一个区域储存node2。查看节点链表所在的内存区域:

第三块的作用是把储存在栈顶的结点依次起来,并依顺序比较节点储存的数是否小于下一节点的数。据此可以推荐堆栈内节点的顺序应该是node1node4node6node2node5node3.因此答案是1 4 6 2 5 3.

3.7 阶段7的破解与分析(隐藏阶段)

密码如下:35(四阶段字符串为DrEvil

破解过程:

炸弹的关键为secret_phase阶段的二叉树地址,根据地址查询到二叉树的数据,不难观察节点n包含自身的值和其中一个子节点地址,而n+16为节点n的另一个子节点地址。需要由func7输出6,逆推过程如下

 

 

第4章 总结

4.1 请总结本次实验的收获

熟悉了汇编语言,明白了循环在汇编语言里如何实现,同时熟悉了地址访问方式,加深了对函数传递参数的概念理解。

4.2 请给出对本次实验内容的建议

注:本章为酌情加分项。

 

参考文献

 

https://www.runoob.com/cprogramming/c-function-atoi.html

https://www.cnblogs.com/Tokubara/p/13909097.html

posted @   woshiybj  阅读(154)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示