AST入门与反混淆初体验

news2024/12/27 13:06:12

文章目录

    • 1.什么是AST?
    • 2. AST反混淆的目的
    • 3. babel库安装
    • 4. 直观的理解AST
    • 5.如何用AST解混淆?思路是什么?
    • 6. babel库的学习
    • 7. AST反混淆初体验-常量折叠

1.什么是AST?

​ 在计算机科学中,抽象语法树(Abstract Syntax Tree,AST),或简称语法树(Syntax tree),是源代码语法结构的一种抽象表示。

​ 它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。

​ 之所以说语法是“抽象”的,是因为这里的语法并不会表示出真实语法中出现的每个细节。(摘自百度百科)

2. AST反混淆的目的

我们想这样:

1 + 2   ==> 3

AST反混淆的目的:让代码变得更简单,其逻辑不变,可读性增强。

用库的话,需要去了解它的api,调用它,它帮我们进行裁剪。 babel 库,相当于剪刀,胶水等工具

具体在哪里进行裁剪,需要自己去分析。
比如:

"Hello," + "AST!";    ===>   "Hello,AST!"; 
function br() {
            function r(r, n) {
                return Ur(n - 491, r)
            }
            var n = t
              , v = document[n(r(616, 610))](n(r(591, 604)));
            v && (v[n("OiIKRksPEDQr")] += n("eSMEUVktXCoiAlFdbB4sOg"))
        }

==>

function br() {
      var v = document["querySelector"]("div.px-captcha-container");
      v && (v["className"] += " modal-slide-out");
    }

目的:想要分析更简单的代码。

3. babel库安装

环境搭建参考:

node环境,及AST环境搭建(基于windows10)

在Node.js下,有关AST的库很多,我这里使用的是babel库,其他的库没做了解,babel库简单,功能强大是它的特点

在下载并安装后Node.js,就可以直接安装 babel库了。

安装命令:

npm install @babel/core --save-dev

在这里插入图片描述

在导入 @babel/parser 库后没有报错,那说明可以正常使用babel库了。

运行js可能会遇到错误:

Error: Cannot find module '@babel/parser'

解决方法:在当前目录下执行npm install @babel/core --save

4. 直观的理解AST

在线的解析网站:

https://astexplorer.net/

5.如何用AST解混淆?思路是什么?

首先要明确的是,你要做什么。比如看到源代码中,有很多类似这样的代码:

var a = "\u0068\u0065\u006c\u006c\u006f\u002c\u0041\u0053\u0054";

这代码看起来,可读性就差了很多,如果不是特别记忆,根本看不出是什么字符。

这个时候,你想把它还原成本来的面目:

var a = "hello,AST";

这样对你来说,就清晰多了。这时,你的目的就出来了,想要将

"\u0068\u0065\u006c\u006c\u006f\u002c\u0041\u0053\u0054"

替换成:

"hello,AST"

在这里,如果只有这一行我们直接手动替换就好了。那如果代码中有大量这样的字符串呢?也是一个一个手动替换吗?

那我们肯定选择用工具来完成这个重复的工作,目的明确了,现在就是如何编写工具了。

var a = "\u0068\u0065\u006c\u006c\u006f\u002c\u0041\u0053\u0054";

放在在线网站进行解析,发现要处理的字符串是一个 StringLiteral 类型的节点:

在这里插入图片描述

在使用babel库操作时,只需遍历这个类型的节点,就会处理全部的 StringLiteral节点。

要处理节点,那肯定要理解babel库的相关知识。

1.babel库官方文档:

https://babeljs.io/docs/en/

2.babel库github地址:

https://github.com/babel/babel

3.babel库官方插件开发手册:

https://github.com/jamiebuilds/babel-handbook

4.babel库官方插件

https://www.babeljs.cn/docs/plugins

