从零开始的编译器生涯

近日一屑高二学生无聊动手写起了编译器….这是他的珍贵作战记录 0x01 理论基础 我摊牌,我没有看任何编译原理相关的书籍,因此这篇文章并不能作为严格的参考资料,甚至很多地方可能是错误的。 编译器,编译器,就是把高级语言的代码编译成另一种形式(class,asm,二进制,IR),而他在编译成另一种形式之前大概需要过这么个流程: Lex -> Parse -> Compile 接下来逐步讲解这个过程。 Lexer 就是分词器,输入用户提供的代码接着把他分成 tokens,也就是 tokenstream。 你肯定看不懂上面那句话的意思,让我们来点实例: a.value 里的那个 ArrayList 就是一个 token stream,str 是被解析的代码。不难发现,语句被 Lexer 按顺序进行了分类以及数据的分割,如 a 被识别为了一个 Identify (标记)。 因此也可以归纳出来 Token 大致的代码长啥样: @AllArgsConstructor @Getter public class Token { private int line; private Type type; private String content; } Parser Lexer 从源码中提取出 token stream 后将会交给 Parser 处理,它负责对 token stream 进行解析,生成一个 AST (Abstract Syntax Tree),也就是 抽象语法树。 这张图直观的描述了这一过程,你可以看到它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。之所以说语法是“抽象”的,是因为这里的语法并不会表示出真实语法中出现的每个细节。 接着,AST 将会丢给代码生成器用于生成代码,但是一般会先对 AST 进行优化,例如 常量折叠 Static Analyzing 但在这之前,我们还有一些问题要解决。 其实这玩意我是和 Parser 写一块的 试想一下,如果有这样一行代码: ...

October 1, 2021 · 7 min · 1396 words

使用 cproxy 对程序进行透明代理

在 Windows 下,说到 透明代理 ,你可能会想到 Proxifier , SSTap, Mellow 但在 Linux 下,你可能会想到 proxychains 然后再想到 proxychains 不能代理 static-linked 的程序。 为什么 ProxyChains(NG) 不能代理静态连接的程序 ProxyChains NG 通过一个预加载的共享库来hook到网络相关的函数(比如: connect,getaddrinfo)上,接着他就可以转发这些流量。 缺点似乎显而易见,如果只是通过 LD_PRELOAD 来进行透明代理,那么这招对于静态连接的程序是无用的(比如说 Go 程序..) 其次,ProxyChains 只支持 TCP,这可能导致无法转发 DNS 流量 -> DNS 流量泄漏。 cproxy 是什么 cproxy 也是透明代理,作用和 proxychains 类似。 原理上与 proxychains 不同,它使用 cgroup 进行对程序的代理 ,不过配置起来还有点麻烦 本文将会教您在您的Linux PC上使用 cproxy,截至本文发布之前,cproxy似乎只支持 Linux。 下载 cproxy 官方推荐的方法是: 直接用 cargo cargo install cproxy 如果没有 cargo 可以在 Release 上下载压缩包。 解压压缩包,可能会发现有两个可执行文件,不过似乎只留一个就好了。 安装 cproxy 先来试一试 cproxy! ...

March 13, 2021 · 1 min · 131 words