操作系统-设计与实现-八
前言 本篇博客完成M5的实验
M5 File Recovery(frecov)实验背景快速格式化 大家一定用操作系统提供的“格式化”功能对存储介质进行格式化——通常默认的选项是“快速格式化”;MacOS比较贴心的提供了更多的选项,例如更慢但更安全的选项。
实际上,虽然存储设备会比较大,但是格式化起来仍然非常快——如果把存储设备上的文件系统看做是一个数据结构(例如二叉树),那么只要破坏数据结构的“根节点”,即root->left = root->right = NULL;,数据结构的其他部分也就永久地丢失了。这样,数据结构就完成了一次完美的“内存泄漏”。当然,因为整个数据结构都被摧毁,你也可以重置内存分配器的状态,这样所有磁盘上的空间就变得可以被分配,磁盘也就“焕然一新”(被格式化)了。
格式化磁盘的数据恢复 当然,快速格式化紧接着带来了一个问题:快速格式化(指针赋值)也意味着可以通过遍历存储设备(内存)的方式,将数据结构找回来。在本次试验中,就尝试恢复格式化后的FAT-32文件系统镜像。
实际上,仅是格式化,我们知道文件系统在实现文件/目录的删除操作时,也仅是 ...
操作系统-设计与实现-七
前言 终于结束了痛苦的L2,虽然感觉确实学到了很多东西。这篇博客完成M4实验
M4 C-Real-Eval-Print-Loop(crepl)实验背景 很多编程语言都提供了交互式的read-eval-print-loop(REPL),更俗一点的名字就是”交互的shell”。例如在命令行中输入python,就可以和Python shell交互了。现代程序设计语言都提供类似的措施,即便是非解释型的程序设计语言,也提供了类似的措施,例如Scala REPL、go-eval等
实际上,C这种编译型的语言,同样可以实现”交互式”的shell——即支持即使定义函数,并且可以计算C表达式的数值。如果输入一段代码,例如strlen("Hello, World"),这段代码会经历gcc编译、动态加载、调用执行,并最终讲代码执行得到的数值11,打印到屏幕上
在本次实验中,将实现一个非常简单的C交互式shell
实验描述
crepl - 逐行从stdin中输入,根据内容进行处理:
如果输入的一行定义了一个函数,则把函数编译并加载到进程的地址空间中
如果输入是一个表达式,则把 ...
glibc2.31下largebin攻击
前言 之前打天翼杯线下的时候,遇到了一道pwn题完全没思路,查资料的过程中发现,好家伙,怎么House of系列攻击有更新了这么多类别,细看发现大多是largebin attack相关的。因此特别整理了一期博客进行学习
源代码 实际上largebin attack的原理十分简单,就是检查不严格,其漏洞代码如下所示 123456789101112131415161718192021222324/* malloc/malloc.c: */ victim_index = largebin_index (size); bck = bin_at (av, victim_index); fwd = bck->fd; /* maintain large bins in sorted order */ if (fwd != bck) { /* Or with inuse bit to s ...
操作系统-设计与实现-六
前言 最近太忙了,以至于操作系统-设计与实现和博客都没怎么更新过了…趁着国庆假期,把其他杂事都干完了,终于有时间来填坑了!
首先总结一下最近的课程内容,然后实现L2。
Manual 对于计算机科学来说,其实际上就是一个由各种手册(标准)组成的学科。因此学习的最好方法就是RTFM, Read The Friendly Manual。 如果想要对于Linux下的各种文件格式约定、内存布局等有更深入的了解,可以阅读System V ABI手册
加载 这里复现一下jyy老师在课程中给出的加载器demo
静态链接程序的加载 对于静态链接的程序,其加载起来非常简单:由于二进制文件中已经包含了程序运行所需要的全部代码和数据,因此理论上,只需要通过mmap,将其映射入内存中,然后将执行流转交给程序入口即可。 虽然如此,静态链接程序的加载器实际上坑也不少
要进行一些额外的设置(栈的初始化,部分寄存器初始化等),从而使其符合Linux进程初始化的约定——具体可以查看System V ABI手册的Process Initialization章节。
Auxiliary Vector必须初始化 ...
长城杯2021
前言 美好的一个中秋假期,然而基友们都去见女朋友了。。。只有自己在打比赛,太惨了!!! 虽然如此,女生只会影响我拔剑的速度。还是来总结一下这场比赛的骚思路更现实一些😶
K1ng_in_h3Ap_I 点击下载题目附件
题目保护 如下图所示,基本保护全开
题目逻辑 其就是一个标准的菜单堆,框架如下所示 1234567891011121314151617181920212223242526272829303132void __fastcall __noreturn main(__int64 a1, char **a2, char **a3){ int v3; // eax nothing(); while ( 1 ) { while ( 1 ) { menu(); v3 = read_int(); if ( v3 != 2 ) break; delete(); } if ( v3 > 2 ) { if ( v3 == ...
数位dp
前言 之前刷其他的题目的时候,看到过数位dp解法,但是太菜了,根本看不懂! 今天刷leetcode的每日一题时,题目虽然用了别的方法做出来,但是太丑了,非常多的判断。在看别人的解析的时候,突然看到数位DP模板级解法,一下突然懂了。 特别记录一下这个瞬间,自己又进步了一点。🚩
数位dp 首先,我们正式的(不讲人话)的介绍一下数位dp算法
数位dp算法是用来解决如下问题的算法求出在给定区间[A,B]内,符合条件f(i)的数$i$的个数。条件f(i)一般与数的大小无关,而与数的组成有关
这就是一般的数位dp算法的介绍,然后后面就直接跟例题和代码了,大家都是谜语人么? 这里我再介绍一下数位dp的一种通用解法,从而更好的理解这个优美的算法
数位dp通用解法 一方面,由于前面介绍的条件f(i)与数大小无关,而仅仅与数的组成有关,因此数位dp需要通过动态规划的方法,预处理出一个dp[i][j]的数组,dp[i][j]表示长度为i,最高位为j的符合条件f(num)的个数 另一方面,数位dp更多的可以理解为一种根据其数的组成的遍历顺序——该遍历顺序可以让我们有效的结合动态规划解决 ...