6. babel库的学习

  1. JavaScript源代码转AST结构,@babel/parser,代码路径:

    node_modules\@babel\parser\lib
    

    在 node_modules@babel\parser\bin\babel-parser.js 该文件中有一段打印AST的代码,如下:

    var filename = process.argv[2];
    if (!filename) {
      console.error("no filename specified");
    } else {
      var file = fs.readFileSync(filename, "utf8");
      var ast = parser.parse(file);
    
      console.log(JSON.stringify(ast, null, "  "));
    }
    
    
  2. AST结构转JavaScript源代码,@babel/generator,代码路径:

    node_modules\@babel\generator\lib\generators
    
  3. 遍历 AST结构 的相关api,@babel/traverse,代码路径:

    node_modules\@babel\traverse\lib
    

    该路径下的 path 和scope 子文件夹是学习的重点。

  4. 构建新的节点,@babel/types,代码路径:

    node_modules\@babel\types\lib
    

解混淆能用到的api,基本就在这四个目录里面了,建议直接从源代码开始学习。

7. AST反混淆初体验-常量折叠

建议先看一下蔡老板写的的先导知识:利用AST解混淆先导知识:调用babel库反混淆代码模板

解混淆通用框架:

//babel库及文件模块导入
const fs = require('fs');

//babel库相关,解析,转换,构建,生产
const parser = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const types = require("@babel/types");
const generator = require("@babel/generator").default;
//读取文件
let encode_file = "./encode.js",decode_file = "./decode_result.js";
if (process.argv.length > 2)
{
  encode_file = process.argv[2];
}
if (process.argv.length > 3)
{
  decode_file = process.argv[3];
}

let jscode = fs.readFileSync(encode_file, {encoding: "utf-8"});
//转换为ast树
let ast    = parser.parse(jscode);

const visitor =
{
  //TODO  write your code here!
}

// 可以将整个ast规整的打印出来
// JSON.stringify(ast,null,'\t');
//some function code

//调用插件,处理源代码,顺序执行,依次调用
// traverse(ast,插件名称);
// traverse(ast,插件名称2);

traverse(ast,visitor);

//生成新的js code,并保存到文件中输出
let {code} = generator(ast);
fs.writeFile('decode_result.js', code, (err)=>{});

以下面最简单的一行js代码为例(encode.js):

var a = 1 + 2 ;

想转换成这样(decode_result.js);

var a = 3 ;

利用ast在线解析网站:AST在线解析

鼠标点到“+”号旁边,观察节点类型:

在这里插入图片描述

在解混淆通用框架visitor里开始编写插件规则,并导出,详细代码:

//babel库及文件模块导入
const fs = require('fs');

//babel库相关,解析,转换,构建,生产
const parser = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const types = require("@babel/types");
const generator = require("@babel/generator").default;
//读取文件
let encode_file = "./encode.js",decode_file = "./decode_result.js";
if (process.argv.length > 2)
{
  encode_file = process.argv[2];
}
if (process.argv.length > 3)
{
  decode_file = process.argv[3];
}

let jscode = fs.readFileSync(encode_file, {encoding: "utf-8"});
//转换为ast树
let ast    = parser.parse(jscode);

const visitor =
{
  //TODO  write your code here!
    "BinaryExpression":{
	enter(path)
	{
		let {left,operator,right} = path.node;
		if (types.isNumericLiteral(left) && operator == '+' && types.isNumericLiteral(right))
		{
			console.log(path.toString());
			let value = left.value + right.value;
			let newNode = types.NumericLiteral(value);
			path.replaceWith(newNode);
		}

    }
	},
}

// JSON.stringify(ast,null,'\t');
//some function code

//调用插件,处理源代码
traverse(ast,visitor);

//生成新的js code,并保存到文件中输出
let {code} = generator(ast);
fs.writeFile('decode_result.js', code, (err)=>{});

运行以上代码,可以看到产生的decode_result.js文件内容成功转换:

在这里插入图片描述

大概就是这种处理思想。

但是如果是:

var b = 4 - 3;
var c = 1 + 2 + 3 + 4 ;

这样的就处理不了,多写几个判断又太繁琐,这里引入蔡老板写好的常量折叠通用插件:

const constantFold = 
{
	 "BinaryExpression|UnaryExpression|ConditionalExpression"(path)
  {
  	if(path.isUnaryExpression({operator:"-"}) || 
  	  path.isUnaryExpression({operator:"void"}))
  	{
  		return;
  	}
  	const {confident,value} = path.evaluate();
  	if (!confident || value == "Infinity") return;
  	if (typeof value == 'number' && isNaN(value)) return;
  	path.replaceWith(types.valueToNode(value));
  },
}

