CS:APP二进制炸弹phase5
写在前面
在阶段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相关推荐
- CS:APP二进制炸弹phase2
写在前面 在前文<CS:APP二进制炸弹phase1>中成功"破解"了phase_1,毕竟是第一个阶段,非常简单.本篇来破解第二阶段.let's go!!! 分析 反汇 ...
- [祭祖作业一]二进制炸弹破解笔记2
哨兵值 数据结构与算法随笔之------哨兵变量(编程思想与技巧) 编程技巧1_哨兵值(sentinel) 为什么"哨兵值"没有解决错误处理问题 while 循环中的变量 i 控制 ...
- CSAPP实验二:二进制炸弹(Bomb Lab)
本系列文章为中国科学技术大学计算机专业学科基础课<计算机系统>布置的实验,上课所用教材和内容为黑书CSAPP,当时花费很大精力和弯路,现来总结下各个实验,本文章为第二个实验--二进制炸弹( ...
- 深入了解计算机系统(CS:APP)思考题
QA1 1.简述C.ASM.ML的关系,各自优缺点? 机器语言是二进制数据表示的语言,机器可以直接识别:汇编语言是与机器指令一一对应的助记符,是一种低级语言,经过汇编和链接之后机器可以运行:C语言在低 ...
- 哈工大 计算机系统 二进制炸弹实验报告
实验报告 实 验(三) 题 目 Binary Bomb 二进制炸弹 专 业 计算机学院 学 号 班 级 学 生 指 导 教 师 实 验 地 点 实 验 日 ...
- 计算机系统二进制炸弹实验报告,二进制拿炸弹实验报告完整版.doc
课程名称:计算机系统原理实验 实验课时:32课时 实验项目名称:BombLab二进制炸弹 实验材料:可执行文件bomb.源代码bomb.c.说明README 实验环境:Linux操作系统(安装虚拟机和 ...
- 计算机系统原理实验之BombLab二进制炸弹1、2关
实验目的: 通过二进制炸弹实验,熟悉汇编语言,反汇编工具objdump以及gdb调试工具. 实验过程: 实验包里有三个文件,分别是二进制可执行文件bomb,C语言源程序文件bomb.c以及一个READ ...
- 二进制拆弹实验详解linux,拆解二进制炸弹
拆解二进制炸弹 一.实验目的 1.理解C语言程序的机器级表示. 2.初步掌握GDB调试器的用法. 3.阅读C编译器生成的x86-64机器代码,理解不同控制结构生成的基本指令模式,过程的实现. 二. 实 ...
- 二进制炸弹(arm)
x86上的二进制炸弹对于反汇编的练习来说还是比较经典的,由于网上有很多该程序的讲解,所以在此我打算写一下arm平台上的二进制拆炸弹这个游戏. 环境的搭建 由于是arm平台的环境,所以需要在linux环 ...
最新文章
- 隔空操作之通过简单计算识别手的挥动反向
- 巴西队被打成了蜂窝煤
- jquery总结06-动画事件03-淡入淡出效果
- MyEclipse10安装SVN插件的几种方法
- POJ 1944 Fiber Communications (枚举 + 并查集 OR 线段树)
- php创建表设置编码,教您在Zend Framework里如何设置数据库编码以及怎样给数据表设定前缀!...
- linux服务器u盘启动项检测不到,将U盘设置为第一启动项之后却检测不到U盘怎么办?...
- 查看linux网络带宽
- 华为Mate X 5G被黄牛炒出天价:这价格都能买辆车了!
- 文字排版不在单调!可临摹的网页UI设计模板,轻松驾驭!
- vhdl变量赋初值_变量类型、构造器、封装以及 LeetCode 每日一题
- Oracle 官宣:腾讯 JDK 18 国内第一!
- day 26 学习Linux-01天
- python协成_python基础26 -----python进程及协成
- Kali局域网断网攻击
- mysql有next_day用法_Next_day()函数的用法
- 戴尔寄希望于区块链在印度服务器市场保持竞争力
- sas数据操作update、modify by ke=、控制modify的更新、datasets添加约束条件、操作文件变动aduit trail...
- 教我怎么写连笔字签名胡彦清
- 手把手教学京东api接口全部操作过程