写在前面

在阶段4中的,我不得不承认,为了搞懂func4在搞什么,我还是花费了一些功夫的,主要原因是对其中几个汇编代码生疏,还特地上网查了一下。不过还好最后得出了答案!

本篇来看看phase_5,应该难度又有些上升了。

分析

同样的,先找到调用phase_5的汇编代码:

反汇编函数phase_5如下:

寄存器%rbx入栈,开辟0x20大小的栈空间。

mov    %rdi,%rbx,使寄存器%rbx指向我们的输入。

接下来的关于%fs:0x28的操作我们这里忽略,这是gcc做的一个栈保护检测机制。

接着调用函数string_length返回我们输入字符的长度,判断长度是否为6个字节,如果不是则触发炸弹。就是说phase_5对输入字符串的长度是有严格限制的,不想phase_2那样只要前面字节是正确的,后面的有没有都无所谓。

输入6字节长度的字符串后,跳转到0x00000000004010d2处执行。设置寄存器%eax值为0,再跳转到0x000000000040108b指定。

movzbl (%rbx,%rax,1),%ecx,对于这样的指令格式我们遇到不止一次了,可能有的人遇到这样的汇编指令会晕头转向,这里我简单说明下:众所周知,x86/x64 寻址方式众多,什么直接寻址、间接寻址、基址寻址、基址变址寻址等等让人眼花缭乱,而 AT&T 语法对内存寻址方式做了一个很好的统一,其格式为section:displacement(base, index, scale),其中section 是段地址,displacement 是位移,base 是基址寄存器,index是索引,scale 是缩放因子,其计算方式为线性地址=section + displacement + base + index*scale,最重要的是,可以省略以上格式中的一个或多个部分,比如 movw 4, %ax 就是把内存地址 4 中的值移动到 ax 寄存器中,movw 4(%esp), %ax 就是把 esp+4 指向的地址中的值移动到 ax 寄存器中,依此类推。

再补充一点,一般遇到这样格式的指令,都是在循环访问数组。这里就是典型的访问数组的案列,即我们输入的6字节字符数组。

取出一个字符传入寄存器%ecx中。

mov    %cl,(%rsp)

mov    (%rsp),%rdx

and    $0xf,%edx

这三行只需关注最后一行,即只取字符数值的低4位。例如字符'A',ascii码值为0x41,取低4位后得到0x01。

movzbl 0x4024b0(%rdx),%edx,又是访问数组,并且是用刚刚才算得的字符低4位数值作为索引来访问这个值。从movzbl得到这是个单字节数组,数组首地址是0x4024b0。我们使用x命令查看下这个数组的内容是什么。

观察,首先从array.3449命名上可以大胆测试,array是个局部静态字符数组。其次发现输出的内容的后半部分是在信号处理函数中使用过的,因此数组array的内容应该是前半部分。

接着往下看。

mov    %dl,0x10(%rsp,%rax,1),哈哈,看来今天是跟数组杠上了,这句又是在访问数组,而且是个局部单字节数组,数组首地址在%rsp + 0x10处,目前猜测这个数组至少6个字节大小。

接下来三条汇编指令,我们知道这是个循环的过程。

循环结束后,movb   $0x0,0x16(%rsp),将局部单字节数组第7个元素复制为0,所以我们可以得出这个局部数组至少7个字节大小。

最后又调用函数strings_not_equal来比较字符串,这个函数在phase_1中就已经分析过了。

待比较的两个字符串一个是刚刚的局部数组,一个是存储在地址0x40245e处的字符串,我们使用x/s查看是"flyers"。

如果不相等,则触发炸弹,否则OK。

好了,看来我们输入的6个字符是array数组的下标值。得到的6个字符必须是"flyers",得出这个结论就好办了,接下来就是数数游戏了。要得到字符"flyers",下标值必须依次为9、15、14、5、6和7。用16进制来表示的话,则为0x09、0x0f,0x0e,0x05,0x06和0x07。

也就是说我们输入的

第一个字符的低4位的值必须是0x09,查表得出字符')'、‘9’、‘I’、‘Y’、‘i’、‘y’符合条件。

第二字字符的低4位的值必须是0x0f,查表得出字符‘/’、‘?’、‘O’、‘_’、‘o’符合条件。

第三个字符的低4位的值必须是0x0e,查表得出字符‘.’、‘>’、‘N’、‘^’、n‘、‘~’符合条件。

第四个字符的低4位的值必须是0x05,查表得出字符'%'、‘5’、‘E’、‘U’、‘e’、‘u‘符合条件。

第五个字符的低4位的值必须是0x06,查表得出字符‘&’、‘6’、‘F’、‘V’、‘f’、‘v’符合条件。

第六个字符的低4位的值必须是0x07,查表得出字符‘''、‘7’、‘G’、‘W’、‘g’、‘w’符合条件。

因此phase_5的答案就多了,这6组字符随便按顺序组合即可。

C源码应该如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>int strings_not_equal(const char *input, const char *dst)
{int result;size_t len1 = strlen(input);size_t len2 = strlen(dst);if (len1 != len2) {result = 1;} else if (input[0] == '\0') {result = 0;} else { result = 1;while (*input++ == *dst++) {if (*input == '\0') { result = 0;break;   }}}return (result);
}static size_t string_length(const char *s)
{if (s[0] == '\0') {return (0); }const char *p = s + 1;ptrdiff_t len = p - s;while (*p++ != '\0') {len = p - s;    }return (size_t)len;
}void phase_5(const char *input)
{static int array[] = { 'm', 'a', 'd', 'u', 'i', 'e', 'r', 's', 'n', 'f', 'o', 't', 'v', 'b', 'y', 'l'};char str[7];size_t len = string_length(input);if (len != 6) {explode_bomb();      }int i;for (i = 0; i < 6; ++i) {str[i] = array[input[i] & 0x0f];    }str[6] = '\0';int result = strings_not_equal(str, "flyers"); if (result != 0) {explode_bomb();  }
}#if 0
int main(int argc, const char *argv[])
{phase_5(")/.%&'");return 0;
}
#endif

