CSAPP Lab 2 Bomb小记二

哈尔滨工业大学CSAPPLAB2二进制炸弹详解 哈尔滨工业大学计算机系统LAB2 一,实验基本信息 1.实验目的 拆炸弹,了解汇编 and fun 2.实验环境与工具 2.1硬件环境 Intel i7-i0875H 64位处理器 RTX2070 2.2软件环境 Windows11 & Ubuntu 20.04 64位 2.3 开发工具 vscode IDA pro gdb(peda) 二,各阶段炸弹的破解与分析 1.初步分析 在gdb环境下安装peda或者pwndbg都会大大提高工作效率,工作界面友好很多 peda 阅读详情

接着上一篇文章,我们来继续分析几个phase

实验过程

phase 4 破解

反汇编代码:
在这里插入图片描述
设置断点:
在这里插入图片描述
执行程序:
在这里插入图片描述
分析汇编:
446:压栈
447:传入的第二个参数%rcx
448:传入的第一个参数%rdx
449:输入” %d %d”
450-453:输入个数为2
454-457:判断输入的第一个参数的大小,该数需小于等于14,且被初始化为14
458:%esi值为0
459:%edi的值等于刚输入第一个参数的值
460:调用func4,大致上浏览一遍函数,找到传入func4的参数:%edi,%esi,%edx
我们把这三个参数分别设为x,y,z;产生的中间变量有%ecx,%eax,将它们分别设为t和m。
在这里插入图片描述
则分析func4可以得到C语言的函数: 这是一个递归调用的函数
PS:下面的函数是我在第一次做的时候错误代码示例,没有理解递归含义

int func4 (int x, int y, int z)
/* x in %rdi, y in %rsi, z in %rdx, m in %rcx, t in %rax
  y的初始值为0,z的初始值为14 */
{
  int t = z - y;
  int m= t>>31;
  t= (t + m)>>1;
  m= t + y;
  if( m > x){
  z= m – 1;
  func4( x, y, z);
  t = 2*t;  **这里的t应该是递归调用的func4的返回值,而不是上面的t**
  return t;}
  else{
  t = 0;
  if( m < x){
  y = m +1;
  func4( x, y, z);
  t = 2*t + 1; **同理,这里的t应该是递归调用func4的返回值,而不是之前的t**
  return t;}
  else return t; }
}

编写正确的函数并测试:

