本人容易在做完一件事情之后就会因为丢失目标而无所事事。所以我找了一个长期目标:看 Linux 2.6.24 源码,主要是跟着《深入 Linux 内核架构》看,最近这段时间看下来,发现在前人的指导下,并不会看不懂代码(知道代码段是做什么的了,看懂并不难),但是问题就在容易看过留不下印象,并且容易看睡着。
仔细想想,可能最好的源码分析书籍是带着读者一起重新把分析目标从头开始写一遍出来(比如带着读者把 Linux 内核从头开始写出来)。这样读者可以跟着书一起抄一遍,并且抄的过程中也会知道自己在抄的是做什么的,不会无聊,印象也非常深刻。当然如果在带着读者写的过程中不需求后向知识的话,要写出这样的书非常困难。
一早起来看了一下 xv6 book 的 interrupt 一章,相对看的比较潦草,因为想尽快开始写 net 的 lab。一直都很想写个 driver,结果看了一下 lab 的 guidance,有点劝退,就先去看了一下南大的静态分析课。今天看了 data flow analysis 的 fundation,本来只是想浅看一下就转去写 driver,结果越看越起劲,就把两节课都看完了。明天有强网杯不知道来不来得及把 assignment 和笔记都补完,准备尽快弄完。
学习的过程很有意思,学到了格(lattice)的概念,然后把这个概念应用到数据流分析上,证明我们的算法能求出对特定 transfer function 的最优解,充斥着形式化的美妙。最后介绍的 worklist 优化,又让我想到了我最爱的 spfa 算法(队列优化的 bellman-ford 最短路算法),也是很特别的感受。
晚上本来准备继续看下 Windows heap 的 slide,结果还是没忍住去重构了一下自己的 toy 编译器。虽然也算是学过一点设计模式,但是开发的经验确实少了一点,写之前也没分析清楚,导致现在看着各处耦合的代码挺头疼的,还是尽力重构一下,toy 也得 serious 一下hhh。 另外 Windows 用户态利用,感觉还是挺有意思的,希望不要半途而废啦。
今天突然发现了 apple music 的空间音频这个新功能(6 月 8 号实装的,我火星了),感受了一下,实在是牛。 由于是新技术,只有一部分歌曲能够以该模式播放,其中我比较喜欢的歌有 Sweet Child O' Mine, Don't Know What You Got, I Want You Back 和 Here Comes The Sun 这四首,推荐听一下,真的是全新的体验。 所以什么时候可以全面进入空间音频时代呢?比较期待《Have a nice day》和《Use Your Illusion》这两张专辑
今天学到一个骚操作:把 `;' 映射成 tap 层的 CTRL。这样长按时就是 CTRL,由此按 ctrl 变成了一件非常省力的事。
很久没写过博客了,以后不准备再用 markdown 写博客,而是全面拥抱 org-mode。而我把 org-mode 的图片粘贴路径写成了绝对路径,这样就会导致导出成 html 时图片失效。我感觉这个问题 ox-huge 应该可解决,但是下一个问题是导出成 pdf,使用 elegant paper 的模板,可以好看很多,也不需要再费心找模板了,所以我打算把 pdf 托管在 GitHub,这个博客只做索引
花了一个星期浅学了一些 OCaml 的 pure functional 部分的知识。函数式编程确实非常有意思,模式匹配加递归非常强大,使用高阶函数解决问题也是非常舒服的一个过程。一个星期的学习非常值得、非常快乐。
本人容易在做完一件事情之后就会因为丢失目标而无所事事。所以我找了一个长期目标:看 Linux 2.6.24 源码,主要是跟着《深入 Linux 内核架构》看,最近这段时间看下来,发现在前人的指导下,并不会看不懂代码(知道代码段是做什么的了,看懂并不难),但是问题就在容易看过留不下印象,并且容易看睡着。
我的解决方案是做笔记。这样确实感觉能记住了,不会困了,有些错过的细节也可以找出来。但是做笔记会花很多时间,而且感觉以后也不会再回去看过去的笔记,会觉得很亏。
仔细想想,可能最好的源码分析书籍是带着读者一起重新把分析目标从头开始写一遍出来(比如带着读者把 Linux 内核从头开始写出来)。这样读者可以跟着书一起抄一遍,并且抄的过程中也会知道自己在抄的是做什么的,不会无聊,印象也非常深刻。当然如果在带着读者写的过程中不需求后向知识的话,要写出这样的书非常困难。
在这里许个愿,希望有大神能写个这样的书出来 ^_^。
这两天写了一下 cs6.858 的符号执行 lab,也拜读了一下 EXE 的论文。对于符号执行,第一次接触可能已经是一两年前了,曾经也不熟悉 CMAKE 等构建系统,只觉得环境挺难搭的。后来了解了思想,感觉他的思想其实是挺 straight-forward 的,但是要真正实现他,主要的难度可能在设计一套数据结构来表示约束条件集和程序的执行路径,这个数据结构还要和约束求解器兼容。同时,还需要设计插桩的方法,提供插桩的接口
写了 cs6.858 的 lab 后我发现,似乎和我想的差不多,哈哈哈
最近这十天左右,一直在做同一个工作,就是把 xv6 的文件系统移植到 fuse 上,现在已经基本完成。做这件事的主要原因如下
我校操作系统的最后一个实验就是实现文件系统,做这个能顺便把实验过了。不过我校的实验要求仅仅是用内存模拟文件,而且许多地方都有简化
最开始学操作系统的时候,文件系统这里很惭愧,没有仔细看
暑假写了 xv6 的几个 lab,写完感觉收获有限,感觉写完 lab 并不难,但是原来不了解的(主要就是文件系统了),还是模模糊糊的感觉
现在把 fuse 写完了,至少是理解了 xv6 的文件系统设计,而且也感觉到,fuse 这个技术确实很有意思。另外,由于现在是在现代 Linux 用户态中写“系统调用”,所以能用的基础设施变多了很多,也可以把 xv6 为了简单而舍去的性能等方面给加入到我的实现中。
之后尽量整理出一篇博客来讲讲 fuse 是怎么用的(其实是很简单的)
最近在移植 xv6 的文件系统到 fuse 上,有一点感触,xv6 的 log layer 设计的是需要所有的文件系统相关调用都显示地写 begin_op() 和 end_op(),我觉得这样不太优雅,就想设计成自动开关操作。最后发现,原来地设计如果漏写了 begin 和 end,非常容易查出来,只要单线程测试一下就行了,但是如果设计成自动开关,就会使内部实现变得复杂,容易出现更多地问题。所以有的时候适当的取舍,看来非常重要
许多调试器都有条件断点,这是一个一直被我忽略的功能,在这里留个链接,以后要多用,大幅提高调试体验
http://c.biancheng.net/view/8255.html
开学半个月了,本来以为这段时间很充实,但是回头一看发现也没做多少,做完了南大程序分析课的 8 个 assignment,最后两个没 A 掉,实在不想调了,容我偷个懒,安慰自己理解原理就行了。然后把 xv6 的 lab 写的差不多,还有个 net lab 没写,之前看了两天文档被困得劝退,暂时没什么勇气再开始了。
周末做了之前一直想做的事,把 differential-datalog 整合到一个 llvm pass 里面做静态分析,碰到了很多问题,我把还记得的(也就是折磨了我很久的)几个问题写在了 readme 里面。写了一段时间也只是搭了个框架,不过还是很有意思的。仓库地址:https://github.com/chujDK/StaticAnalysisOnLLVMWithDDlog
实习开始之后有很长一段时间觉得在上学期间不需要深耕于一个子领域,不如都涉猎一下,拿这样的想法确实是安慰了自己一段时间。但是现在看看自己的技术栈,似乎并没有什么拿的出手的东西,之后也准备为一场比赛出个题,但是又感觉没有能出的,不像有些师傅懂 V8 有些师傅懂 kernel,暂且想法是一个非常小众的 realworld 程序利用,但是目前还没找到洞,笑哭。
现在感觉自己还是觉得编译器有意思,但是要学的东西太多太深太晦涩,文档也略少。不管如何,先啃啃看吧。有趣的是,在学完静态分析之后,在小语的建议下我看了看 NTFuzz 的论文,虽然我没看完,但是当时的感觉就是论文也没有那么难看懂。也许之后查资料的时候,打开发现是论文我也敢看了吧。
到了大三,突然又有些遗憾当时没有考到更好的学校,没有志同道合的人一起研究技术。不过在这找到了最喜欢的人,也就释然了。
很久没写过这时光机了,突然想记录一下今天做了什么,因为主要是看了点网课,然后时间也有点晚,不准备立马整理,就觉得有事情没做完的感觉。
一早起来看了一下 xv6 book 的 interrupt 一章,相对看的比较潦草,因为想尽快开始写 net 的 lab。一直都很想写个 driver,结果看了一下 lab 的 guidance,有点劝退,就先去看了一下南大的静态分析课。今天看了 data flow analysis 的 fundation,本来只是想浅看一下就转去写 driver,结果越看越起劲,就把两节课都看完了。明天有强网杯不知道来不来得及把 assignment 和笔记都补完,准备尽快弄完。
学习的过程很有意思,学到了格(lattice)的概念,然后把这个概念应用到数据流分析上,证明我们的算法能求出对特定 transfer function 的最优解,充斥着形式化的美妙。最后介绍的 worklist 优化,又让我想到了我最爱的 spfa 算法(队列优化的 bellman-ford 最短路算法),也是很特别的感受。
确实会感觉好的大学的课确实设计的用心,自己确实还是太菜了。处在一个很菜的环境,又不努力,不能这样了:(
安卓写起来好致郁,搞了一晚上连个 context 都拿不到。
看来还是要加深理解才能更好的开发。郁闷:(
看起来是我自己没搞清楚,可能音乐播放确实不应该放到 viewModel 里面。不过我把它拿到 Activity 的 setContent 里面的 launchedEffect 里面放,虽然有效,但是也并不明白这符不符合设计模式的原则。知识还是太匮乏了555
https://docs.google.com/document/d/1BpdCFecUGuJU5wN6xFkHQJEykyVSlGN8B9o3Kz2Oes8
clangd 真是太强了
晚上本来准备继续看下 Windows heap 的 slide,结果还是没忍住去重构了一下自己的 toy 编译器。虽然也算是学过一点设计模式,但是开发的经验确实少了一点,写之前也没分析清楚,导致现在看着各处耦合的代码挺头疼的,还是尽力重构一下,toy 也得 serious 一下hhh。
另外 Windows 用户态利用,感觉还是挺有意思的,希望不要半途而废啦。
忍不住想说,llvm 真是太好玩辣
这两天跟着文档拓展了一下自己的解释器,使其能够生成 llvm-ir,期间不断感受到 llvm 的设计是真的简单易用,太优秀了!
反过来再看一下自己的代码,不说了,我还是找个电子厂上班吧:(
这次的 D3 出了两道题,有些师傅觉得第二题 d3bpf-v2 是对 d3bpf 出现非预期的修补,其实并不是。两道题都是入门级的 ebpf 利用题(因为我也只是初学者不可能出的难到哪里去),第一题用的 kernel 版本着实有点奇怪,受到许多 CVE 影响,有些师傅只用了公开的 exp 改改偏移就出了。第二题则是因为新版本的 kernel 中加入了 mitigation,旧的利用方式失效,又似乎没有公开的 exp,所以才出的。最后只有 ROIS 的师傅解出,这也很正常,我其实是参考这位师傅发现的 CVE-2022-23222 的利用总结出的题。师傅人也很好,没有对我剽窃他的思路表示不满。总的来说,如果大家能够借助这两道题了解一下 ebpf 的一种利用套路,我觉得我的目的也就达到了。至于非预期之类的,确实给各位师傅带来了一些不好的体验,十分抱歉。
今天看到了 C++ 中兼顾多态和性能的设计模式,即奇异递归模板模式,通过把派生类作为基类模板的类型参数在编译器实现运行期多态,避免了通过虚表进行函数调用。
这篇文章讲的很友好 https://liam.page/2016/11/26/Introduction-to-CRTP-in-Cpp/
我根据这种思想也写了个 demo,很有趣。
两天时间打完祥云杯,最后拿了个第六,打了一些奖金,也算是值回票价。
花了一天时间看完了图解 http,很棒的一本小书。学习计网的开始
最近在学习 js,真是一门神奇的语言
今天开始写 COOL 的语法分析,遗憾的是毫无进展,还没有理解提供的 AST 模块的用法和原理,文档是有的,也不是很长,但是是英文的,说起来也挺好笑的,学了十多年英语看这点东西还是有点吃力,看了一段时间发现有点难以理解就放弃了,明天再弄吧。bison 也还不会用。看看明天能不能尽量实现一下这个。
虽然说起来语法分析这种更加偏向于数学的东西对我来讲可能不大有用,但是我感觉还挺有意思的,而且对于 jit 语言来说词法、语法分析应该也是很重要的(毕竟是运行时),所以并不愿放过,之后也准备整理一下学到的相关的知识点。
今天终于弄完了服务器的迁移。由于阿里云学生机取消,原来买的 ecs 就不能原价续费了,所以用老云翼买了一个轻量应用服务器。刚开始嫌麻烦就用了宝塔的一键迁移,结果 502 了,最后还是老老实实地重装了一遍,很奇怪的是在发表文章的时候会有 api 未配置错误,不过反正文章还是能发布,就不多管了。
有前辈翻译了 flex 的部分文档 https://eternalsakura13.com/2020/05/27/flex/,我看了之后才知道有 input/yyinput 这个方法(前者用于 C,后者用于 C++)让我们可以在 pattern 的 action 中读取输入,由此对注释和字符串的处理就变得简单了。昨天一直在尝试用正则直接把注释匹配出来,由于 COOL 的块注释是可以嵌套的,所以一直弄不好,可以用 input 自己处理就简单许多了。
说到用正则匹配注释,在嵌套的时候需要用正则处理字符串中间不含字串 STR 且以 STR 结尾这样的问题,据说正则其实不适合做这样的事情,不过我也有看到解决方法,也就是先写出,NFA 然后从 NFA 转回到正则 https://www.seas.upenn.edu/~cit596/notes/dave/regexp-nfa4.html
不过这里给出了表达式https://www.it-swarm.cn/zh/regex/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%EF%BC%8C%E4%B8%8D%E5%8C%85%E5%90%AB%E6%9F%90%E4%BA%9B%E5%AD%97%E7%AC%A6%E4%B8%B2/957945248/
花了一些时间写 COOL 的词法分析,进展不甚顺利。flex 的写法还是不太懂
编译原理学习小记:
关于词法分析的设计过程。感觉这确实是很简单的一个操作。首先写出根据词法规则写出正则表达式(上一篇时光机中提到了),然后根据正则表达式写出 NFA,然后根据 NFA 写出 DFA,最后实现 DFA。当然根据需求不同也可以直接实现 NFA。
之前浅浅地看过自动机的慕课(应该是哈工大的),正好也是看到 NFA 为止。哈工大的慕课中说到 NFA 是对同一个输入,一个状态可以有转移到多个状态,而编译原理的慕课中,把一个状态转移到多个状态拆分为了空跳(即不需要消耗数据就可转移,也就是输入为 epsilon)加一个状态转移到一个状态。这样就把 NFA 和 DFA 的区别变为了 NFA 允许有空跳(且一个状态可以拥有多个空跳),DFA 不允许。
看似两种定义没有特别大的区别,但是在 NFA 和 DFA 的转换上变得简单明了了许多。首先引入 epsilon-closure 的概念,也就是一个状态经过 0、1 或多个空跳可以转移到的所有状态集合,那么把 NFA 转移到 DFA 时,DFA 的初始状态就是 NFA 的初始状态的 epsilon-closure(注意 DFA 的状态变为了 NFA 的状态集合)。然后每个 DFA 的每个转移就是状态集中每个状态对应得转移状态和 epsilon-closure 的并集,此并集就是目标状态了。最后 NAF 终止状态处于的集合都是 DFA 的终止状态。这样转换之后首先状态可能会爆炸,因为有 2^N -1 中可能状态,另外每个状态都可能很复杂。对于状态爆炸使用行重用可以缓解。比较有趣的是每个状态很复杂这个问题,实际上这根本不是问题,因为在我们确定了所有的状态和终止状态后就不需要知道每个集合的确切结构了。
DFA 的优势在于匹配快速,NFA 则更省空间。
明天争取实现 COOL 的词法分析。
编译原理学习小记:
编译的过程可以分为五步:词法分析(lexical analysis),语法分析(parsing),语义分析(Semantic Analysis),优化(optimization)和代码生成(code generation)。
今天花了点时间看了一下慕课,了解了词法分析的原理。即使用正则语言识别代码,从而生成 token(词法单元),即 <类别, 词素>这样一个二元组。我们通过正则表达式表达出所有的词素,然后对代码进行匹配即可将代码转换为 tokens。
这里表达出所有的词素的正则表达式实际上是多个正则表达式的和,举例来说也就是 R = R_Identifier + R_Variable + ...
一些细节问题挺有意思的
首先是匹配歧义的问题,以英语举例,对 input 这个字符串从左往右扫描,扫到 "n" 的时候其实已经可以匹配了,因为 "in" 就是一个合法的词素,但是正常人都会看到 "t" 为止,把这个字符串理解为 "input",这就是最长匹配原则,当对代码进行匹配时,如果碰到 "==",虽然 "=" 也显然满足正则表达式,但是我们仍然应该匹配到最长,也就是匹配失败的上一个接受状态。
然后是匹配优先级的问题,对于 else 这个标识符来说,它是一个关键字,那么它可以被 R_Keyword 匹配。但是光看变量的定义(即字母开头,由字母数字下划线组成的字符串)时,我们会发现 else 也会被 R_Variable 匹配。当然大多数(PL1 不是这样的)的语言都不允许变量是关键字,那么我们如何改写正则表达式呢?比较难。所以一个更好的方法是在匹配 R 的时候优先匹配 R_Keyword 这个表达式,这样 else 就不会被识别为变量了。
最后是词法错误的情况,如果代码中出现了词法错误,让匹配直接出错崩溃看似不是很好,所以可以加一个 R_Fault,这个正则表达式包含了所有的错误情况。有了匹配优先级的思想,我们可以比较简单地写出这个表达式,然后放到 R 的最后。那么匹配不了的都会被这个正则表达式识别,然后对词法错误进行异常处理即可。
关于 InCTF Kqueue 一题:当时找到了堆溢出后不知道怎么 leak 就放弃了。赛后看了一下公开的 exp 后才发现原来是没有开启 smep(Supervisor Mode Execution Protection,不同态间不可执行)和 smap(Supervisor Mode Access Protection,不同态间不可访问),可以直接 ret2usr。那么劫持 tty 虚表为用户函数,执行 mov rax, [rbp + 8] ret 回来返回值就是内核地址了,完成 leak。之后继续 ret2usr 提权就很容易了。
这样看来题目其实很简单,没有仔细看 qemu 启动参数真的是非常大的失误。
InCTF 结束了,做出了两道 pwn。如果中间没有一些摸鱼的时间可能可以多出一道 kernel pwn 的题,不过那道题虽然找到了洞,但是不知道怎么 leak,所以有更多的时间可能也是做不出来。两天 6 道题目是有点多,甚至没来的及看过每道题。
明天要考科一了,所以 WP 明天再来补。
还是需要提高自己的知识水平。
关于模板方法模式和钩子:
对于多个有相似算法的类,可以应用模板方法模式,将算法骨架抽离,定义为一个超类。对于算法中不同的地方,把它变成一个虚函数,有子类实现自己需要的逻辑。超类也可以实现这个虚函数提供默认操作。
有时子类可能需要自己拓展算法的功能,这个时候可以添加钩子函数。所谓钩子函数,其实就是一个函数指针(当然根据钩子的实现者不同也可以定义为虚函数),子类只要实现钩子函数就可以添加新的功能,如果不需要扩展那就提供一个空的函数即可。
C++ stl 中的 std::sort 就是一个应用模板方法的例子,我们在 sort 时,可以提供自己的比较函数来定义被排序对象的大小关系,这里提供的就是钩子函数了。
应用模板方法模式可以减少重复代码,并且提取了公共代码,便于系统的维护。通过钩子和抽象函数也提高了系统的弹性。
这里也体现了 OO 中所谓的“好莱坞原则”:高层调用低层方法,低层方法不调用高层。这样便于他人理解系统,避免了“依赖腐败”。
睡前记录一下今天学习到的知识:
今天在重构代码的时候碰到了工厂模式的环形依赖问题,也就是工厂里有产品的头文件,产品里有工厂的头文件,导致 VS 报了近百个错误。
一度毫无头绪,后来网上冲浪了一下得知,在 A has-a B 这种组合关系时,编译时编译器并不需要知道 A 的具体属性,只要提供一个指针即可,所以在 B 类定义前声明 A 类即可,不需要包含头文件。
头文件包含应当尽量少,以加快编译速度。尽量使用 #ifdef 或 #pragam once 来避免重复包含。
谢谢这篇文章的作者,帮我解决了头疼的问题 https://blog.51cto.com/5885774088/242124
这三天打了一场英国排名第二的战队的比赛 RaRCTF,本以为是高质量国际赛,做了才发现题目的难度非常温暖人心。花了两天做完了所有的 pwn,现在着实有点憔悴。
今天学习了单件模式,适配器模式,外观模式,命令模式。
单件模式很好理解,通过这种设计方式可以保证一个类最多被实例化一次,具体的方式就是将构造函数定义为私有,然后提供一个静态的 getInstance 方法根据类是否被实例化过选择调用构造函数。这个方法需要考虑条件竞争的问题,一种解决的方法是加锁,但是加锁会造成性能的损失,于是我学习到了一种 fancy 的加锁方式
这种加锁方式感觉挺有意思的,算是一个小 trick 了吧。
然后是适配器模式,做的是接口的转换,也很好理解。一个简单的 java iterator 适配器可以这样写
这样就可以用 enumeration 的方法来访问 iterator 了。
当客户使用的类在更新时发生了 api 更改时可以把原类用一个适配器适配出来,就可以避免对原来的代码进行大面积的修改
适配器模式分为类适配器和对象适配器,前者使用继承,后者使用组合。
外观模式也比较容易理解,使用一个类对大量组件类的方法的进行了包装,使客户可以更容易地调用组件群。
命令模式感觉还没有理解清楚。
C++ 好像有 std::mutex,可以不用 pthread
《HEAD FIRST 设计模式》告诉我“依赖倒置原则”这个专有名词可以让我加薪。很棒,记录一下。
也就是说,OO 设计时,应当依赖抽象,而非依赖具体类。
倒置就体现在对于满足“依赖倒置”的 OO 设计,低层和高层类都会依赖于较高层的抽象类。
为了实现“依赖倒置”,书中提供了三点建议:
1、变量不可以持有具体类的引用 也就是说避免使用 new,可以使用工厂模式来替代。
2、不要让类派生自具体类 派生自具体类就是依赖了具体类,尽量派生自抽象类
3、不要重写基类已实现的虚函数 如果需要重写基类虚函数,就说明基类不适合被继承。基类中已实现的方法应当共享给所有的子类
当然,在实际开发时,不可能完全按照该原则进行,只应当尽量。再引用书中的话就是“如果你在 Hello World 的时候都考虑用什么设计模式的话,那可能已经病了”
之前碰到了一个 read 时 nbytes 过大会无法读取的问题,今天调试了一下发现原因是在 fs/read_write.c 中的 vfs_read 函数中的 if (unlikely(!access_ok(buf, count))) 这个检查无法通过
今天终于把强网杯的 notebook 复现了,挺简单的 kernel pwn 复现了两天多,不过还是学到了新知识,挺棒的。之后准备研究一下给 http 服务器的那种 pwn 题,每次碰到这种题都不知道该怎么下手,有必要学习一下
kernel pwn 好难啊
受不了 typecho 这个在线编辑器了,已经第二次在我写完文章后卡死导致数据完全丢失了
今年的夏促感觉没有游戏可买,感觉已经失去了对游戏的热情了,这真的很奇怪
最近这段时间考试周开始了,复习倒也没复习,但是就是没有学习的动力,的确有些许颓废。今天还忘了大物的小测,非常的烦。大一一年下来学到的东西全是自学的,平时上课反而是影响了我的学习,想想就觉得很不舒服
今天突然发现了 apple music 的空间音频这个新功能(6 月 8 号实装的,我火星了),感受了一下,实在是牛。
由于是新技术,只有一部分歌曲能够以该模式播放,其中我比较喜欢的歌有 Sweet Child O' Mine, Don't Know What You Got, I Want You Back 和 Here Comes The Sun 这四首,推荐听一下,真的是全新的体验。
所以什么时候可以全面进入空间音频时代呢?比较期待《Have a nice day》和《Use Your Illusion》这两张专辑
用了很长一段时间的 cmder 做终端,vimplus 做编辑器,其实这样操作挺方便的,但是今天突然发现 VScode 可以 ssh 到 wsl 和远程服务器,而且做到非常的好。所以决定了,cmder 拜拜。
本来想复现一下 XCTF-FINAL 的 hellostack 这道题,比赛的时候学长很快做出来了,就看都没有看。现在看了一下想想还是算了,没什么意思,这道题就是自己实现了一套类似影子堆栈的系统,对每个函数的返回地址都做了检查,但是存在很裸的 UAF 和 double free,可以直接攻击其备份返回地址的结构。别的地方都难以控制,只有 main 的返回地址可以随便控制。同时,有一个后门提供了无限溢出,所以可以直接溢出掉整个栈,在 main 退出时进行 rop。
以上为预期解,实际上 2.27 下有 double free 和 UAF,堆的攻击是非常简单的,出题者为了避免直接这样攻击便未提供输出,无法直接 leak,但是攻击 IO_2_1_stdout 结构体仍然可以 leak。所以还是可以 leak 之后直接打 __free_hook。一般来说这种方法需要进行一个 1/16 的爆破,不过本题的输入方式导致需要爆破 12 位,每一次启动 sleep 了 10 秒,所以爆破理论上可行,但是代价应该是不可接受的。
总体来说这题应该是此次比赛的 PWN 签到。
更新了博客版本,看看时光机还能不能用
发现突然多出很多想学的东西,罗列一下免得忘了
看 ptmalloc,下一步 sysmalloc
学 OS,看《操作系统真象还原》
学习 driller 的使用和原理
多了解一点符号执行相关的测试技术
终于看完 _int_malloc 了,收获还是有的,发现了一些原来不知道的细节,也获得了相对理性的认知,对 4 bin 1 cache 的操作也有了理性的认知。之后准备看一下 sysmalloc。很有成就感!
Source Insight 真的很棒!
wiki 通过了我的第二次 PR,现在也可以在首页的 Contributors 里看到我啦!
最近很颓废,感觉没有学习的目标了,题目也都不会做,好难受
plaidctf pwn 出了一道比较简单的菜单类题,很开心,终于不至于在比赛一直 0 解了
本来是准备把 vtable 里面的函数都分析完再一起发出来的,但是实在太多了,第一篇以深度优先的顺序分析完了 _finish。过程中解决了我对之前 _IO_2_1_stdout 攻击中的疑惑,还是有收获的。
今日继续推进了对 vtable 的分析,但是进度不甚快,而且也有许多操作系统 I/O 的知识需要补。有段时间没有做题了,有一丝丝的不适,但是我觉得还是有必要先啃啃源码。
ctf-wiki merge 了我的 pull request 了!很开心,我也是参与开源项目的人了!
今天一天都比较摸,上午满课,下午出去吃了顿饭,马上接着上形策,所以很遗憾没有做题。但是令我满意的是我终于开始有效地阅读起了 _IO_FILE 相关的源码,分析的文章我一定会尽快写完的
今日看完 困在时间里的父亲 这部电影。其实看得迷迷糊糊
花了快一个星期,断断续续看完了导演剪辑版的正义联盟,确实比几年前的院线版要优秀不少。
今天没有做出题.. 尝试学习一下反弹 shell 然而发现搞不出来,心态有些崩。确实状态不是很好
今天不想做题,写作业写的非常生气,真的是服了英语精读这垃圾课了,学分这么少作业还这么多。
今天有两件事令我开心:
1.成功进入 Vidar-Team
2.观看了重映的阿凡达,终于在银幕上观看了这部电影,3D 确实比以前在电脑上看 2D 要震撼
今天只做了一道水题,而且自己还没有想出来,明明都是已知的知识但是无法实现融会贯通,实在是遗憾和伤心。不过考虑到中午睡觉起来刷了 2 分钟暗黑2就出了塔拉夏头的份上,心情也不是特别失落。
今天颓了一天,这大概是比赛后遗症了吧,的确是无心学习,V&N 的公开赛也没什么心思去打(主要是因为什么的都不会)
今天一天比较颓废,因为被 _IO_FILE 卡了。本来是准备看一下源码的,但是发现很难读,就颓了。
但是这是不行的,这里还是要读的。
我终于日穿 House of Orange 啦!
接下来的安排:可以暂缓题目的进度了,下一步先做个 House of Orange,然后开始研究源码,特别是 IO 相关的,都值得一看。同时还有一个 AFL 要看。
House of Orange 为什么也是 _IO_FILE 啊,头疼啊
可能还是有必要在本地编译一个2.23的ld,题目提供的ld都无法用。每次都在wsl开一个docker,虚拟机套虚拟机是有点呆了
我终于明白为什么rop的时候可以随便改rbp了!rsp才决定了栈在哪里,每一次新进一个函数的时候,rbp都会被置为rsp。难以想象我竟然被这个问题困扰了这么久
突然感觉这句话体现的我基础很不牢固,其实不至于,只是写 exp 的时候会有过度的担心而已
不拼别的方向的题了,不系统地学做了也是白做,为了这点分没啥意义
做个密码学的题目碰到扩欧,不禁回想起当年打OI的时光,头疼啊
对着exp看了一个多小时完全想不通为什么打不通,然后才发现是payload没送出去..
hgame真的好难啊..
去年hgame的题看起来好难啊,今年这场比赛我可能比较蓝了
堆利用好难学啊
看完剪刀手爱德华,我又哭了
关于近期可能出现的长时间停更:由于考试周的逼近,本人需要进行小小的突击,否则面临退院的可能,考虑到最近做题也都是做水题,没时间学习新的利用法(特别是堆),干脆就不做了,因此可能会出现大面积的停更。有些遗憾,更多的是无奈
关于这几天没做什么有意义的题,今天甚至颓到可能一题都不会做一事:我忏悔
现在感觉学的非常累,会做的题目都是简单的毫无意义的题,能学到东西题目是真的做不出来,感觉都和魔法一样。这条路感觉确实比较难走
今日上午的学习效率极低,两个多小时什么成果都没有,有一丝伤心
花了这么久,libc的问题还是无法解决,还是考虑用dockers吧,虽然在虚拟机里面开dockers显得很呆,但是这也许是现在最好的解决方法了
echo_back这道io_file题解不出来,比较重要的原因是gdb还是用不来,明天尽量把指定libc运行的方法搞好
https://www.796t.com/article.php?id=181322
这个网站竟然盗取了我的文章,还有300的阅读量,一方面被盗取也是我的文章质量尚可的表现,另一方面是真的非常难受啊,其实我并不介意被转载,相反我非常欢迎,但是至少要声明清楚是从我这里转载去的啊。
看到我chrome杂乱无章的收藏夹,突然动了删除用不上的书签的想法,这一删仿佛时光倒流,从三年多前刚保送时买电脑到现在的往事全部闪过,泪目
试一试时光机的功能