总结:

其实本阶段对我来说没遇到什么难点,毕竟汇编指令都是常用的,只不过汇编指令比较多,需要更多的耐心才行。OK,进入下一阶段吧!

CS:APP二进制炸弹phase5相关推荐

  1. CS:APP二进制炸弹phase2

    写在前面 在前文<CS:APP二进制炸弹phase1>中成功"破解"了phase_1,毕竟是第一个阶段,非常简单.本篇来破解第二阶段.let's go!!! 分析 反汇 ...

  2. [祭祖作业一]二进制炸弹破解笔记2

    哨兵值 数据结构与算法随笔之------哨兵变量(编程思想与技巧) 编程技巧1_哨兵值(sentinel) 为什么"哨兵值"没有解决错误处理问题 while 循环中的变量 i 控制 ...

  3. CSAPP实验二:二进制炸弹(Bomb Lab)

    本系列文章为中国科学技术大学计算机专业学科基础课<计算机系统>布置的实验,上课所用教材和内容为黑书CSAPP,当时花费很大精力和弯路,现来总结下各个实验,本文章为第二个实验--二进制炸弹( ...

  4. 深入了解计算机系统(CS:APP)思考题

    QA1 1.简述C.ASM.ML的关系,各自优缺点? 机器语言是二进制数据表示的语言,机器可以直接识别:汇编语言是与机器指令一一对应的助记符,是一种低级语言,经过汇编和链接之后机器可以运行:C语言在低 ...

  5. 哈工大 计算机系统 二进制炸弹实验报告

    实验报告 实 验(三) 题     目 Binary Bomb 二进制炸弹 专       业 计算机学院 学    号 班    级 学       生 指 导 教 师 实 验 地 点 实 验 日 ...

  6. 计算机系统二进制炸弹实验报告,二进制拿炸弹实验报告完整版.doc

    课程名称:计算机系统原理实验 实验课时:32课时 实验项目名称:BombLab二进制炸弹 实验材料:可执行文件bomb.源代码bomb.c.说明README 实验环境:Linux操作系统(安装虚拟机和 ...

  7. 计算机系统原理实验之BombLab二进制炸弹1、2关

    实验目的: 通过二进制炸弹实验,熟悉汇编语言,反汇编工具objdump以及gdb调试工具. 实验过程: 实验包里有三个文件,分别是二进制可执行文件bomb,C语言源程序文件bomb.c以及一个READ ...

  8. 二进制拆弹实验详解linux,拆解二进制炸弹

    拆解二进制炸弹 一.实验目的 1.理解C语言程序的机器级表示. 2.初步掌握GDB调试器的用法. 3.阅读C编译器生成的x86-64机器代码,理解不同控制结构生成的基本指令模式,过程的实现. 二. 实 ...

  9. 二进制炸弹(arm)

    x86上的二进制炸弹对于反汇编的练习来说还是比较经典的,由于网上有很多该程序的讲解,所以在此我打算写一下arm平台上的二进制拆炸弹这个游戏. 环境的搭建 由于是arm平台的环境,所以需要在linux环 ...

最新文章

  1. 隔空操作之通过简单计算识别手的挥动反向
  2. 巴西队被打成了蜂窝煤
  3. jquery总结06-动画事件03-淡入淡出效果
  4. MyEclipse10安装SVN插件的几种方法
  5. POJ 1944 Fiber Communications (枚举 + 并查集 OR 线段树)
  6. php创建表设置编码,教您在Zend Framework里如何设置数据库编码以及怎样给数据表设定前缀!...
  7. linux服务器u盘启动项检测不到,将U盘设置为第一启动项之后却检测不到U盘怎么办?...
  8. 查看linux网络带宽
  9. 华为Mate X 5G被黄牛炒出天价:这价格都能买辆车了!
  10. 文字排版不在单调!可临摹的网页UI设计模板,轻松驾驭!
  11. vhdl变量赋初值_变量类型、构造器、封装以及 LeetCode 每日一题
  12. Oracle 官宣:腾讯 JDK 18 国内第一!
  13. day 26 学习Linux-01天
  14. python协成_python基础26 -----python进程及协成
  15. Kali局域网断网攻击
  16. mysql有next_day用法_Next_day()函数的用法
  17. 戴尔寄希望于区块链在印度服务器市场保持竞争力
  18. sas数据操作update、modify by ke=、控制modify的更新、datasets添加约束条件、操作文件变动aduit trail...
  19. 教我怎么写连笔字签名胡彦清
  20. 手把手教学京东api接口全部操作过程

热门文章

  1. 南开大学软件学院2021年秋季学期研究生计算机网络课程(复习)
  2. 第三方支付平台结算流程是什么样的?
  3. poj1950 Dessert(DFS)
  4. graphics.h图形库用法总结
  5. 全面的网络诊断-Omnipeek
  6. tableView 取消 cell 默认下划线样式 - iOS
  7. 从装大象中我们学会了什么设计模式
  8. 数据结构----各种排序方法总结
  9. 黄海导航软件测试,测试软件平台环境一览
  10. 关闭 Windows 安全中心警报 及 用户账户允许此应用对你的设备进行更改 通知 及 打开文件 - 安全警告 通知