正则反混淆破坏字符串数组旋转器:用正则把解码调用替换成字符串字面量时,如果误伤到旋转器 IIFE 里的 parseInt(_0x...(0x...)) 校验和计算,会把字符串数组旋转逻辑打坏成同步死循环,页面直接卡死。

触发条件

  • 对 obfuscator.io 混淆的 JS 做正则式反混淆(如 re.sub(r'(_0x[0-9a-f]+)\((0x[0-9a-f]+)\)', 替换成数组值, code))
  • 替换规则是"全文件无差别替换所有 _0x[hex](0x[hex]) 调用",没有排除旋转器内部
  • 旋转器里的 parseInt('createApp') / parseInt('errorMsg') 这类非数字字符串

症状

  • 页面加载永远停在 loading,document.readyState 不前进
  • page.evaluate / 任何主线程操作阻塞不返回(这是死循环的典型特征,区别于"仅加载慢")
  • while(!![]) 旋转器永不 break,CPU 打满
  • 有时被更早触发的 domainLock 跳转掩盖(页面先跳走了,根本看不到卡死)

根因

旋转器用 parseInt(解码调用) 对数组做校验和旋转,直到算出的值等于目标数才 break:

// 正确(可终止):解码调用返回数字样字符串,parseInt 能算出值
var _0x505d1b = -parseInt(_0xbec1(0x100))/0x1 + ...;
// 被正则内联后(不可终止):parseInt('createApp') = NaN,NaN===target 永远 false
var _0x505d1b = -parseInt('createApp')/0x1 + ...;

正则反混淆把 _0xbec1(0x100) 替换成了字符串数组里的字面值(如 'createApp'、'errorMsg'、'length'),这些字符串大多不是数字样,parseInt 得 NaN,校验和永远是 NaN,while(!![]) 死循环。

排查

// 特征:旋转器里出现 parseInt('字母开头的串') 而非 parseInt(_0x...(0x...))
src.match(/parseInt\('([A-Za-z][^']*)'\)/);   // 中招
src.match(/parseInt\(_0x[0-9a-f]+\(0x[0-9a-f]+\)\)/);  // 正常

解法

  1. 不要修坏文件——重新从服务器下载 fresh 原始文件(本地被正则处理过的不可当原始版)
  2. 反混淆改用运行时解码映射或 webcrack(AST 级操作,不会误伤旋转器),见JavaScript 混淆逆向与反混淆 (JavaScript Obfuscation Reverse Engineering)
  3. 实在要用替换,务必排除旋转器 IIFE 内部的匹配,或只替换函数体里的解码调用

下次怎么识别

  • 看到 parseInt('字母') 在旋转器里 → 已中招,直接重下原始文件
  • 页面疑似卡死 → 先查 while(!![]) / while(true) 的终止条件是否被破坏

相关


本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/Web