为了在xv6上增加kprobe,发现要从编译器的优化器来查找函数,除了编译原理,我还要学习llvm的编译框架,然后深入Linux reverse和代码混淆(加壳)这一个领域。
我去,x86的汇编技术都还没有学扎实,后面还有这么一大片海啊?
目前编译原理还要继续学,然后学习Practical Binary Analysis,好像可以制作一个 Automatically Exploiting a Vulnerability,拿来可以检测一下Vulnerability,但是我不知道这个检测原理是什么?
编译原理
-
前端:词法分析->语法分析->语义分析
-
词法分析就是把与剧中的元素拆开,就像把中文里的主谓宾定状补拆开,但是拆下来的不叫词语,叫做Token。工具其实就是正则表达式(正则表达式是种魔法,以后一定要写篇随笔聊聊它)和有限自动机。
-
语法分析是生成一棵AST树,递归就能够遍历所有
-
语义分析其实也不是让计算机就懂你的语法含义(语音识别都要靠马尔科夫链呢)只是根据一些规则找出肯定错误的地方,同时还需要通过检查消除一些模糊性。
-
-
中端(好像也有直接把这个板块叫做优化器):生成中间代码->优化
-
后端:中端->生成目标代码
LLVM框架的介绍
其实llvm就是一个编译框架,就是为了把代码处理成一个机器能够执行的代码。
llvm都开源了,说明它重要,但是肯定不是最核心的技术,在翻译为机器码,然后扔到CPU上执行之前,CPU怎样接受指令,怎样在硬件层面再进行优化肯定是更加核心的技术。llvm这东西确实复杂,从编译它花的时间就看出来了。
下面的学习就是简单入个门,知道是怎么回事,然后不断找例子,无论是CTH还是代码混淆,努力把这个东西用起来吧。
llvm里面clang主要是负责前端,而core负责中间代码和后端。跟gcc比,llvm可以实现模块化编写,那开发就会非常灵活。只要这个项目不是整个一大坨,而是一小块一下块,那拼装肯定就会快很多。
编写llvm pass函数其实就是用来干预代码的整个优化过程。据说可以用来编写优化工具、Fuzzing工具,可以搞搞看要怎么实现?pass可以与整个llvm一起重新编译,放在//vm/lib/Transforms,虽然比单独编译一个llvm的时间要短一些吧,但是这样效率也不够高。更方便的做法使用Cmake管理源代码,可以不用手写Makefile?
构建pass流程
- Module Pass
- Function Pass
- runOnFunction(Function &F)
- 创建llvm类继承父类
- 注册llvm
- CallGraph Pass
- Loop Pass