int func4(int x, int y, int z)
{
 int t = z - y;
 int m = t>>31;
 t =(t + m)>>1;
 m = t + y;
 if(m > x){
 z = m - 1;
 return 2*func4( x, y, z);
 }
 else{
 t = 0;
 if(m < x){
 y = m + 1;
 return 2*func4(x, y, z) + 1;
 }
 else
 return t;
 }
 
int main()
{
 for(int i=0;i<=14;i++)
  {
     if(func4(i,0,14)==0)
       printf("%d\n",i);
   }
   return 0;
}

结果为:
在这里插入图片描述
则phase_4实现了对func4的递归调用,其中func4的第一个参数取值为0-14,第二个参数初始化为0,第三个参数初始化为14。最终得到一个使得func4递归调用的返回值为0的结果输出。
可输入的结果有:0 0 / 1 0 / 3 0 / 7 0
举几个例子:
在这里插入图片描述
在这里插入图片描述
phase 4成功破解!

phase 5破解

反汇编代码:
在这里插入图片描述在这里插入图片描述
设置断点
在这里插入图片描述
执行程序
在这里插入图片描述
分析汇编:
477:调用string_length函数查看输入字符串的长度
478-480:输入字符串的字符数必须为6,跳转
在这里插入图片描述
设置%eax为0(字符计数器),跳转
在这里插入图片描述
由前面的汇编代码知,%rcx中存放第一个字符的地址
8b:%ecx的值为%rbx + %rax (对于第一个字符来说,%rax为0),即存放第 %rax 个字符的地址。
8f-92:将第 %rax 个字符的低八位放入%rdx中。
96:取%rdx的低四位
99:%edx的值为 0x4024b0 + %rdx(低四位),即以0x4024b0为基地址,%rdx 为偏移寻找到的地址的值放入%edx中。
a0:将%edx的低八位放入内存%rsp + 0x10 + %rax处
a4:%rax 的值加1(计数器),即将开始对第二个字符的操作。
则六个字符串经过变换后产生的数值依次存储在内存 (%rsp+0x10)(%rsp+0x11)(%rsp+0x12)(%rsp+0x13)
(%rsp+0x14)(%rsp+0x15)中。

a8-ac:判断计数器内的值是否为6,若不为6则继以上续循环。直至等于6,继续执行。
在这里插入图片描述
b3:查看%esi中的值对应的字符串
在这里插入图片描述
b8:将数值串的首地址存入%rdi中
bd:调用string_not_equal函数判断输入字符与给定字符是否相等
这里注意,因为我们传入的参数是一些十六进制的数值,与给定字符串进行比较事,要比较的是二者的ASCII码值,若相等,成功跳出函数。
于是关键来了,怎样找出比较的数呢?我们知道,在ASCII码表中,从64-90(0x41-0x5a)是大写英文字母,从97-122(0x61-7a)是小写英文字母。那么给定字符串的ASCII码值都是八位数值(低八位)。这与之前分析的%edx的低八位正好能用来比较。
那么首先将给定字符串的ASCII码找出:
在这里插入图片描述
接着查找以0x4024b0为基地址的查找表的表项:
在这里插入图片描述
若要使得%edx的低八位与与给定字符串的数值相同,则需要在查找表中寻找对应的项。
0x66:位于查找表偏移为0x9的位置
0x6c:位于查找表偏移为0xF的位置
0x79:位于查找表偏移为0xE的位置
0x65:位于查找表偏移为0x5的位置
0x72:位于查找表偏移为0x6的位置
0x73:位于查找表偏移为0x7的位置
回溯:
偏移值为%rdx的低四位
%rdx的低八位对应第 %rax 个字符
则:低四位为0x9的字符:0x49 ( I ) 0x59 ( Y ) 0x69 ( i ) 0x79 ( y)
0xF :0x4F ( O ) 0x6F ( o )
0xE :0x4E ( N ) 0x6E ( n )
0x5 :0x45 ( E ) 0x55 ( U ) 0x65 ( e ) 0x75 ( u )
0x6 :0x46 ( F ) 0x56 ( V ) 0x66 ( f ) 0x76 ( v )
0x7 :0x47 ( G ) 0x57 ( W ) 0x67 ( g ) 0x77 ( w )
将这些字符进行组合,输入。
在这里插入图片描述
phase_5 破解!

phase 6 破解

反汇编代码:
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
设置断点:
在这里插入图片描述
执行程序
在这里插入图片描述
分析汇编:
/* %rbp %rbx %r12~%15 被调用者保存寄存器
%r10 %r11 调用者保存寄存器
%rdi %rsi %rdx %rcx %r8 %r9 依次保存输入数1~6 */
512-516:入栈(被调用者)
517:创建栈帧(注意空间大小为0x50)
518:%r13保存%rsp的地址
519:%rsi保存%rsp的地址
520:调用reab_six_numbers函数读入六个数字
521:%r14保存%rsp的地址
522:将%r12的值置为0
523:%rbp保存%rsp的值
查找%rsp存储的地址:(第一个为创建栈帧前,第二个为创建栈帧后)

在这里插入图片描述
524:%eax的值为%r13存储地址在内存单元中的值
525-528:判断%eax的值,即存储在(%rsp)中的值,该值必须小于等于6。
529:%r12的值加1
530-531:比较%r12的值,若%r12等于6,跳转;不等于6,继续执行
(1) 若%r12不等于6
在这里插入图片描述
将%r12符号扩展的值传递给%rax
将 %rsp + 4*%rax代表的地址中存储的数复制到%eax中(从这里我们可以猜测%r12代表的是循环条件 类似于 i=0;i<6;i++)
比较两个数大小: %eax(注意在第529行%r12加1,代表相对于当前数的下一个数,则这里%eax中的数为下一个数的数值)和 %rsp存储地址的数值(即第一个数)
两个数大小必须不相等,否则bomb。
在第一个数与第二个数不相等的情况下,
%ebx加1,此时%ebx值为2
判断%edx的值:若%edx小于等于5,则跳转;大于5,继续执行
(a) 若%ebx小于等于5
%edx的符号扩展的值传递给%rax
将第三个数存入%eax
第三个数与第一个数比较,两数不等
%ebx加1,判断
依次比较其他数与第一个数,确保与第一个数不等
(b) 若%edx大于5,即所有其他数与第一个数的比较结束
%r13加4,则%r13指向第二个数的地址
跳转到*0x401114
在这里插入图片描述
将第二个数的地址传入%rbp
将第二个数值传入%eax
传入的数值要小于等于6
%r12加1,即此时%r12的值为2(结合前面分析,%r12代表被比较的是第%r12个数)
之后则为第三个数与第二个数比较,第四个数与第二个数比较…….
直到全部数值比较完毕,实现输入的六个数字两两各不相同的作用
相当于C语言的函数(有助理解,不是规范代码)

bool  num_not_equal ( int a[ ] )
{  
   for ( int i=0; I !=6; i ++)
     {
        int j = i +1;
        for (  ; j <=5; j++)
           {
             if( a[ i-1 ] == a [ j ])
                 return false;
            }
     } return true;
}

(2) 若%r13等于6,则跳出循环。跳转到0x401153
在这里插入图片描述
地址%rsp+0x18正好指向输入数字存储区域之外,将该地址复制到%esi,%esi将作为条件结束的标志
将%r14(即%rsp)存储的地址复制到%rax
将%edx的值置为7
用7减去%rsp中存储的值(即第一个数),并将差放入原来输入数值的存储单元中
%rax加4,则%rax指向下一个数(第二个数)
判断结束条件,若未结束,跳转到0x401160
继续用7减去第二个数,将结果存入第二个数原来的存放单元
以此类推,以所有数分别为减数,7为被减数,得到的差存入内存单元。
循环结束,即%rax等于%rsi时,继续执行
在这里插入图片描述
将%esi的值置为0
跳转到
0x401197
在这里插入图片描述
在这里插入图片描述
将位于地址%rsp + %rsi中的数(即各个内存单元内存储的数)存入%ecx中
比较该数与1,若该数小于等于1,跳转;大于1继续执行
(1) 若%ecx小于等于1
在这里插入图片描述
在这里插入图片描述
将%edx的值设置为地址0x6032d0(重置链表)
从%rsp+0x20处开始,将%rdx的值放入后者地址对应的内存单元中(创建链表节点)
%rsi加4,即指向下一个内存单元中的数
判断创建链表是否完成,若完成跳转;未完成,继续执行。
(a) 若创建未完成
在这里插入图片描述
将地址为%rsp +% %rsi处存储的值(第一个数)放入%ecx中,比较该数与1
若该数小于等于1,同样地将0x6032d0放入%rdx中,重置链表
这里的循环操作是为了建立一个以0x6032d0为首地址的链表结构,且链表中的索引值按顺序排列存储
关键部分:
在这里插入图片描述
在这里插入图片描述
这部分操作的目的即为将第n个node的地址存入对应索引n的内存单元
在这里插入图片描述
(b) 创建完成,跳转到*0x4011ab
在这里插入图片描述
%rbx存储第一个node的地址对应的内存单元的地址
(由前面可知内存单元存放的是节点地址),
%rax存储第二个node的地址对应的内存单元的地址,
%rsi存储最后一个node的地址对应的内存单元的地址(判断结束)
将%rbx的值复制给%rcx
将%rax存储地址对应的值(即第二个node的地址)放入%rdx中
关键步骤:将第二节点的地址放入第一个节点的后八个字节
%rax加8,即下一个node,以此类推,将链表连接起来。
判断是否结束,若结束跳转;未结束则继续执行

创建完成,查看链表情况:
在这里插入图片描述
我们可以发现链表的每个节点占16个字节,后八个字节为链表的下一个节点地址
前八个字节的最后四个字节存储值看起来跟索引值有关(即前面得到的7-输入数得到的差)
画个图表示一下:
在这里插入图片描述
查看链表中各节点存储情况:
在这里插入图片描述
在这里插入图片描述
我们可以发现,每个节点的最高四个字节存储着一些数值。此时不能确定该数值是什么,我们继续往下看。
创建链表结束,跳转到*0x4011d2
在这里插入图片描述
第六个节点指向的值为0
%ebp的值置为5
将第六个节点地址放入%rax
对应的值(这里的值就是之前我们不知道不清楚的存在node中的值)放入%eax
若第五个节点指向值大于第六个节点指向值,(必须大于)
将第六个节点与第五个节点交换(节点指向值大的放前面)
%ebp减1
进入循环(%ebp不等于0),直到%ebp为0
则这部分汇编检查链表中的数据是否为降序排列。
分析到这里,我们已经非常清楚phase_6在干什么了
(1) 输入六个数字,记为ai
(2) 用7分别减去这六个数字,得到的值记为bi
(3) 以bi为索引,创建节点,连成链表
(4) 将链表中的数据降序排列
(5) 成功执行
回溯流程:存储的数据降序排列
在这里插入图片描述
降序排列后
在这里插入图片描述
此时节点值按顺序为 3 4 5 6 1 2
注意这些值为前面得到的7-输入数得到的差
则原来输入的数应为:
4 3 2 1 6 5

在这里插入图片描述
phase_6破解!

csapp实验二 ---bomb(第四关) 再接再厉 来到第四关 gdb bomb disas phase_4 看一看到什么东西送到esi并且做为sscanf的第二个输入 先看下是什么 (gdb) x/s 0x4025cf 0x4025cf: "%d %d" 那么这题就是输入两个数 接下来判断第一个数小于等于14我们才能接着游戏 调用func4 入口参数 第一个参数 第一个数 第二个参数... 阅读详情

相关推荐

sid图像数据_遥感影像数据

影像数据基本概念影像数据是由卫星或飞机上的成像系统获得的影像,多为遥感影像数据。影像数据的每个像元都有一个值,表示传感器探测到像素对应地面面积上目标物的电磁辐射强度,也叫亮度值、灰度值。SuperMap支持的影像数据格式有:*.img、*.tif、*.tiff、*.bmp、*.jpg、*.png、*.gif、*.raw、*.sid等。计算机以二进制记录数据,所以其量化的等级以二进制来划分,即2n。...

weixin_39534395的博客 1626

CSAPP Lab2

高质量解析 https://www.cnblogs.com/wulichenai/p/14130721.html https://www.zybuluo.com/SovietPower/note/1786675#hints https://zhuanlan.zhihu.com/p/339461318 Phase_1 0000000000400ee0 <phase_1>: 400ee0: 48 83 ec 08 sub $0x8,%rsp 400ee4: be

qq_43457051的博客 660

10-142 6-4 查询厂商“D“生产的PC和便携式电脑的平均价格

分数 10全屏浏览题目切换布局作者 lhm单位 河北农业大学本题目要求编写SQL语句,查询厂商D生产的PC和便携式电脑的平均价格。

dqd66的博客 2748

csapp bomb lab phase_4

随着课程的深入,笔者发现实验基本是延续着上课的进程来的,包括之前利用jump table 实现了switch的编译。 这一小节采用的知识点是函数(procedure)与递归(recurison),写到这里,笔者觉得CSAPP课程编排真的挺不错,通过实验来强调知识点,所以说,单单看书必然是事倍功半,因为书势必追求完备性,对初学者而言,很难抓到汇编语言部分的重点,而视频可以稍微集中一下知识点,老师的...

qq_36672987的博客 3412

【Unity】【模型】【AI建模】如何将AI生成的GLB格式3D模型文件导入Unity

本文介绍了一个将AI工具自动生成的GLB格式3D模型文件转换成fbx模型文件导入Unity的步骤。

O青草O的博客 Unity和游戏制作知识分享 1358

KANO分析模型

KANO分析模型的基本概念,目的意义,应用场景,实现方法和示例等

JasonH2021的博客 3066

BUPT CSAPP lab2二进制炸弹

一、实验目的 1.理解C语言程序的机器级表示。 2.初步掌握GDB调试器的用法。 3.阅读C编译器生成的x86-64机器代码,理解不同控制结构生成的基本指令模式,过程的实现。 二、实验环境 1.SecureCRT(10.120.11.12) 2.Linux 3.Objdump命令反汇编 4.GDB调试工具 5.Xshell 软件 三、实验内容 登录bupt1服务器,在home目录下可以找到Evil博士专门为你量身定制的一个bomb,当运行时,它会要求你输入一个字符串,如果正确,则进入下一关,继续要求你输入下

qq_52606374的博客 6754

Hiblup入门指南:从下载到基础应用

本文是Hiblup软件的入门指南,详细介绍了这款遗传评估工具的核心功能与价值。Hiblup能整合系谱、基因组和表型数据,高效计算估计育种值,助力动物育种与植物遗传改良研究。文章从软件下载安装、数据格式准备,到运行系谱BLUP和基因组BLUP分析,提供了清晰的实战步骤与命令示例,帮助用户快速上手并应用于实际科研与育种工作。

weixin_29209825的博客 495

CSAPP LAB2 BombLab

CSAPP LAB2 BombLab给一个可执行文件,需要按顺序输入6个字串,每个字串是一个小炸弹的密码。通过反汇编找出每个字串的内容。考察汇编语言,gdb的使用。关于GDB的使用 终端下输入gdb进入GDB,使用file <文件名>加载二进制文件,加载后只是读取符号表,并不执行。使用set args <参数>给程序设置参数,可以为空(我遇到了没设置参数,但参数不为空的情况>_<,所以还是清一下参数

P.H.S 1823

Python开发者必看:5分钟搞定Gemini API的3种调用方式(含代码示例)

本文为Python开发者详细介绍了三种高效调用Gemini API的核心方式:基础同步调用、流式调用和聊天模式,并涵盖多模态应用等高级特性。通过清晰的代码示例和实战场景分析,帮助开发者快速掌握Gemini API的集成与优化,提升AI应用开发效率。

g8f9d0s1a2的博客 1122

【时时三省】vector cast (vcast) 集成测试使用教程

山不在高,有仙则名。水不在深,有龙则灵。----优快云 时时三省。

时时三省的博客 708

CSAPP Lab2 Bomb小记一

实验概述 这是一个非常有趣的实验,实验以通关(phase)的形式来呈现汇编语言学习的重点与难点,并且一环扣一环,除了必须要经过的六个phase外,还有一个secret phase,接下来我们看一下如何破解这些phase。 实验过程 首先,输入命令objdump -d bomb > bomb_assembly.S,得到bomb_assembly.s反汇编文件。 之后在终端用gdb对bomb.c进行调试。 phase 1破解 首先给出phase 1的反汇编代码: 347: 压栈 348:将0x402

code120302的博客 358

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

CSAPP Lab 2 Bomb小记三

在前面两篇文章中,我们已经分析完了六个phase,接下来分析最后一个phase。 实验过程 secret phase 破解 在此之前,我们分析bomb.c文件,发现一件有趣的事情: 在文件执行的过程中,我们似乎并没有察觉到phase_defused()函数的动静,接下来我们看看这个函数干了什么。 这里要注意: 这是一个防止栈溢出的操作。把%fs段偏移0x28处的一个数据存储到了%rsp上面0x68距离处(金丝雀) 903:将%esi置为0x402619,查看其代表含义 为输入两个数字和一个字符串,

code120302的博客 266

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

CSAPP lab2 bomb(深入了解计算机系统 实验二)

这个问题还得用GDB调试来做。截图做笔记吧,实在写不动了!1.执行反汇编 obj-dump -D bomb > mysrc.S 得到可执行文件的机器级程序(汇编文件)。2.搜索main(每一个应用程序都是从main函数开始) 找到如下内容:0000000000400da0 <main>: 400da0: 53 push %rbx 400

lzjsqn的专栏 1万+

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

csapp lab2 bomb

前置知识 你最好知道e前缀和r前缀的区别,推荐阅读《X86-64寄存器和栈帧》。 对gdb常见命令有所了解。 懂得常见的ATT格式的汇编指令。 lab主页:http://csapp.cs.cmu.edu/3e/labs.html 准备工作 下载一个实验文件,网上有,如果找不到可以用我的。 https://download.youkuaiyun.com/download/w55100/...

w55100的博客 2438

CSAPP——Lab2——Bomb Lab

本篇博客是《深入理解计算机系统》实验记录的第二篇,也是非常有名的炸弹实验。首先吐槽一下学校的这个实验代码不更新的问题,教材和上课讲授的均是x86-64位汇编语言,结果实验给的还是第二版配套的32位汇编语言,这两者之间有不少的差别,为此还查阅了一些关于32位汇编的资料自己学习(例如32位的参数传递规则和64位不同),这无疑增加了学习成本。 接下来进入正题,我领取的代码包是第19号,即bomb19。后来发现不同人领取的代码包实验题目虽不同,但解决思路大体相同,答案也是不一样的。不知为何,我感觉我的实验包好像难度

zheyuan的博客 2133

CSAPP 六个重要实验 lab2

哈哈~ 不愧是“美国进口的六级炸弹”!爽歪歪的“升级打怪” 我把实验材料都上传到下面这个link了,0分下载(良心啊~)

Jason Leaster | Rebuilding the tower of babel 1万+

深入浅出GNU X86-64 汇编

深入浅出GNU X86-64 汇编本文是我翻译自 Introduction to X86-64 Assembly for Compiler Writers. 因为之前在学校学的X86汇编都是32位的,而现在的PC机处理器基本都是64位的,我的Linux机器也是64位的,反汇编C语言时,生成的是64位汇编,所以翻译一下这篇文章。这篇文章深入浅出的描述了C和X86-64汇编的转换关系。目录深入浅出GNU

pro_technician的专栏 2万+

linux lea 0x18(%r12),%rbx,CSAPP: Bomb Lab 实验解析

这是CSAPP课本配套的第二个实验,主要任务是“拆炸弹”。所谓炸弹,其实就是一个二进制的可执行文件,要求输入六个字符串,每个字符串对应一个phase。如果字符串输入错误,系统就会提示BOOM!!!。解决这次实验需要将二进制文件反汇编,通过观察理解汇编语言描述的程序行为来猜测符合条件的字符串。Linux & GDB Basic Commands反汇编指令:objdump -d [objfil...

weixin_39973416的博客 2757

CSAPP lab2 二进制拆弹 binary bombs phase_4

给出对应于7个阶段的7篇博客 phase_1 https://www.cnblogs.com/wkfvawl/p/10632044.htmlphase_2 https://www.cnblogs.com/wkfvawl/p/10636214.htmlphase_3 https://www.cnblogs.com/wkfvawl/p/10651205.htmlphase_4 ht...

weixin_30745641的博客 685

csapp bomb lab phase_2

一.承接上一篇文章,接下来是解决bomb的phase_2的问题     首先我们看看phase_2的汇编代码,上文已经提到了反汇编指令disas (dis assemble) phase_2(函数名)    其中有个函数名是否值得注意,&lt;read_six_numbers&gt;,显然,这个函数需要我们读入6个数字作为密码。 (作者一开始在0x400f0e处设置过断点,但是在run时,...

qq_36672987的博客 1920
上一篇: CSAPP Lab2 Bomb小记一
下一篇: CSAPP Lab 2 Bomb小记三
code120302
博客等级 码龄7年 195粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值