文章总结: 该文档介绍了Yaklang将脚本编译为原生二进制文件的SSA2LLVM项目进展,目前已完成从源码到SSAIR再到LLVMIR的完整编译链路,支持基础语法、函数调用、异步等特性,并集成多阶段混淆管线(如算术替换、虚拟机化)。项目处于工程化阶段,重点优化混淆稳定性和语法支持,同时测试接入LLVM原生混淆能力,未来将补齐map支持等缺失功能。 综合评分: 85 文章分类: 安全开发,二进制安全,安全工具,代码审计,红队
把 Yaklang 脚本编译成原生二进制:SSA2LLVM 现在走到哪了
原创
YAK YAK
Yak Project
2026年5月22日 17:41 湖南
在小说阅读器读本章
去阅读
一、在安全领域的程序分析
今天的文章聊一下接下来要上线的一些功能。
简单说就是:我们现在可以把 Yaklang 脚本,编译成原生二进制文件,加上混淆,并且能真正跑起来。
但这不是一个突然冒出来的方向。
它其实是 yaklang 编译这条线上长期规划的一部分。
YAK
1.这件事为什么是现在
过去很长时间,我们花了很多力气在做一件事:把各种语言的源码编译成统一的 SSA IR(中间表示)。
你如果关注过我们之前的文章,应该知道我们已经接入了不少语言的编译前端,并且做了大量的语法特性支持。在做这些的过程中,Yak SSA IR 本身也在慢慢趋于稳定。
而当中间这一层稳定下来以后,一个很自然的问题就出现了:
能不能继续往下走?不只是把源码编译成 IR 用来分析,而是把 IR 再往下编译成真正能跑的二进制?
这件事从技术上来说并不突兀。
编译这件事,本质上就是保持语义一致的前提下,一层一层做代码形式的转换——从源码到 AST,再到 IR,再到目标码。每一层都是在前一层的基础上,把语义保留下来,换成更接近机器能执行的形式。
所以当中间 IR 层趋于稳定,往后端走就是水到渠成的事情。
这条编译路径叫 AOT(Ahead-Of-Time,提前编译),意思是把代码提前编译成原生二进制,运行时不再临时编译或解释。它和 JIT(运行时边跑边编译)是两条不同的路。我们现在走的是 AOT 这一条。
YAK
2.现在做到了什么程度
关于编译和分析,我们前面已经聊过很多了。
这篇文章,主要聊编译向后端走这一步。
编译链路已经完整跑通
从一份 .yak 源码开始,整条路是这样的:
1.先把源码编译成 Yak SSA IR
2.再把 SSA IR 转成 LLVM IR
3.从 LLVM IR 出汇编、目标文件
4.链接对应的运行时库
5.最后拿到一个真正的原生二进制,可以直接跑,并且结果校验是对的
这五步,每一步都已经是跑通的状态。
不是“只能生成 LLVM IR 就停了”,是所有步骤都打通了。
语法支持已经覆盖了不少
目前这条线可以处理的 Yaklang 代码,不是玩具级。已经支持的包括:
- 基本算术、比较、控制流(if / for / return)
- 函数调用、递归
- defer / panic / recover / try-catch-finally
- 异步调用(go 语句)和自动等待
- 闭包基础能力
- slice 的创建、追加和索引读写
这里面有些是简单收口,有些是踩了不少坑才做通的——比如 try-catch-finally 和闭包,在编译路径下的实现逻辑和在解释执行里完全是两套东西。
调用协议已经统一
目前所有调用——不管是普通函数、builtin 分发、runtime shadow method、还是异步 go 调用——都统一接到了一套调用协议上。这件事单独看不算亮点,但它意味着以后加新能力不用每种调用都重新拆一遍,工程上会越来越省力。
YAK
3.混淆:不只是能编译,还要能保护
如果只是编译成二进制,这件事还不够完整。
所以我们从一开始就在这条线上同时推进了混淆能力。
目前这条线已经接入了一整套混淆管线,包括:
– addsub:算术指令替换
– callret:调用返回混淆
– xor:LLVM 层的异或混淆
– opaque predicates:不透明谓词
– MBA:混合布尔算术变换
– virtualize:虚拟机化混淆
而且这些混淆器不是零散的——它们已经按三阶段(SSA 前 / SSA 后 / LLVM 层)做了分层,不同混淆器放在不同阶段,用 profile 统一配置。
换句话说:今天你已经可以指定一份混淆策略,把它和编译一起跑下来,拿到一份被混淆过的原生二进制。
YAK
4.LLVM原生混淆能力也在测试接入
上面那些是我们自己实现的混淆器。
除此之外,我们还在编译链路里留了一个 LLVMinterop 层。它不限于我们自己的混淆器,而是可以直接挂接 LLVM 生态里已有的混淆 pass——不管是标准的 opt pass,还是第三方的混淆插件,都可以通过插件或 pass 管线接进来。
目前这一层开始测试,正在实验性支持阶段:
- 支持 LLVM 新 Pass Manager 和 Legacy Pass Manager 两种模式
- 支持按 pack 批量加载、按单个 plugin 加载、按 pass 名指定
- 支持 LLVM 版本检测和能力校验
- 内置 pack(比如 instcombine + simplifycfg 的组合)可以直接用
所以现在的情况是:我们自己的混淆器已经在跑,LLVM生态里已有的混淆能力也正在接入和测试中。
YAK
5.还在继续补的事情
到这里这条线的大概轮廓应该清楚了:主链路跑通了,混淆方向打开了,剩下重点在做稳定性和边界补齐。
具体来说:
混淆稳定性
混淆器本身能跑,但在不同组合、不同场景、不同规模的项目下的行为和性能,还需要继续验证和收口。这一层会持续做深。
语法支持稳定性
前面列的语法点都已经支持了,但复杂组合场景(比如闭包 + 对象 + 副作用叠加在一起)还需要更多测试覆盖。语法支持会一块一块补,稳定性也会一步一步提上来。
还有没实现的能力
map 完整支持、更完整的 slice 能力、更细粒度的 LLVM 原生类型系统——这些还在研发阶段,也是后续会继续推进的方向。
YAK
6.怎么理解现在的状态
SSA2LLVM 不是概念验证,也不是已经全面成熟的产品功能。它处在中间:主链路是跑通的,大部分基本语法是支持的,混淆管线是接好的,LLVM原生混淆接入也在测试中。现在的工作重心是混淆稳定性和语法支持的稳定性,一步一步往深做、做扎实。
它不是替代当前执行路径,而是一条被认真推进的工程线。
而且它已经推进到了一个阶段:你真的可以拿一份 Yaklang源码去编译出一份带混淆的原生二进制。
YAK
7.备注
本文内容基于仓库内 SSA2LLVM 状态文档与工程实现整理,重点参考:
common/yak/ssa2llvm/STATUS.mdcommon/yak/ssa2llvm/PROJECT.mdcommon/yak/ssa2llvm/readme.mdcommon/yak/ssa2llvm/docs/link-prep.mdcommon/yak/ssa2llvm/compiler/llvm_interop.gocommon/yak/ssa2llvm/llvminterop/doc.gocommon/yak/ssa2llvm/obfuscation/obfuscator.go
END
更新记录
Yakit v1.4.7-0522
-
MITM/Web Fuzzer系统代理Tag新增关闭按钮
-
修复Yak Runner等文件树UI展示问题
-
修复Web Fuzzer切换数据包时重置配置问题
-
修复部分暗色模式问题
-
优化编辑器美化问题
-
修复漏洞通知tag颜色问题
-
优化部分翻译问题造成的展示错位
-
修复启动Yakit是流量规则数据有时候未刷新展示的问题
Memfit AI v1.0.1-0522
-
优化会话框展示样式
-
Plan和意图设置可热更新和跟历史会话绑定
-
停止会话逻辑进行优化,会跟会话任务进行绑定
-
系统通知进行优化展示
-
历史会话排序优化为根据更新时间排序
YAK官方资源
Yak 语言官方教程:
https://yaklang.com/docs/intro/
Yakit 视频教程:
https://space.bilibili.com/437503777
Github下载地址:
https://github.com/yaklang/yakit
Yakit官网下载地址:
https://yaklang.com/
Yakit安装文档:
https://yaklang.com/products/download_and_install
Yakit使用文档:
https://yaklang.com/products/intro/
常见问题速查:
https://yaklang.com/products/FAQ
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:Yak Project YAK YAK《把 Yaklang 脚本编译成原生二进制:SSA2LLVM 现在走到哪了》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论