看一下需要解混淆的js:

var a = 1 + 2;
var b = 4 - 3;
var c = 1 + 2 + 3 + 4 ;

调用常量折叠通用插件的还原结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dg4WybOE-1675242038111)(AST总结文档.assets/image-20230201163454432.png)]
蔡老板写了很多这样好用的插件,感兴趣的话可以加入蔡老板的知识星球AST入门与实战,站在巨人的肩膀上,跟着大佬走总比自己摸索要强很多(工具人的觉悟)

文章到此结束,感谢您的阅读,下篇文章见!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/192865.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【服务器数据恢复】raid5中3块磁盘先后掉线的数据恢复案例

服务器数据恢复环境&故障: 某单位同友存储设备,该存储有大于5台的虚拟机,其中有3台linux系统虚拟机存储重要数据。存储设备中组建的raid5由于未知原因崩溃导致存储无法启动。 存储结构: 服务器数据恢复过程: 1、对…

C语言进阶——字符函数和字符串函数(上)

目录 一、前言 二、正文 1.求字符串长度 ♥strlen 2.长度不受限制的字符串函数 ♥strcpy ♥strcat ♥strcmp 三、结语 一、前言 一日不见,如隔三秋;几日不见,甚是想念。猜想小伙伴们在平常进行有关字符的练习时遇到有关字符的操作却无从下手…

GEC6818 移植 rtl8723bu wifi驱动

文章目录1. 配置内核2、RTL8723BU 模块驱动编译2.1 下载解压2.2 配置编译3. openssl 移植3.1 下载解压3.2 配置3.3 编译安装4. libnl 移植4.1 下载解压4.2 进入源码目录并配置4.3 编译安装5. wpa_supplicant 移植5.1 解压源码5.2 配置5.3 make编译6. 启动wifi网卡6.1 配置WiFi连…

Python调用Go语言编译的动态链接库(CGO)【待续】

CGO C 语言作为一个通用语言,很多库会选择提供一个 C 兼容的 API,然后用其他不同的编程语言实现。Go 语言通过自带的一个叫 CGO 的工具来支持 C 语言函数调用,同时我们可以用 Go 语言导出 C 动态库接口给其它语言使用。 hello world程序 p…

【定时同步系列11】各种开环定时同步算法与MCRB性能对比的MATLAB仿真

重要声明:为防止爬虫和盗版贩卖,文章中的核心代码和数据集可凭【CSDN订阅截图或公z号付费截图】私信免费领取,一律不认其他渠道付费截图! 引言 开环定时同步包括内插控制、定时误差估计等环节,其中内插控制在之前的博客里有详细的描述,请翻阅之前的博客! 【定时同步系…

Python编程技巧分享:6 个必知必会高效 Python

编写更好的Python 代码需要遵循Python 社区制定的最佳实践和指南。遵守这些标准可以使您的代码更具可读性、可维护性和效率。 本文将展示一些技巧,帮助您编写更好的 Python 代码 遵循 PEP 8 风格指南 PEP 8 是 Python 代码的官方风格指南。它提供了一组用于格式化…

Maven parent多项目打包找不到reversion变量问题

项目结构:packagetest:顶级父级c1:子项目(web项目)c2:子项目(jar包)c1依赖c2的jar包。在父级maven中deploy成功,package也成功,私服上有都有包了。但是在c1上package的时候&#xff…

二十、操纵管道

本章将讨论如何在应用程序中使用多种方式操作管道。本章的部分内容都是很底层的,所以在开始阅读之前,请确保你需要一些编程知识,并对GStreamer有很好的理解。 这里将讨论的主题包括如何从应用程序向管道中插入数据,如何从管道中读…

电商项目之Mailgun邮件退信率升高

文章目录1 项目背景2 前言3 采取的措施4 排查的思路5 原因6 技术实现方案1 项目背景 运维人员进行日常巡检发现Mailgun邮件代发渠道的退信率不寻常,在某个时间段会飙高。这会有2个影响: (1)针对运维的角度,Mailgun官方…

3.SpringBoot配置

