IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> JavaScript-Obfuscator4.0.0字符串阵列化Bug及修复方法 -> 正文阅读

[JavaScript知识库]JavaScript-Obfuscator4.0.0字符串阵列化Bug及修复方法

JavaScript-Obfuscator4.0.0字符串阵列化Bug及修复方法

Javascript-obfuscator是全球知名的开源JavaScript代码混淆加密工具,由俄罗斯程序员Timofey Kachalov开发维护。

在2022年2月15日发布的4.0.0版本中,其存在一个字符串阵列化Bug,某些情况下会导致混淆结果异常。本文对Bug情况进行说明并提供修复方法。

注:此bug由JShaman团队发现,并已提交作者修复。

JShaman是国内专业的javascript源代码安全研究组织,与Javascript-obfuscator保持着友好联络与技术交流。

Bug描述:


Javascript-obfuscator4.0.0,其字符串阵列功能,对async函数中的成员对象进行阵列化处理,会导致代码异常。

例如,一段NodeJS代码:

async function waitPage(page) {
    await page.evaluateHandle(function(){
        return window.renderdone;
    });
 }
 
 (async () => {
     const puppeteer = require('puppeteer');
     puppeteer.launch().then(
         async browser => {
             console.log('...');
             const [page] = await browser.pages();
             await page.goto('https://www.baidu.com');
             await waitPage(page);
         }
     )
 })();

使用Javascript-obfuscator进行混淆加密,保护选项只选择了字符串阵列化这一个功能:

混淆加密后的代码,运行时发生异常,提示有变量未定义:

注意图中命令行中所显示,第一次执行是在未加密前,可正常使用。第二次是执行加密后的代码,出现错误。

Bug原因:

上述JS代码混淆加密后出现错误的原因,是由于进行字符串的阵列化处理时,未考虑是否处于async函数中。导致阵列化时MemberExpression字面量放置到了函数不可访问的外部区域中。如下图所示:

注:绿线上方是原始代码,做对比用。参考上面图中的错误提示变量,可以看出错误原因。

Bug修复方案:

阵列化功能,在JavaScript-Obfuscator目录下的StringArrayTransformer.ts文件中。

以下为临时修复代码:

//原始: return this.transformNode(node, parentNode);

//修复bug后的代码:

//是否是异步函数的标识
var in_async_function = false;
//递归函数,检测节点所有上级节点,判断是否处于异步函数中
var point = "-";
function detect_async_function(node:ESTree.Node){
    console.log(point, node.type);
    if(node.type == "FunctionDeclaration"){
        console.log(point, node.id?.name);
    }

    //是函数定义,并且是异步函数
    if((node.type == "ArrowFunctionExpression" || node.type == "FunctionDeclaration" || node.type == "FunctionExpression") && node.async == true){
        in_async_function = true;
        return;
    }
    //是否达到节点顶部。测试中发现node.parentNode永远存在,达顶点后上级顶点依然是Program
    if(node.type == "Program"){
        return;
    }
    
    if(node.parentNode){
        point = point + "-";
        detect_async_function(node.parentNode)
    }else{
        //不能获得父节点,是异常的代码,跳过
        in_async_function = true;
        return;
    }
}
detect_async_function(node);
console.log(node.value,node.loc);

//没有检测出异步函数,正常处理
if(in_async_function == false){
    return this.transformNode(node, parentNode);
}

即:在处理字面量时,判断是否处于async函数体中,如是,则跳过。

用此方法修复后,运行混淆加密后的代码正常,如下图所示:

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-06-29 18:55:53  更:2022-06-29 18:59:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 12:59:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码