AST反混淆实战|某国外混淆框架一小段混淆js还原分析

news/2024/11/29 2:36:08/

关注它,不迷路。       

本文章中所有内容仅供学习交流,不可用于任何商业用途和非法用途,否则后果自负,如有侵权,请联系作者立即删除!

1. 需求

我相信做币圈爬虫的兄弟,或多或少的见过类似下面的混淆js:

860b681b9aace0e4dd4a76ea38907f53.png

大部分的变量名,主要以 "__p_" 开头,分析下来,其实是ob混淆上面再套了一层壳。

再去掉第一层壳以后,发现还套了一层,它的函数如下:

function __p_1295650017_calc(__p_0552970006, __p_6576181459) {switch (__p_3757655876) {case 12:return !__p_0552970006;case 26:return -__p_0552970006;case -29:return __p_0552970006 + __p_6576181459;case -6:return __p_0552970006 - __p_6576181459;case 57:return ~__p_0552970006;case 35:return __p_0552970006 / __p_6576181459;case 3:return __p_0552970006 * __p_6576181459;case 2:return typeof __p_0552970006;case 6:return void __p_0552970006;}
}

这个混淆函数很有意思,它有两个形参,函数里面有包含一个全局变量 

__p_3757655876,而这个全局变量,又由下面的函数来控制:

function __p_2245858992(a) {a = __p_3757655876 + (__p_3757655876 = a, 0);return a;
}

而上面的 混淆函数,它的函数调用有这样的:

__p_1295650017_calc(1940, __p_3757655876 = 26)

函数的结果很明显是 -26;

也有这样的:

__p_1295650017_calc(_0x10e09f(746), "e", __p_2245858992(-29))

函数的结果很明显是 _0x10e09f(746) + "e";

还有一个,就是,对于不同版本的混淆文件,它的这个函数定义是变化着的,如:

function __p_0807818337_calc(__p_9916442306, __p_4970943498) {switch (__p_3679524284) {case 13:return !__p_9916442306;case 7:return -__p_9916442306;case 31:return __p_9916442306 + __p_4970943498;case 3:return __p_9916442306 - __p_4970943498;case 21:return ~__p_9916442306;case 50:return __p_9916442306 / __p_4970943498;case -47:return __p_9916442306 * __p_4970943498;case 18:return typeof __p_9916442306;case 55:return void __p_9916442306;}
}

2. 共同点

如果想要写出通用的插件,就得找出它的共同点。先来看看有哪些共同点:

  1. 函数名不一样,但都以 _calc 结尾

  2. 函数体结构是一样的,但是 每个case 后面的值不一样。

  3. case体是一样的,都是 return 语句。

很快写出代码:

const getCalcFunction = 
{FunctionDeclaration(path){let {scope,node} = path;let {id,body,params} = node;let name = id.name;if (!name.endsWith('calc')){return;}}
}

因为整个混淆js,只有它是以 "calc" 结尾的,因此,只需简单的判断一下就可以了。

接下来怎么写呢?

根据每个case 里的return语句来写?

3. 隐藏的彩蛋

观察 每个case里的return语句,拿到在线解析网站上观察,只有两种类型:

BinaryExpression  UnaryExpression 类型,而它们有个共同点,都有 operator 这个子节点,即操作符。因此,我们可以使用 一个 Object类型的变量来保存它.即通过每个 case的值 和 operator 来注册一个键值对,保存起来。遍历的时候去取就可以了。

const getCalcFunction = 
{FunctionDeclaration(path){let {scope,node} = path;let {id,body,params} = node;let name = id.name;if (!name.endsWith('calc')){return;}let newMap = new Object();let cases = body.body[0].cases;for (let eachCase of cases){let {test,consequent} = eachCase;let value = test.value || -test.argument.value;let operator = consequent[0].argument.operator;newMap[value] = operator;}console.log(newMap);}
}

打印结果:

1d51aaaa2a64cca71667c04e6f9cecf6.png

拿到了 case 的值和 它的操作符,再去构造节点就简单了。

这里也许你有个疑问,就是 BinaryExpression  UnaryExpression 它们有个共同的操作符:  "-",如何区分呢?

当然是根据它函数调用的实参个数来区分了。实参是2个的时候,它肯定是UnaryExpression  类型;实参是3个的时候,它肯定是 BinaryExpression 类型。

文件demo在星球里,请星友们完成后续的还原工作:

https://t.zsxq.com/13Sv5Igr1

今天的文章就分享到这里,后续分享更多的技巧,敬请期待。

6e592ed211219aabdfeb2264206fbbc0.jpeg

欢迎加入知识星球,学习更多AST和爬虫技巧。


http://www.ppmy.cn/news/1170362.html

相关文章

Mysql数据库 2.SQL语言 数据类型与字段约束

Mysql数据类型 数据类型:指的是数据表中的列文件支持存放的数据类型 1.数值类型 Mysql当中有多种数据类型可以存放数值,不同的类型存放的数值的范围或者形式是不同的 注:前三种数字类型我们在实际研发中用的很少,一般整数类型…

[Ubuntu 20.04] HEIF图像格式与libheif库及其工具的使用

一、HEIF图像格式 HEIF 是一种高效的图像文件格式,它由 MPEG(Moving Picture Experts Group)组织制定。相较于传统的 JPEG 格式,HEIF 提供了更好的图像质量和更高的压缩率。下面是对 HEIF 格式的详细解析: 图像编码技术:HEIF 使用先进的编码技术来实现更高效的图像压缩。…

java读取指定文件夹下的全部文件,并输出文件名,文件大小,文件创建时间

import java.io.IOException; import java.nio.file.*; import java.nio.file.attribute.*; import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { try { Path startingDir Paths.get("你的目…

FPGA设计FIR滤波器低通滤波器,代码及视频

名称:FIR滤波器低通滤波器 软件:Quartus 语言:Verilog/VHDL 本资源含有verilog及VHDL两种语言设计的工程,每个工程均可实现以下FIR滤波器的功能。 代码功能: 设计一个8阶FIR滤波器(低通滤波器&#xff…

字符串的匹配——KMP算法的学习

一、核心: 当出现字符串不匹配时,可以记录一部分之前已经匹配的文本内容,利用这些信息避免从头再去做匹配,因此需要一个数组记录已经匹配的文本内容。 对于字符串匹配问题,暴力法也叫朴素求解法是将两个字符串…

UE5--物体卡片与材质入门

参考资料: 《Unreal Engine5 入门到精通》--左央 虚幻引擎5.2文档:https://docs.unrealengine.com/5.2/zh-CN/ 前言: 跟着左央老师的《Unreal Engine5 入门到精通》学习制作AI版胡闹厨房,把学习过程与学习到的东西归纳总结起来。 …

Java:SpringBoot实现JDK动态代理和CGLIB动态代理

目录 1. JDK 动态代理2. CGLIB 动态代理总结参考文章 需要代理的对象 // 接口 public interface PayService {void pay(); }// 实现 public class AliPayService implements PayService {Overridepublic void pay() {System.out.println("AliPayService");} }1. JDK…

实现图像处理和分析的关键技术

在计算机视觉中,我们可以利用摄像头捕捉到的图像来进行各种分析和处理。以下是一些常见的计算机视觉任务: 对象检测:识别图像中的特定对象并标注其位置。人脸识别:识别和验证人脸身份。姿态估计:估计人体的姿态和动作…