一、IOC的好处在对象依赖关系复杂的对象中,只需要考虑“我自己”依赖什么,减少程序员思考负担方便的进行依赖概念(接口、抽象类)的实现类对象的替换。二、什么是SpringBoot?1.SprigBoot是Spring的一个子工程,目标就是…

JS逆向技巧汇总---给普通爬虫学习者的吐血建议

爬虫实战的JS逆向,就像是做侦探。很多时候,我们要尝试不同方式和手段寻找线索,不能放过蛛丝马迹,通过仔细观察和比较,然后顺藤摸瓜,找到加密入口。再调试JS代码的时候,需要保持清晰的目标和方向…

专科逆袭入职腾讯,真是小母牛坐飞机,牛逼上天了..

在踏入腾讯,办理入职手续的那一天,作为一个男子汉,确实是落泪了。特地分享一波我的真实经历,共勉。 先说一下自己的个人情况,18 届应届生,通过校招进入到了国内某二线城市传统互联网公司,然后一…

优化算法:曲径步长通优处,优化半天白优化

本文来自公众号“AI大道理” 训练一个神经网络,我们想要得到误差最小,就是要我们的损失函数最小。 如何得到最小值呢? 这就是优化算法。 梯度下降法是众多优化中的一种。 1、损失函数 2、GD(梯度下降法) 3、BGD&a…

Java集合基础

文章目录集合基础一、集合介绍1. 什么是集合&#xff1f;2. 集合类型3. ArrayList 长度可变原理4. 集合和数组的使用选择二、ArrayList 集合快速入门集合创建语句泛型(<>)三、集合常用成员方法1. 增加元素2. 删除元素3. 修改元素4. 查找数据四、集合遍历1. 集合存储字符串…

国联易安:2023年网络安全“五大技术”预测

我国对网络安全非常重视&#xff0c;明确指出“安全是发展的前提&#xff0c;发展是安全的保障&#xff0c;安全和发展要同步推进”。作为国内专注于保密与非密领域的分级保护、等级保护、业务连续性安全和大数据安全产品解决方案与相关技术研究开发的领军企业&#xff0c;国联…

数学建模与数据分析 || 3. 面向数据的特征提取方法: 探索性数据分析

面向数据的特征提取方法: 探索性数据分析 文章目录面向数据的特征提取方法: 探索性数据分析1. 原始数据的准备1.1 导入 python 模块1.2 导入数据集并进行宏观认识1.3 数据集描述2. 数据的预处理2.1 缺失数据的甄别2.2 类别规模的评估3. 数据特征的处理3.1 第一个因变量- 分析范…

【Linux】Linux调试器-gdb使用

作者&#xff1a;小卢 专栏&#xff1a;《Linux》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 目录 1.背景 2.gdb的使用 2.1如何生成可以调试debug版本的文件&#xff1a; 2.2如何查看调试信息&…

wcf服务启动禁用Wcf测试客户端(WcfTestClient)

以下页面在WCF工程运行时&#xff0c;会自动启动wcf测试客户端。如果想禁止&#xff0c;可以通过这个方法。 如果希望F5时始终启动IE&#xff0c;可以在.csproj.user文件里增加EnableWcfTestClientForSVC属性配置以禁用WCF测试客户端&#xff1a; <Project> <ProjectE…

Excel等文件中出现新型恶意软件Dropper,通过钓鱼邮件传播

Dropper 是将 Payload 部署到失陷主机的恶意软件&#xff0c;被很多攻击者使用。2022 年第二季度研究人员发现了一些活跃的 Dropper&#xff0c;例如 Microsoft Excel 文件以及 Windows 快捷方式文件和 ISO 文件。通过与社会工程相结合的攻击方式&#xff0c;诱使受害者触发失陷…

打脸质疑者!Mobileye市值冲高,公司CEO说出心声

三个多月前&#xff0c; Mobileye以21美元发行价第二次在美股IPO上市。截止上周五&#xff0c;该公司股价升至32.98美元&#xff0c;市值达到264.47亿美元。相比于美股其他自动驾驶公司股价跌跌不休&#xff0c;显然&#xff0c;资本市场更看重企业的盈利能力和可预见的营收规模…