如何在浏览器中使用 AST 实时反混淆?(附AST模版可直接使用)

大家好,今天分享一个在浏览器中使用原生 babel 库进行实时反混淆的方案。

浏览器 AST

说到在浏览器中运行 AST 的方案,目前我个人测试可用的有两种方案:

  • 使用 babel 在浏览器中进行 AST 反混淆,仅用于编写和调试 AST 代码
  • 在对应的网站中使用 babel 进行 AST 反混淆,可以做到实时反混淆

浏览器反混淆

先说第一种方案,在浏览器中进行 AST 反混淆,此方案适用于部分会检测浏览器环境的代码或者动态生成的混淆代码。因为在 nodejs 中没有 window 对象,如果在 nodejs 中处理效果就不是很好,在浏览器中就比较方便了。

使用方式还是老朋友:https://astexplorer.net/,打开这个 AST 解析网站,将需要反混淆的代码粘贴到左侧上面的窗口中。

image-20250520220245942

然后点击 babel7,下面会自动再打开两个窗口,左侧就是 AST 代码,右侧是处理的结果。

image-20250520220827072

这样一来,真正实现了在一个窗口中展示所有我们需要的东西,原始代码,AST 语法树,AST 处理代码,处理结果,并且处理结果是实时显示的,不用手动点击运行。图中是默认的 AST 代码,作用是反转一个标识符字符串,可以看到结果中所有的标识符都被反转了,当然这个代码是无法运行的,这里仅作为示例。

有了这个网站其实调试 AST 都可以在浏览器中进行,只需要一个网页即可完成 AST 的解析+调试,并且实时输出结果,一条龙服务。当然了,也不是完全没有缺点,实时输出结果可能会影响性能,这个就看大家的需求了,按需使用。

实时反混淆

第二种方案就是实时进行 AST 反混淆,该方案适用于需要反混淆的代码无法粘贴出来的情况或者混淆代码是动态变化的情况。之前的文章中提到过将 nodejs 的模块打包后放到浏览器中运行的方案,有小伙伴留言说 babel 有官方的独立库,我按照关键字找了一下还真有。不过 Github 一直没更新,但是官网中是有的。

image-20250520213500237

并且官网直接给出了链接,将 script 标签注入到想要实时反混淆的网站即可使用 babel 进行 AST 处理。

在使用的时候,先要导入对应的方法:

1
2
3
4
const types = Babel.packages.types;
const parser = Babel.packages.parser;
const traverse = Babel.packages.traverse.default;
const generator = Babel.packages.generator.default;

然后将代码解析为 AST 语法树,编写 AST 反混淆逻辑,再生成代码执行即可。

1
2
3
4
5
traverse(ast, {
Identifier(path) {
path.node.name = path.node.name.split('').reverse().join('');
}
})

其他逻辑和使用 nodejs 进行反混淆的逻辑一致,可以直接套用。不会使用的小伙伴可以在文章的最后自取浏览器版本的 AST 实时反混淆模版。

image-20250520223411477

image-20250520223426661

执行效果如上图所示,AST 代码正常运行,正确的反转了所有的标识符。

AST 实时反混淆实战

说完了原理,咱们来实战试试,本次使用猿人学 2024 春节题目作为示例。

这道题使用 JS盾进行了混淆,每次 eval 执行的代码都是动态生成的,而且将生成好的代码复制出来直接运行或者使用 eval 运行都会报错,应该是检测了某些环境或者在生成代码的时候生成了某些检测点,如果检测不到就走了错误的逻辑分支。

其实有办法可以将生成的代码固定下来,之前的文章有写过方法,后面再具体讲。

image-20250520221939210

生成后的代码使用了大量的逻辑表达式进行混淆。

image-20250520222953228

并且生成的代码中还有一个特殊的 Unicode 字符,会干扰浏览器的格式化功能,导致格式化后的代码长这个样子,如上图,完全没法看,也没法调试。

image-20250520222253573

如果将代码复制出来直接执行的话,会报错,因为生成后的代码中有大量的控制流,所以暂时无法找出问题在哪里。

说完了背景,再来说说如何使用实时 AST 的方案来解决这个问题。

实时 AST

image-20250520222457762

首先要记得引入 babel 的 JS 文件,在网站的主 html 中添加一行代码即可。

然后导入所需的依赖,并且使用 AST 反混淆模版即可,模版在文章的最后,大家自取

image-20250520222626325

实时反混淆效果

image-20250520222734925

上面就是实时 AST 的效果,现在已经可以正常的格式化了,并且变量中比较诡异的字符也已经被去掉了。目前是可以正常调试的,打断点之类功能也 OK,只不过控制流还是没有去除,这个就留给大家自行思考如何去除了。(不要问我,我也不会哈哈哈,在努力学习中)

AST 实时反混淆模版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!DOCTYPE html>
<html lang="cn">
<head>
<meta charset="UTF-8">
<title>AST 实时反混淆模版</title>
</head>
<body>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script>
//导入所需要的依赖,如果不够请自行添加,非必要这里不用改动
const types = Babel.packages.types;
const parser = Babel.packages.parser;
const traverse = Babel.packages.traverse.default;
const generator = Babel.packages.generator.default;

//实际的反混淆函数
function astProcess(s) {
//解析代码
let ast = parser.parse(s);

//这里写你的反混淆逻辑
//举个例子:
traverse(ast, {
Identifier(path) {
path.node.name = path.node.name.split('').reverse().join('');
}
})
//反混淆逻辑结束

let {code} = generator(ast, opts = {
"compact": true,//建议压缩代码,防止格式化检测。压缩后可以使用浏览器格式化,浏览器格式化不会触发格式化检测
});
return code;
}
</script>
<script>
//这里调用 AST 反混淆逻辑,举个例子
let code = astProcess('let abcd=1;\n' +
'console.log(abcd)')
console.log(code);

</script>
</body>
</html>

将以上内容复制到 html 文件中直接运行即可在控制台看到反混淆结果。

注:别忘了在修改好的 AST 语法树重新生成代码的时候压缩一下,防止格式化检测。 使用浏览器的格式化功能只会对代码样式进行格式化,不会修改实际的代码,所以不会触发格式化检测。

总结

以上就是使用浏览器进行 AST 反混淆调试和实时 AST 反混淆的所有内容。以上方案目前我个人测试通过,不保证在所有情况下可用,如果大家在使用中有其他的问题,可以在下方留言,谢谢大家。

本文章首发于个人博客 LLLibra146’s blog

本文作者:LLLibra146

更多文章请关注公众号 (LLLibra146):LLLibra146

版权声明:本博客所有文章除特别声明外,均采用 © BY-NC-ND 许可协议。非商用转载请注明出处!严禁商业转载!

本文链接
https://blog.d77.xyz/archives/922c64b6.html