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

关注它,不迷路。       

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

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.mzph.cn/news/111363.shtml

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

相关文章

Docker 部署

1 完全清除旧版本docker for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; doneImages, containers, volumes, and networks stored in /var/lib/docker/ arent automatically removed when y…

一种退避序列实现

介绍功能和需求背景 介绍代码上下文,思路,方案。 讲解代码,评委穿插提问。参会的其他同学有问题也可以提。 评委对代码给建议和反馈 写在前面 你有一个苹果,我有一个苹果,交换一下我们还是只有一个苹果;…

人防行业通信系统

深圳市华脉智联科技有限公司是一家拥有核心自主知识产权的高科技企业,公司致力于公网对讲、融合通信、应急通信、执法调度等领域的系统和技术的开发和探讨,为行业用户提供一整套以通信为基础,软硬件结合的实战解决方案。华脉智联始终坚持将解…

RabbitMQ中的核心概念和交换机类型

目录 一、RabbitMQ相关概念二、Exchange类型三、RabbitMQ概念模型总结 一、RabbitMQ相关概念 Producer:生产者,就是投递消息的一方。生产者创建消息,然后发布到RabbitMQ中。消息一般可以包含两个部分:消息体和附加消息。 消息体…

git 新建 branch 推送 到服务器

通常情况下,需要开发一个模块,从 master 新建立了一个 分支,newbranch,如果推送到服务器; 1:从远程 master 建立本地分支 newbranch; git checkout -b newbranch origin/master 2:当修改完成代码…

@JsonCreator(mode = JsonCreator.Mode.DELEGATING) @JsonValue解释

@JsonCreator(mode = JsonCreator.Mode.DELEGATING)public MessageId(Long id) {this.id = id;}<

jmeter集成kafka测试

Kafka的使用 查看kafka的topic ./kafka-topics --bootstrap-server 10.1.9.84:9092 --list 查看topic信息 ./kafka-topics --bootstrap-server 10.1.9.84:9092 --describe --topic topic_example_1 创建topic 创建topic名为test&#xff0c;分区数为8&#xff0c;副本数为…

nginx动静分离

1、简单概述 Nginx动静分离简单说就是将动态请求和静态请求分开。可以理解说是用nginx处理静态页面&#xff0c;Tomcat处理动态页面。动静分离目前分为两种 方式一&#xff1a;纯粹将静态文件独立成单独的域名&#xff0c;放在独立的服务器上&#xff0c;也是目前主流的推崇方…

CSS【基础】

目录 一、CSS的介绍 二、CSS语法规则 三、CSS引入方式 四、CSS的基础选择器 五、CSS属性: 字体font 六、CSS属性&#xff1a;文本text 七、CSS属性&#xff1a;颜色 八、样式层叠问题 九、谷歌浏览器的调试工具 十、拓展&#xff1a;标签(盒子)水平居中的方法 一、C…

idgen导入Android11源码

文章目录 配置下载AS编译源码依赖导入玩一下andorid.iml 注意&#xff1a; 有些时候发现为啥自己编译就这么难呢&#xff1f;不是卡死就无数次重启虚拟机&#xff0c;一切的原罪在配置过低&#xff0c;换句话说就是穷。关于导入源码的下载参考 Android Studio for Platform (AS…

MAC如何在根目录创建文件

在这之前先明确一下啥是根目录。 打开终端&#xff0c;输入cd /&#xff0c;然后输入 ls 查看根目录下有哪些文件 可以看到 usr、etc、opt 这些文件的地方才叫根目录&#xff0c;而不是以用户命名&#xff0c;可以看到音乐、应用程序、影片、桌面的地方哈 介绍一种叫做软连接…

python字典

字典 字典定义创建字典 字典定义 字典是python语言中唯一的映射类型。这种映射类型由键&#xff08;key&#xff09;和值&#xff08;value&#xff09;组成&#xff0c;是“键值对”的无序可变序列 定义字典时&#xff0c;每个元组的键和值用冒号隔开&#xff0c;相邻元素用…

lspci源码

lspci 显示Linux系统的pci设备最简单的方法就是使用lspci命令&#xff0c;前提是要安装pciutils包&#xff08;centos在最小化安装时不会自带该包&#xff0c;需要自己下载安装&#xff09; pciutils包的源码github地址为&#xff1a; https://github.com/pciutils/pciutils …

Python数据挖掘实用案例——自动售货机销售数据分析与应用

&#x1f680;欢迎来到本文&#x1f680; &#x1f349;个人简介&#xff1a;陈童学哦&#xff0c;目前学习C/C、算法、Python、Java等方向&#xff0c;一个正在慢慢前行的普通人。 &#x1f3c0;系列专栏&#xff1a;陈童学的日记 &#x1f4a1;其他专栏&#xff1a;CSTL&…

【试题028】C语言关于逻辑与的短路例题

1.题目&#xff1a;设inta1,b;&#xff0c;执行b0&&(a);后&#xff0c;变量a的值是&#xff1f; 2.代码解析&#xff1a; #include <stdio.h> int main() {//设inta1,b;执行b0&&(a);后&#xff0c;变量a的值是?int a 1, b;printf("表达式的值是…

SQL 语法

SQL 语法规则 SQL语句总是以关键字开始&#xff0c;如SELECT、INSERT、UPDATE、DELETE、DROP、CREATE。SQL语句以分号结尾。SQL不区分大小写&#xff0c;意味着update与UPDATE相同。 数据库表 数据库通常包含一个或多个表。每个表都用一个名称标识&#xff08;例如&#xff0c;…

【ELK使用指南 2】常用的 Logstash filter 插件详解(附应用实例)

Logstash filter 一、logstash filter过滤插件的常用模块简介二、grok 正则捕获插件2.1 grok插件的作用2.2 内置正则表达式2.3 自定义正则表达式 三、mutate 数据修改插件3.1 mutate插件的作用3.2 常用的配置选项3.3 mutate插件应用实例 四、multiline 多行合并插件4.1 multili…

Mac上安装和配置Git

在Mac上安装和配置Git是一个相对简单的过程&#xff0c;以下是一份详细的步骤指南。 首先&#xff0c;你需要确保你的Mac已经安装了Homebrew&#xff08;如果还没有安装&#xff0c;可以通过以下命令安装&#xff1a;&#xff09;&#xff0c;Homebrew是一个包管理器&#xff…

Unity之ShaderGraph如何实现马赛克效果

前言 今天我们来实现一个马赛克的效果 如下所示&#xff1a; 关键节点 Posterize&#xff1a;色调分离节点 图像的色调分离或色调分离需要将色调的连续渐变转换为色调较少的几个区域&#xff0c;并从一种色调突然改变为另一种色调。 原理 原理就是通过色调分离节点&…

thinkphp队列的使用?

1.安装队列依赖 由于框架版本原因可以选择适合的版本 composer require topthink/think-queue 由于我是tp框架5.1的&#xff0c;所以选择了think-queue 1.1.6 composer require topthink/think-queue 1.1.6 判断安装成功 php think queue:work -h image.png 2.配置文件…