AST系列文章|根据节点前后的变化来写代码

关注它,不迷路。       

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

需求

本文以一个简短的混淆js代码来讲解如何根据节点前后的变化来写代码。代码如下:

calc(p?33:34);

为什么要还原?

因为还原后,方便后续的处理,如果这里不还原,没办法 计算出 calc 这个函数的值,因为实参不是常量的调用表达式,是没办法在AST文件中计算它的值的。也就不能反混淆。

还原后的代码是怎样的?

根据js基础知识,它还原后的代码应该是这样的:

p?calc(33):calc(34);

还原前后的代码有什么异同?

就整个代码而言,都是 ExpressionStatement 类型的表达式,而它的 expression 子节点却发生了变化:

由 CallExpression 变成了 ConditionalExpression 表达式。

因此这里会有一个 生成 ConditionalExpression 表达的过程,还有一个替换节点的过程。

混淆代码有哪些特征,如何过滤?

首先,它是一个 CallExpression 类型,主要关心的是它的 arguments 节点。

1. 只有一个实参,即arguments 长度为1

2.实参是ConditionalExpression 表达式。

因此,过滤这两个特征即可。

AST插件源码

完整代码如下:

const changeCallToConditionalExpression =
{CallExpression(path) {let { callee, arguments } = path.node;if (arguments.length != 1 || !types.isConditionalExpression(arguments[0])) {return;}let { test, consequent, alternate } = arguments[0];let newConsequent = types.callExpression(callee, [consequent]);let newAlternate = types.callExpression(callee, [alternate]);let newConditionalNode = types.ConditionalExpression(test, newConsequent, newAlternate);path.replaceWith(newConditionalNode);}
}traverse(ast, changeCallToConditionalExpression);

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

bca3e67518a07a9234765c1024c37e0b.jpeg

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

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

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

相关文章

基于单片机音乐弹奏播放DS1302万年历显示及源程序

一、系统方案 1、本设计采用51单片机作为主控器。 2、DS1302计时显示年月日时分秒。 3、按键可以弹奏以及播放音乐,内置16首音乐。 二、硬件设计 原理图如下: 三、单片机软件设计 1、首先是系统初始化 /时钟显示**/ void init_1602_ds1302() { write…

市级奖项+1,持安获「创业北京」创业创新大赛优秀奖!

2274个创业项目参赛 历经五个多月的激烈角逐 第六届“创业北京”创业创新大赛 终于圆满落下帷幕 持安科技在北京市总决赛中再创佳绩! 荣获制造业赛道优秀奖 本次大赛由北京市人力资源和社会保障局、北京市发展和改革委员会等11家单位联合主办,以“创…

初识MongoDB及安装

文章目录 一、MongoDB核心概念1、库2、集合3、文档4、关系总结 二、MongoDB的安装总结 一、MongoDB核心概念 1、库 mongodb中的库就类似于传统关系型数据库中库的概念,用来通过不同库隔离不同应用数据。mongodb中可以建立多个数据库。每一个库都有自己的集合和权限…

C++项目案例圆和点的关系 (涉及知识点:头文件定义类,cpp文件实现类,类和作用域,linux编译运行c++项目)

一.项目描述 点与圆有三种关系&#xff1a; 点在圆外 点在圆上 点在圆内计算点到圆心的距离就能判断点在圆的哪个地方。二.项目结构 三.include文件 3.1 Circle类的声明 Circle.h // 防止头文件重复包含 #pragma once // #include<iostream> #include "Point.h&…

C语言--从键盘输入10个数字放在数组中,并输出

用scanf读取数字的时候要注意&#xff0c;可以输入一个数字&#xff0c;按一下回车&#xff0c;输入一个数字&#xff0c;按一下回车&#xff0c;也可以一次性输入完10个数据。&#xff08;中间可以用空格隔开&#xff0c;系统会自动识别&#xff09; 输出一:每按下一个数字&am…

B-2:Linux系统渗透提权

B-2:Linux系统渗透提权 服务器场景:Server2204(关闭链接) 用户名:hacker 密码:123456 1.使用渗透机对服务器信息收集,并将服务器中SSH服务端口号作为flag提交; 使用nmap扫描,发现ssh服务端口为2283 Flag:2283 2.使用渗透机对服务器信息收集,并将服务器中…

Linux 阻塞机制及等待队列

原文地址: http://www.cnblogs.com/gdk-0078/p/5172941.html 阻塞与非阻塞是设备访问的两种方式。驱动程序需要提供阻塞&#xff08;等待队列&#xff0c;中断&#xff09;和非阻塞方式&#xff08;轮询&#xff0c;异步通知&#xff09;访问设备。在写阻塞与非阻塞的驱动程序时…

二十、Linux网络配置

1、Linux网络配置原理 我自己Linux虚拟机的IP地址是&#xff1a;192.168.159.131 vmnet8&#xff1a;192.168.159.1 无线网卡&#xff1a;192.168.159.1 2、查看网络IP和网关 查看虚拟网络编辑器和修改IP地址 如果把这个位置的子网IP换成&#xff1a;192.168.8.0的话重启虚拟机…

开源与闭源:创新与安全的平衡

目录 一、开源和闭源的优劣势比较 一、开源软件的优劣势 优势 劣势 二、闭源软件的优劣势 优势 劣势 二、开源和闭源对大模型技术发展的影响 一、机器学习领域 二、自然语言处理领域 三、数据共享、算法创新与业务拓展的差异 三、开源与闭源的商业模式比较 一、盈…

原型网络Prototypical Network的python代码逐行解释,新手小白也可学会!!由于工作量大,准备整5个系列完事,-----系列1

文章目录 一、数据集展示二、代码第一步--导入库与读入训练集和测试集解释1.原始代码如下2.代码解释 总结 一、数据集展示 二、代码第一步–导入库与读入训练集和测试集解释 1.原始代码如下 import os import matplotlib.image as mpimg import numpy as np import csv os.ch…

【实习】串口通信

modbus介绍 详解Modbus通信协议—清晰易懂 Modbus协议是一个master/slave架构的协议。有一个节点是master节点&#xff0c;其他使用Modbus协议参与通信的节点是slave节点。每一个slave设备都有一个唯一的地址。在串行和MB网络中&#xff0c;只有被指定为主节点的节点可以启动一…

【Linux】线程互斥

文章目录 线程互斥互斥量 mutex初始化互斥量加锁与解锁 可重入和线程安全常见的线程安全情况常见的线程安全的情况常见的不可重入情况常见的可重入情况可重入与线程安全联系可重入与线程安全区别 死锁死锁的四个必要条件避免死锁 线程互斥 进程线程间的互斥相关背景概念 临界…