【中等】 猿人学web第一届 第2题 js混淆 动态cookie 1

一给  金牌会员 | 2024-8-24 10:33:58 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 541|帖子 541|积分 1623

调试干扰

进入标题正常加载数据后
打开调试工具,等待一会(2~3分钟) 革新页面 cookie 失效以后会弹窗
删除 cookie 中的 m 字段再革新页面也是一样的

点击确定后,页面主动革新完会进入 无限 debugger

检察上一层堆栈
生成 debugger 的代码 是经过混淆的

手动解混淆后的代码

  1. (function () {
  2.     // function 中的代码并不会执行,debugger主要是靠 ['constructor'](('debugger'))['call']('action') 执行
  3. }['constructor'](('debugger'))['call']('action'))
  4. // function(){}['constructor'] 是 Function
  5. // 上面的代码也也可以写成
  6. Function.prototype.constructor('debugger')()
复制代码

Hook Function

   这个 debugger 是靠 Function 的构造器生成的
Hook Function.prototype.constructor 就可以过掉这个 debugger
  1. let _Function = Function.prototype.constructor;
  2. Function.prototype.constructor = function(Value){
  3.     if (Value.indexOf('debugger') !== -1){
  4.         return _Function.call(this, '')
  5.     }
  6.     return _Function.call(this, Value)
  7. };
复制代码
  将代码在控制台运行就可以正常调试了

  加密参数定位

   数据接口在 https://match.yuanrenxue.cn/api/match 里
对应的请求参数为 page(页码)

    加密参数在 cookie m字段

  hook Cookie

   删除cookie中对应的 m 字段
  

   hook cookie 找到 m字段加密的位置(加上 hook Function 的代码)
  1. // Hook Functionlet _Function = Function.prototype.constructor;
  2. Function.prototype.constructor = function(Value){
  3.     if (Value.indexOf('debugger') !== -1){
  4.         return _Function.call(this, '')
  5.     }
  6.     return _Function.call(this, Value)
  7. };
  8. // Hook Cookie(function () {    let cookie_func = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie')    Object.defineProperty(document, 'cookie', {        get() {            return cookie_func.get.call(this, val);        },        set(val) {            if (val.indexOf('m') !== -1){                debugger            }            return cookie_func.set.call(this, val);        }    })})();
复制代码

hook 到 cookie 后,向上检察堆栈就能找到生成 cookie m参数的位置

AST 解混淆

每次请求返回的代码都不一样,但执行逻辑是一样的,所以将 2.html 文件更换,方便调试

js代码是在 2.html 文件里,script代码 是被 script标签 包裹的(只必要将被标签包裹住的代码还原即可)

将代码 copy 到本地

字符串解密

先看看混淆代码
  1. document[$dbsm_0x4638('\x30\x78\x34\x38\x39', '\x28\x37\x28\x5a') + $dbsm_0x4638('\x30\x78\x34\x61', '\x29\x69\x38\x67')] = _0x5eed8e[$dbsm_0x4638('\x30\x78\x33\x61\x36', '\x7a\x6b\x34\x53') + '\x79\x62'](_0x5eed8e[$dbsm_0x4638('\x30\x78\x63\x36', '\x64\x79\x2a\x5d') + '\x79\x62'](_0x5eed8e[$dbsm_0x4638('\x30\x78\x34\x65\x33', '\x64\x75\x52\x62') + '\x79\x62'](_0x5eed8e[$dbsm_0x4638('\x30\x78\x31\x62\x33', '\x44\x21\x4c\x4b') + '\x79\x62'](_0x5eed8e[$dbsm_0x4638('\x30\x78\x34\x62\x38', '\x54\x45\x58\x6e') + '\x79\x62'](_0x5eed8e[$dbsm_0x4638('\x30\x78\x34\x32\x65', '\x29\x69\x38\x67') + '\x79\x62']('\x6d', _0x5eed8e[$dbsm_0x4638('\x30\x78\x32\x64\x38', '\x6f\x38\x4a\x47') + '\x67\x61'](_0x2fdc55)), '\x3d'), _0x5eed8e[$dbsm_0x4638('\x30\x78\x33\x38\x31', '\x39\x52\x36\x32') + '\x70\x6d'](_0x691b6d, _0x29c654)), '\x7c'), _0x29c654), _0x5eed8e[$dbsm_0x4638('\x30\x78\x37\x38', '\x72\x69\x63\x50') + '\x62\x5a']);
  2. location['\x72\x65\x6c' + $dbsm_0x4638('\x30\x78\x31\x31\x63', '\x6e\x34\x54\x28')]();
  3. // 解混淆后
  4. document['cookie'] = (((((('m' + (_0x2fdc55())) + '=') + _0x691b6d(_0x29c654)) + '|') + _0x29c654) + '; path=/');
  5. location['reload']();
复制代码
还原解密函数

   混淆的代码中有很多处字符串是 $dbsm_0x4638 函数生成的
检察 $dbsm_0x4638(解密函数)

    解密函数依靠 $dbsm_0x23b3 数组

    文件开头 $dbsm_0x23b3 是一个大数组 后经过一个自执行函数打乱排序

应在欣赏器环境中先拿到 打乱排序后的数组 $dbsm_0x23b3

在断点处断住之后,copy大数组
> 将 copy 到的数组拿到之后,更换到本地,(自执行函数就不必要了)

    解密函数中 有很多 if 分支,在欣赏器打上断点调试
这里大数组的值是对的,与欣赏器相同


第一个 if 条件是通过的 通过以后进入了一个自执行函数 F9 或单机

进入这个自执行函数

首先会进入一个 try catch 块

检察 Function 里面的代码

执行这段代码后 欣赏器返回的是 window (全局对象) / nodejs 返回的就是 global


atob在欣赏器环境中是有的 但是在node中没有,node必要补上 atob 这个函数
true || true 不会执行后面的代码

后面的代码不会执行,所以 atob 还是一个体系函数 nitive code

在node中补 atob
atob = require(‘atob’); // npm installer atob
自执行函数执行完之后,给解密方法添加了一些属性之后,这个自执行函数就结束了

    继承向下执行,检察这个 if 条件通事后的代码
打上断点后,F8 跳到这个断点或 单机


前面都是界说,在执行方法处打上断点后直接跳到这个代码段,再单步调试检察这个函数执行了什么

做了一个 格式化检测
欣赏器里的值是 true

在 node 值是 false,将 node 改写 写死为 true


上述的步骤做好后,解密函数就可以正常执行了,测试一下

  AST 配合解密函数还原字符串

   将代码拿到网站中检察对应的布局 AST explorer

必要遍历 CallExpression 范例的节点
并且 callee 属性为 Identifier 节点
Identifier 节点的 name 值为 $dbsm_0x4638
$dbsm_0x4638 是解密函数
  1. // 安装 babel 库:  npm install @babel/core
  2. const fs = require('fs')
  3. const traverse = require('@babel/traverse').default  // 用于遍历 AST 节点
  4. const types = require('@babel/types')  // 用于判断, 生成 AST 节点
  5. const parser = require('@babel/parser')  // 将js代码解析成ast节点
  6. const generator = require('@babel/generator').default  // 将ast节点转换成js代码
  7. // 读取(路径记得改)
  8. const ast_code = fs.readFileSync('demo.js', {
  9.     encoding: 'utf-8'
  10. })
  11. let ast = parser.parse(ast_code)  // 将js代码解析成ast语法树
  12. // 这里插入解析规则
  13. ///
  14. // 解密函数中需要的 atob 函数
  15. global['atob'] = require('atob');  // npm install atob
  16. // 解密函数依赖的大数组
  17. var $dbsm_0x23b3 = ["QjjDhA==", "IyQb", "552u776q5L6D", "eCvDoA==", "EHwT", "wpdVw6I=", "RArDvA==", "Hk8D", "MUvCnA==", "wotlw5k=", "w7xTwrU=", "wrLCvT0=", "w5LCvUc=", "w6hIwrY=", "w716Rw==", "L8OzwpI=", "MlMA", "Gm8r", "WcKVw44=", "W8KKw5s=", "w6bCgUE=", "TSnDpg==", "aEXCuw==", "HMOzwrc=", "wqs3Bg==", "KHsW", "AcOtwp4=", "N8KeIA==", "cifCig==", "wrBZw7M=", "AMKtw4g=", "FMOkwqA=", "WwEa", "DjzDqA==", "wo7CnAs=", "wpdoAQ==", "JsOfwp0=", "J8KRKA==", "ZsOCw58=", "wojCiAQ=", "w7vCuMKR", "ATY3", "ZyfCvQ==", "dCJD", "UMKpVg==", "O2US", "wqE3LA==", "SMOtwqk=", "w5PCh8Ki", "bMKyaA==", "S8OjEw==", "AcKGw68=", "wpVFw5M=", "fDvDpw==", "w7Brwqk=", "dGYb", "eC45", "AsOGwrE=", "w7fDhcKz", "YATDlA==", "DsK6w6A=", "wrNLw7U=", "biAN", "TxVF", "VzJ2", "wr3CrRc=", "wr0WEQ==", "YAvDrw==", "wqtZNg==", "K0QC", "Y8KBw6c=", "Q8KEw6E=", "wrUhKQ==", "CXfDjA==", "G34/", "esOcTQ==", "wpFiDA==", "w4xCaQ==", "Blo7", "w6vDvcKT", "eyFl", "BE8K", "w6HCvUs=", "wplqw6M=", "wqdOw5Y=", "wqzDr8KW", "XsKdcw==", "VMKsag==", "ecO9w58=", "EkcB", "wpJIw5U=", "JFrDiA==", "YsO7cg==", "eTvCiA==", "wojCuxc=", "WyXDmw==", "MUrDtg==", "w5XDhcKw", "fMKLcw==", "eMOhw5w=", "EGnCjA==", "RcKTYg==", "OALDvQ==", "HlE/", "Q8KGag==", "wpQpFA==", "wqg5wqw=", "ZsOqw4A=", "wp1Ewpk=", "wpkPwro=", "UT9O", "XsOmw7g=", "CFkm", "W0gI", "P8Ouwrw=", "eEMQ", "L8KSw7k=", "ecOvw4Y=", "WT9O", "J8KYfw==", "BiEH", "w7VnwpM=", "w6dxbg==", "wo/Ci8Os", "wqgpAg==", "wozCm8OB", "clHCjA==", "QsOsw6Y=", "woZew44=", "Zz7DnA==", "RgzDrg==", "XMKAVw==", "SwBb", "VMKCSg==", "Ryp1", "wr9Mw44=", "w4rDqMK7", "UMOiw6E=", "w6fDo1U=", "VMOEw4c=", "EcKew4c=", "c8KRZQ==", "WsOOUQ==", "wodyLA==", "e8KMUg==", "w5TDln0=", "GcKbw4s=", "BMK0w7Y=", "wpIewoU=", "R8Kcw6k=", "wobDuMOi", "BsO/wp4=", "VcOnw6w=", "w5t0wok=", "wqgPwpA=", "woTCu8Or", "fg3DvQ==", "L8KEw6g=", "wphswpI=", "woYgIg==", "AXgq", "VTLCqg==", "wrRww4Q=", "wqM1Ig==", "YCzDjQ==", "EVkx", "PWsV", "JWbDjw==", "DF4M", "WcObw54=", "DMKXw6w=", "EcKmOA==", "WsOJw58=", "ajsY", "SsK1w4Q=", "w4zDqMK0", "Gics", "UTkL", "w754wrA=", "IBw2", "wopkDA==", "NFEb", "EFHDig==", "W8Okw40=", "C8KpVg==", "EmnDsQ==", "VhvDmA==", "wqTCoMOV", "fcOfw6A=", "JsKkNw==", "ecOjKg==", "aSTDsA==", "woYfOg==", "YcOyYA==", "fMOtw4E=", "eMOSw5A=", "w7jCn8KA", "LGI2", "asO0Ow==", "f2cW", "egvDuA==", "GcOeGQ==", "w4NYQw==", "IMKvw68=", "wrfDpsO6", "BcKjJA==", "w6PDu2g=", "ayTDrA==", "B0kt", "QsKTVg==", "wpvCuMO1", "YsOHw6M=", "B1XCuA==", "B8Kjw5w=", "Q8Oqw6g=", "RMOAw4c=", "w4/DssK0", "w4rDm8KQ", "ScOwQg==", "YsOGw5s=", "RjbDjQ==", "SCLDpg==", "VcOVMQ==", "KnHCgQ==", "JMONwrU=", "WcO/Cw==", "YcKuRQ==", "wr0MCw==", "WAHDnw==", "esKuUg==", "wp8mNA==", "MMOAEw==", "bcOBw4w=", "w5LCl8K/", "KXk3", "agpl", "wprChSg=", "w5BmYw==", "S2zCrg==", "BXIv", "EMOUwpA=", "WcKvVg==", "WsKkw4I=", "w69iwqQ=", "e8KYVw==", "Y8Ojw6s=", "KUUk", "LcOYwq0=", "Xj/DvQ==", "RiXDkg==", "wrbDiMOj", "Ujd6", "cAc+", "dzt2", "QsO9w6w=", "Ghg3", "ccKkcA==", "fRvDkA==", "KcK4Og==", "H30u", "PMKyw4Y=", "YyrDtw==", "wpDCiMOh", "wqwowoc=", "wojCjDQ=", "wqHCj8OU", "w7HCm8KR", "XsOVw7Q=", "w47Cp8Kj", "w6LCnMKo", "GsKMbw==", "w5J0wrU=", "RCnDuA==", "wpfCgjE=", "wrMnBw==", "w7bDqsK/", "KEM4", "a8OKwrw=", "wpBlw5Q=", "MTAo", "X8K2w5I=", "WsOvFQ==", "Yz7DkQ==", "W8Ocw54=", "ahtQ", "D2vDrg==", "VsKcw4o=", "Fy/CkQ==", "JnAI", "MMOswrA=", "w4zDt8KI", "wrDCksOj", "GBcc", "fcO9Sg==", "w4HDgXY=", "MsKeHA==", "ccOBw4o=", "QsOgw4M=", "Q8OjBg==", "EMK5FQ==", "R8OCw6o=", "XS9D", "d8KfcA==", "wpbCmSE=", "w4XChn8=", "aMKieA==", "woVhGQ==", "wo7CnsOK", "AXwd", "dCAI", "worDhsOC", "V8Krw4A=", "VxHCvA==", "woFywrg=", "w4ZRaA==", "VMO5w6Q=", "wp1zHg==", "wqw/wqo=", "BMKRw58=", "wpxjw7U=", "McKEw4o=", "YyIF", "fkME", "wp1xw6o=", "Sg80", "HMKbAQ==", "HHoX", "MsK7Cg==", "woZWCw==", "GsOKwrE=", "P8KPGg==", "bBDDhw==", "ewLDng==", "TSMk", "wrbCrT4=", "w7tkRg==", "DDQv", "wrdpLw==", "wonDmsKK", "Tx8o", "WMODw7I=", "MXgT", "w6PCrUw=", "wobCg8OR", "Z8Odw6U=", "w55LwrA=", "O8ORwqU=", "w5vDo10=", "wq3Cl8OT", "asKMUQ==", "woBpPg==", "SnPCrA==", "wo7Dn8KG", "wqVtw54=", "wo9WNA==", "QMObNw==", "TMKAw4Y=", "eHEn", "w5rDqcKk", "wqRlw68=", "CxYO", "WcK2VA==", "wpgrAw==", "wpHCgw4=", "wrHCklU=", "BkIZ", "woh4wqM=", "wpBICg==", "AcORGg==", "wpd0NQ==", "w4HDqsKa", "YcKvew==", "wpvCusOs", "K8K5JA==", "w7LCrGU=", "XkUT", "XMOow6s=", "w7/DqcKj", "NsOdwqQ=", "VcOsw7Q=", "eXED", "McKbdA==", "AHXCow==", "K8KeQg==", "ZgMB", "Hm4g", "f8Oqwow=", "AHPDpA==", "wq4Mwq0=", "WsKeYg==", "fDjCog==", "wpY/PQ==", "V8K9cg==", "OlAN", "esO8Xw==", "GsKaJA==", "WgjDnQ==", "DW7CrA==", "f8K1Qg==", "eSw0", "RAIx", "Cls9", "FMOYwqM=", "w4bCvVE=", "wovDkMKK", "WsK/Tw==", "QRrDgw==", "wpV9w4o=", "wrXCmxA=", "wpXChik=", "wq5kw7g=", "wo5jPA==", "w5VgZQ==", "wr1Cw4o=", "wpBYw60=", "woVOwpw=", "wpB2Cg==", "cBlA", "wo52Cg==", "QcO/w58=", "w65UwrM=", "fyfCng==", "w6TCp2s=", "wrRWJQ==", "w7bCv8KW", "XsKyeQ==", "MWbDiQ==", "w4jDscK1", "d8K1w4U=", "C34+", "wprDt8O9", "VsKlw7E=", "w4JdfQ==", "wos1Jg==", "PE7DuA==", "w4bDnsKM", "w5XDq8KA", "JTIy", "w5LDpMKu", "YArDsQ==", "K8K9IQ==", "DsKmw7E=", "BMKxw7A=", "wrvDncKg", "dzrChQ==", "G1nCjg==", "YEYA", "OsKzJg==", "wrfCugs=", "XlvCkA==", "fcKDw54=", "e8OMw40=", "wpBDw68=", "w45CwoY=", "WsONwpw=", "BFDCiQ==", "w7VidA==", "Aloq", "w73Cq8KT", "IkE4", "wqN0Nw==", "dBLDmw==", "wqlRw44=", "w7lleQ==", "C1TCgQ==", "PsKPJQ==", "VcK0bg==", "XcOBwo4=", "VMOjZQ==", "w7pjXg==", "wrBvFw==", "cARj", "w4JSaQ==", "MsK4w4Y=", "acOeeQ==", "AsOQIQ==", "wqUDBQ==", "X1Zb", "RMKKaA==", "w6fDs8KB", "HsKzdw==", "V8OJLA==", "XMOFwqo=", "V8Kybw==", "w5zDhG4=", "wrFHNQ==", "RcOhw6s=", "w6Vhbg==", "XcOow48=", "w5bCi24=", "NkfDgw==", "AcOyHA==", "XUzClw==", "w5XCgGY=", "w5rDhVA=", "a1c3", "WnzCsw==", "wrvDncK4", "w7pUwqk=", "QT1j", "DmLCuA==", "w69tVA==", "w6bCvMK+", "cVUo", "dcO8wqc=", "cBlK", "w5zDhWc=", "wpt+w6w=", "w6lFwrI=", "wojDiMOS", "XcOZw78=", "UwhO", "wotmw4M=", "RC4Y", "w77CjU0=", "S8O3w6U=", "PGAG", "WsKowq8=", "wqTDmsOo", "Hlo8", "I8OuwqQ=", "c8OAKA==", "cl7Cmw==", "V3PCvA==", "DnM2", "wqQTGQ==", "WWYV", "wozDosOV", "w7fDisKb", "csO+w4A=", "IsKiPw==", "w75iQA==", "Ww7CgA==", "wqtrLA==", "fsKtw6c=", "DsKbw5M=", "w5fDgMKO", "wrcaIQ==", "S1c5", "wrMaOQ==", "AcKIcA==", "Cjww", "w6VWYA==", "OQom", "ZxjDjQ==", "wrMoNw==", "VQXDmA==", "d8KeYQ==", "BEs8", "J0k9", "wpEeEQ==", "wqAHFQ==", "w6/DicKx", "ScOiCg==", "YxXCtg==", "dsOiw4k=", "THjCqQ==", "HMK+AA==", "wpQhHw==", "wr7CvcOq", "K0bDiw==", "eMOAcg==", "w60rdg==", "L1IC", "woNlw60=", "K8KDw4k=", "wrpFDg==", "wpFEMw==", "w6fCrGw=", "wo0mCA==", "cUTCtQ==", "w7LCqMKX", "W8OiwoQ=", "QAvDqQ==", "AD03", "aDfDiQ==", "UTHDpQ==", "ZhMa", "w6bDrMKs", "AkvCuw==", "wo8yBQ==", "wo4IPQ==", "M3QK", "TwrDnw==", "wqFcDw==", "e8O7bA==", "PkHDlg==", "esOBwqk=", "eRFw", "ZyvCnw==", "w7PDtcKx", "wpQ1woA=", "WwFc", "XRsF", "BMOCPQ==", "SHHCjA==", "XcOew5w=", "wqhaKA==", "YynCvg==", "XS3Chg==", "BFI0", "wr9HDA==", "wpx7w5o=", "w6DDmHU=", "bA84", "I3AA", "w7jCn2s=", "BWPClw==", "wpbDt8O1", "wpsKYw==", "wq9jw5I=", "woFQwp4=", "wpI9Mw==", "B8KwEQ==", "DmYq", "CcKbAQ==", "TS49", "w6bDvWU=", "YsOVNw==", "dMKBRQ==", "NXg8", "wrBJwoI=", "KsKAYQ==", "EcKNdQ==", "ecO7OA==", "wrV6w7I=", "WMOSw6Y=", "wqV6wqI=", "VcKyUA==", "fcO4Sg==", "IXQl", "Z8KaXw==", "VnvCnQ==", "wr9qOg==", "w6PDiGs=", "QD0a", "wrzCm8OQ", "w6LCp1w=", "bMK+w6A=", "w7PDn24=", "T2LClg==", "woBJw7c=", "SiPDjQ==", "wqbChTI=", "Wj3Dpg==", "fxgU", "YhzCuA==", "ETsw", "W8OdCA==", "GcOxIg==", "Kxkw", "B2zCuA==", "OBER", "Cl4R", "wrLDpMK8", "wq/CnsOZ", "w5XDv8Kw", "dysc", "Y8KjVQ==", "fcOvw40=", "CWjDug==", "bMObNg==", "ScOEw4c=", "w6RTwqM=", "wpJLEw==", "BTw5", "ScKDw4c=", "XMKbw5o=", "TxjDhw==", "w5pOew==", "wpJawp0=", "ZsKwQQ==", "FGMO", "GMKRw7o=", "QMO+OA==", "wrtaMQ==", "TMOUMA==", "J3jDuA==", "D8OnwqA=", "w7zCgcKv", "VnLCmw==", "Z8OJw4I=", "bADDng==", "ccKCZg==", "wrIUJA==", "XCHDow==", "w6DCsV8=", "ZsKafw==", "w5J7fg==", "M8OMwps=", "w7DDt8KG", "W8OYXw==", "EHDDhw==", "w63ChsKU", "O8Kiw4k=", "wrlxDA==", "wrnCkcON", "wqFfHg==", "wovDsMKh", "w67CmMKk", "w75Pwq8=", "wq/DnMKX", "SyhS", "wp1uOA==", "wr3Dt8KG", "DnI2", "OWEf", "w5PDisKX", "wr3CuRE=", "YBJu", "wrxgw58=", "wrEEIQ==", "Uy53", "V2/CjQ==", "ecOjw6Q=", "SMKjw5s=", "X8O5w7Y=", "RsK3w50=", "wpA+wro=", "aynDjQ==", "ccO5w6E=", "ezjCjw==", "BMOPJQ==", "w7FFwq8=", "QsOnw6Y=", "w5VRQQ==", "HmkA", "f8Oewr0=", "dsO7w78=", "w7PDrcKT", "w4vCr3E=", "X8O6w7s=", "CRTDqQ==", "VcO8w54=", "KmjDrA==", "w4dSfQ==", "BG7DpQ==", "bMOvw54=", "bi5F", "VDjDpQ==", "w6HCiFo=", "aMOYCA==", "w5fDqE8=", "CXbCpg==", "FMKwIg==", "w4BxSQ==", "QTbDow==", "J2si", "MsOxwpI=", "IsOdHA==", "wojDlsKP", "Hn44", "bMOQRg==", "dMKCWg==", "w7rDnF4=", "B8K5w58=", "WSjDpg==", "XsO5w5g=", "QTo7", "wqUZwoM=", "ecK1aA==", "esKDUA==", "woFCwrE=", "woISwos=", "dsODEw==", "McOrOQ==", "JVTDmA==", "XcKxbw==", "wqZZBg==", "OsKjFg==", "UQTDkg==", "woh3w4A=", "w5FXwpM=", "wpJAw7w=", "Ongr", "w41zwos=", "N8OGDw==", "w6DDicKj", "UQ0U", "CsKCTw==", "fTnDhA==", "w6TDqHA=", "AloY", "CV4e", "DsKJbQ==", "LyoG", "OFnChA==", "NFsh", "w596fA==", "w6FsYA==", "Pm/Chg==", "wrZ1Ew==", "wprDmcKo", "C3QW", "wo7CqDM=", "woYANg==", "wq3Dl8Ok", "wp7DlcKp", "csKXeA==", "wqVyHA==", "wptxw6k=", "IMOIwpE=", "HcKkw78=", "XzXDsg==", "Q8KAw48=", "QMOOWg==", "V3TClA==", "woY5Pw==", "K2jCng==", "c8OewoY=", "w5zDqVY=", "Al/Cmg==", "w7TDp8Kg", "wpjCoiU=", "G8ONAA==", "w7rCjMKO", "RSjDsg==", "esODbg==", "EWcq", "NsK4BA==", "PcKeEQ==", "GcOpJw==", "cTpO", "wrzDl8Kv", "CcKSw7I=", "fhPDpw==", "wqcfLg==", "B8KiIQ==", "OcKQw78=", "SjHDug==", "w4vDvcKd", "wq8kGQ==", "HH8J", "DVbDsg==", "LXHDrA==", "WCpe", "N8OjGQ==", "MVrDjA==", "ZB/Dpg==", "w7xvwpE=", "WwjDvA==", "wo4cIQ==", "esOvEw==", "wpJRw7Y=", "TRNg", "wrZ0Ag==", "dcOLcQ==", "bsKAw6E=", "wqdoPg==", "XDrCgg==", "wosKPw==", "bwTDvw==", "XQAy", "wpAUwoU=", "dB4t", "wpFRNw==", "UMKwQQ==", "ecOlw48=", "w6TChMKP", "XxFP", "A8K5Pg==", "w5dbfg==", "woDCtcOn", "IE3Cqg==", "JUvCqg==", "HzYw", "ecKEaA==", "fQEi", "fQR3", "J8KsEQ==", "b8Ofw6U=", "MsK6Jg==", "w7bDsMKT", "wqxuwps=", "XxPCrg==", "JcKQbg==", "FsOtAw==", "RcOBw6U=", "YcOxUg==", "EnAz", "ci8a", "VcO9w6E=", "Qj7Dvg==", "YMKEeQ==", "wqLDiMKl", "w5xawoM=", "TMOow6k=", "eRjDpQ==", "DXjCgQ==", "wq87HA==", "w5jCrMKw", "YsKzVw==", "fcOrwq8=", "wpNxw40=", "BgIo", "YcOEw6Q=", "BsKkw7M=", "L1XDiQ==", "DMKeaQ==", "cT3DmA==", "WDtL", "HVQy", "YTzDow==", "TsOZw5A=", "wpLCnSI=", "Ri8m", "w4fDiU0=", "ah5R", "w4TCuEs=", "w6bDusKY", "dgDDow==", "RAx3", "w71XVg==", "X8Obwoo=", "wrfDi8Kd", "ZsO+w5o=", "cB9B", "BH4p", "USBR", "w4bDksKn", "dSXDmQ==", "YMKew4A=", "V8O9BQ==", "wooxGQ==", "VX/Csg==", "XsOEw6Y=", "wrofBg==", "wpUBBw==", "wq87Gg==", "w4HCo0E=", "wpnCrAw=", "asOGwok=", "wqTChyA=", "wr91KA==", "FsKSLg==", "w5LDrMK5", "UxTDqw==", "JCMb", "IlfDmg==", "a8ONYA==", "IMO/wqM=", "OsOMwoI=", "YnM7", "YcOhcA==", "ZgDDhw==", "fcOnwq8=", "QAJu", "METDqw==", "HMKYRQ==", "IsKBw4g=", "wq9Cw5Y=", "WsOZFw==", "wrZkw60=", "aTAu", "bzgc", "RcOPBw==", "wqhlMQ==", "eMOrw48=", "O8Kjw68=", "STbDjA==", "wqvDgsOf", "G8K0bw==", "DsKdfQ==", "w4HCgWY=", "bgHDvw==", "CXPDlg==", "woFJFQ==", "wqDDlcKF", "QADDtg==", "w7tkSQ==", "Vgo3", "BEUK", "wrN2DA==", "wrHDlcKk", "XMOiEQ==", "wq/CnCU=", "QcKUUw==", "ODRV", "wpJuwpc=", "w67DkXY=", "NMOwwr0=", "VD8w", "KG4V", "acOAwqg=", "LMKWKg==", "wrLDmsK7", "a8K3bw==", "w6nDlMKA", "Y8OJw4s=", "w7xjSQ==", "AMKOdg==", "ay9S", "woFUPg==", "DcKVbA==", "Q8ODw4Y=", "w6JkTw==", "wrx5Hg==", "wr/DhsKl", "wo9QMQ==", "bSXDrg==", "eMOrWA==", "GMKpw78=", "w6fDuns=", "wqnDuMKI", "I1rDug==", "IHsb", "wqJMHw==", "OMOdwoM=", "HW4u", "w6JFQQ==", "wrJHEg==", "wpZcw7U=", "wq1tGw==", "wol2wog=", "w6nCu0s=", "wpLDl8KP", "woPCusOl", "wr7CtMOG", "wofDgsO2", "wprCuys=", "cD7Dhg==", "BWMM", "GMKYPA==", "WMOOw44=", "w4VFXA==", "w7DDmk0=", "F8KDOg==", "wo8jCQ==", "bcKEw44=", "aCkH", "cV0v", "aMO9Dg==", "cMOjw5E=", "CiM0", "Sy0W", "dTPCug==", "FsOuwp4=", "BkAs", "ZnkQ", "w7oxw4I=", "WMOPw4w=", "wqvCvyI=", "SRbDow==", "YinCjQ==", "cz4p", "w6PCqsKV", "VgVq", "BCE2", "w5LDrV4=", "TcO2Jw==", "eyRA", "a8Ouw7o=", "J1jDog==", "QcO5w40=", "FkvDjA==", "GMKpLg==", "ZwTDsg==", "wqzCsMOJ", "YS7ClA==", "w4bCuk0=", "ZMOOIA==", "wo4fwpQ=", "S8K6Vg==", "QcObw6U=", "wq9DHQ==", "IXgZ", "FFwc", "wqhvOA==", "wqBnwrw=", "QsOfJg==", "NW8A", "RRPDow==", "VAIr", "D8Kaw4s=", "X8OcGQ==", "JGEU", "eMKTbg==", "Y8OYbA==", "XcKaRQ==", "FMOrAQ==", "fwjCoA==", "wqnDhMK7", "wqkVwq8=", "P8KUfQ==", "Yh7DpA==", "BAsm", "RMK2w50=", "PcOwKg==", "CcKbw6w=", "HsKWTw==", "eyrDmA==", "woDDi8KC", "A2fDjw==", "YRTDlg==", "UsOow64=", "LCsE", "wo4dOg==", "wphxwpE=", "woUcAA==", "wqMfAA==", "TMKAw4U=", "GsKDw7k=", "PTE8", "wrlPGA==", "wqPDn8OT", "ZcOBw60=", "wrjCuMOq", "W8Kmw5k=", "XMOaw7k=", "wqxzwpM=", "fhDCqg==", "QMO+w7E=", "DVgs", "w6lSwrg=", "VMOHw6g=", "P8Oowrg=", "w7zDqHk=", "wq4CAw==", "wqpTDw==", "bDpH", "QcOYw4M=", "SBkv", "worCicOp", "wo0hGQ==", "w5JgWA==", "YQ5g", "AsK+Xg==", "XMOEwoo=", "ZiAN", "IsKsBQ==", "w6PDpVw=", "wrrCjSY=", "TcK+w6M=", "wp/DkMKL", "fhwQ", "ZHcF", "VDXDqw==", "w7rDg8Kg", "w5pywpc=", "UH3Cqg==", "AMOJwpI=", "wpxwwrU=", "SsONwo0=", "Az8p", "U2fCnA==", "wrLDlcKB", "XSlH", "QcOhKA==", "LG7CnQ==", "w6LDlsKm", "w5hkYQ==", "wqvDi8OU", "wo7CqDE=", "fAvCgQ==", "G8Kzw7A=", "YVAg", "wo/CnSY=", "Dk7CgQ==", "RzzCmw==", "P8OdAA==", "wqFcDQ==", "K8KVSA==", "woVawp8=", "JnEi", "w67DmsKc", "w6JRTw==", "DMK9cA==", "aBhR", "Zi4W", "dhzDvw==", "RsO7wq4=", "ecOcw6E=", "JcOmwqY=", "EcKwVg==", "WsKXeg==", "Byo1", "ElYq", "BloJ", "XMO4Ew==", "wo5+w7g=", "Mkk8", "wqAhJw==", "bjjDuw==", "w7bCpsKR", "Z8O7aw==", "d3fCvw==", "wpbDpcOF", "ScK7w7I=", "CkfDjg==", "ecOafA==", "YMOBw4A=", "wo0dwq4=", "dsKWTQ==", "DcKQZA==", "IEvCpw==", "w7fDulQ=", "aXnCkg==", "woMpJg==", "fWQq", "NnPDkQ==", "USBV", "U2gZ", "RsKBZw==", "e8K/cg==", "WMK5w4s=", "wrFww5I=", "w5PDhHk=", "ZsOxwos=", "wp3DisKX", "w7DCmVg=", "w6x4Rg==", "LH4K", "O20W", "ZMOZw7U=", "PMKfaA==", "bRhn", "Izwv", "w4cfwqU=", "w4fCpG0=", "aBvDoA==", "RMKveA==", "QcOxSg==", "V8K7cw==", "J8KeQg==", "w4LDiX0=", "IsKSUQ==", "VQXDkw==", "LXMp", "IsKgw6w=", "TCU4", "ayl1", "w6TDksK+", "Zn0Q", "AHbDug==", "w7JSwpg=", "G8OpwoM=", "fS1h", "wrxxw4s=", "wogKAw==", "wpYvwqA=", "eWXCkw==", "U8Ofw70=", "e2sT", "woUBAw==", "w6LDjmw=", "a8OPw54=", "U8KHbw==", "HTA7", "wonDs8Kk", "BFQG", "w5PDolU=", "ciXDkA==", "NcOSwrg=", "fCTDow==", "woYuwpQ=", "alQl", "S8Kbw5U=", "woRaw7M=", "E34q", "O8KdJg==", "WAHDng==", "w6DCmnA=", "OkYH", "Y8KWRQ==", "w5VNwpk=", "I0HDpg==", "wrQSJA==", "aQ9P", "HcKBw6g=", "eQnDsA==", "wpAcOw==", "w5HDmsKC", "w5tWwrs=", "ecOcIQ==", "JcKvMA==", "bRh5", "cB0F", "VjTDgA==", "wptrw7s=", "WDnDrw==", "Rz09", "wpYdAA==", "wrpUwpM=", "DcKifg==", "wp/DusKm", "wqAoOg==", "a17Cmw==", "J2k1"];
  18. // 解密函数
  19. var $dbsm_0x4638 = function (_0x1e1b14, _0x23b316) {
  20.     _0x1e1b14 = _0x1e1b14 - 0x0;
  21.     var _0x4638d3 = $dbsm_0x23b3[_0x1e1b14];
  22.     if ($dbsm_0x4638['lIzlCZ'] === undefined) {
  23.         (function () {
  24.             var _0x4b121c;
  25.             try {
  26.                 var _0x1d5b59 = Function('return\x20(function()\x20' + '{}.constructor(\x22return\x20this\x22)(\x20)' + ');');
  27.                 _0x4b121c = _0x1d5b59();
  28.             } catch (_0x4f5869) {
  29.                 _0x4b121c = window;
  30.             }
  31.             var _0x55f54d = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
  32.             _0x4b121c['atob'] || (_0x4b121c['atob'] = function (_0x2337bc) {
  33.                     var _0x94736f = String(_0x2337bc)['replace'](/=+$/, '');
  34.                     var _0x5e548f = '';
  35.                     for (var _0x588d26 = 0x0, _0x5d3f20, _0x558d8e, _0x49832a = 0x0; _0x558d8e = _0x94736f['charAt'](_0x49832a++); ~_0x558d8e && (_0x5d3f20 = _0x588d26 % 0x4 ? _0x5d3f20 * 0x40 + _0x558d8e : _0x558d8e,
  36.                     _0x588d26++ % 0x4) ? _0x5e548f += String['fromCharCode'](0xff & _0x5d3f20 >> (-0x2 * _0x588d26 & 0x6)) : 0x0) {
  37.                         _0x558d8e = _0x55f54d['indexOf'](_0x558d8e);
  38.                     }
  39.                     return _0x5e548f;
  40.                 }
  41.             );
  42.         }());
  43.         var _0x2ef3c5 = function (_0x49a1eb, _0x27f9fb) {
  44.             var _0x26a837 = [], _0x90ed46 = 0x0, _0x1e184c, _0x229955 = '', _0x28a13b = '';
  45.             _0x49a1eb = atob(_0x49a1eb);
  46.             for (var _0x4237c8 = 0x0, _0x18c69a = _0x49a1eb['length']; _0x4237c8 < _0x18c69a; _0x4237c8++) {
  47.                 _0x28a13b += '%' + ('00' + _0x49a1eb['charCodeAt'](_0x4237c8)['toString'](0x10))['slice'](-0x2);
  48.             }
  49.             _0x49a1eb = decodeURIComponent(_0x28a13b);
  50.             var _0x2c4f5b;
  51.             for (_0x2c4f5b = 0x0; _0x2c4f5b < 0x100; _0x2c4f5b++) {
  52.                 _0x26a837[_0x2c4f5b] = _0x2c4f5b;
  53.             }
  54.             for (_0x2c4f5b = 0x0; _0x2c4f5b < 0x100; _0x2c4f5b++) {
  55.                 _0x90ed46 = (_0x90ed46 + _0x26a837[_0x2c4f5b] + _0x27f9fb['charCodeAt'](_0x2c4f5b % _0x27f9fb['length'])) % 0x100;
  56.                 _0x1e184c = _0x26a837[_0x2c4f5b];
  57.                 _0x26a837[_0x2c4f5b] = _0x26a837[_0x90ed46];
  58.                 _0x26a837[_0x90ed46] = _0x1e184c;
  59.             }
  60.             _0x2c4f5b = 0x0;
  61.             _0x90ed46 = 0x0;
  62.             for (var _0x4fe42c = 0x0; _0x4fe42c < _0x49a1eb['length']; _0x4fe42c++) {
  63.                 _0x2c4f5b = (_0x2c4f5b + 0x1) % 0x100;
  64.                 _0x90ed46 = (_0x90ed46 + _0x26a837[_0x2c4f5b]) % 0x100;
  65.                 _0x1e184c = _0x26a837[_0x2c4f5b];
  66.                 _0x26a837[_0x2c4f5b] = _0x26a837[_0x90ed46];
  67.                 _0x26a837[_0x90ed46] = _0x1e184c;
  68.                 _0x229955 += String['fromCharCode'](_0x49a1eb['charCodeAt'](_0x4fe42c) ^ _0x26a837[(_0x26a837[_0x2c4f5b] + _0x26a837[_0x90ed46]) % 0x100]);
  69.             }
  70.             return _0x229955;
  71.         };
  72.         $dbsm_0x4638['UYyCMO'] = _0x2ef3c5;
  73.         $dbsm_0x4638['nMtFyB'] = {};
  74.         $dbsm_0x4638['lIzlCZ'] = !![];
  75.     }
  76.     var _0x57b28f = $dbsm_0x4638['nMtFyB'][_0x1e1b14];
  77.     if (_0x57b28f === undefined) {
  78.         if ($dbsm_0x4638['DwWKuR'] === undefined) {
  79.             var _0x9e4186 = function (_0x3712d5) {
  80.                 this['kHsRXo'] = _0x3712d5;
  81.                 this['nWOEyU'] = [0x1, 0x0, 0x0];
  82.                 this['tpblbK'] = function () {
  83.                     return 'newState';
  84.                 }
  85.                 ;
  86.                 this['lAcsth'] = '\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*';
  87.                 this['foeeRg'] = '[\x27|\x22].+[\x27|\x22];?\x20*}';
  88.             };
  89.             _0x9e4186['prototype']['RuyyZP'] = function () {
  90.                 var _0x20d28 = new RegExp(this['lAcsth'] + this['foeeRg']);
  91.                 var _0x5e0e5f = true ? --this['nWOEyU'][0x1] : --this['nWOEyU'][0x0];
  92.                 return this['XVTLWU'](_0x5e0e5f);
  93.             };
  94.             _0x9e4186['prototype']['XVTLWU'] = function (_0x3ab8dc) {
  95.                 if (!Boolean(~_0x3ab8dc)) {
  96.                     return _0x3ab8dc;
  97.                 }
  98.                 return this['HxFvMA'](this['kHsRXo']);
  99.             }
  100.             ;
  101.             _0x9e4186['prototype']['HxFvMA'] = function (_0x13037d) {
  102.                 for (var _0x3bdd37 = 0x0, _0x49b603 = this['nWOEyU']['length']; _0x3bdd37 < _0x49b603; _0x3bdd37++) {
  103.                     this['nWOEyU']['push'](Math['round'](Math['random']()));
  104.                     _0x49b603 = this['nWOEyU']['length'];
  105.                 }
  106.                 return _0x13037d(this['nWOEyU'][0x0]);
  107.             }
  108.             ;
  109.             new _0x9e4186($dbsm_0x4638)['RuyyZP']();
  110.             $dbsm_0x4638['DwWKuR'] = !![];
  111.         }
  112.         _0x4638d3 = $dbsm_0x4638['UYyCMO'](_0x4638d3, _0x23b316);
  113.         $dbsm_0x4638['nMtFyB'][_0x1e1b14] = _0x4638d3;
  114.     } else {
  115.         _0x4638d3 = _0x57b28f;
  116.     }
  117.     return _0x4638d3;
  118. };
  119. // 解密函数还原字符串规则
  120. traverse(ast, {
  121.     CallExpression(path) {  // 遍历 CallExpression 节点
  122.         // callee 属性为 Identifier 类型
  123.         // 且 name 属性为 $dbsm_0x4638 解密函数名
  124.         if (types.isIdentifier(path.node.callee, {name: '$dbsm_0x4638'})) {
  125.             console.log('遍历到的节点: ', path + '')
  126.             // 取出对应的参数
  127.             // 例: $dbsm_0x4638('\x30\x78\x32\x39', '\x72\x69\x63\x50')
  128.             let callArg = path.node.arguments;  // 例 ['\x30\x78\x32\x39', '\x72\x69\x63\x50']
  129.             let arg1 = callArg[0].type;  // 例 '\x30\x78\x32\x39'
  130.             let arg2 = callArg[1].type;  // 例 '\x72\x69\x63\x50'
  131.             // 将对应的参数取出后, 拿到 $dbsm_0x4638 解密函数执行
  132.             let result = $dbsm_0x4638(callArg[0].value, callArg[1].value)
  133.             // 将对应的节点替换成 解密函数执行后的结果
  134.             // 例
  135.             //    将节点:  $dbsm_0x4638('\x30\x78\x33\x66\x36', '\x68\x32\x25\x5e')
  136.             //    替换成:  "hei"
  137.             path.replaceWith(types.valueToNode(result));
  138.             console.log('替换后的节点: ', path + '')
  139.             console.log('==============================');
  140.         }
  141.     }
  142. })
  143. ///
  144. js_code = generator(ast).code  // 将ast节点转换成js代码
  145. // 写入(路径记得改)
  146. fs.writeFileSync('New_demo.js', js_code, {
  147.     encoding: 'utf-8'
  148. })
复制代码
  剖析前的代码

剖析后的代码

  ASCII 编码字符串还原

   还原思路在 1. js混淆-源码乱码 中有提到
  1. // ASCII 码还原
  2. traverse(ast, {
  3.     StringLiteral(path) {
  4.         if (path.node.extra) {
  5.             console.log('ASCII码替换前: ', path.node.extra);
  6.             path.node.extra.raw = `'${path.node.extra.rawValue}'`
  7.             console.log('ASCII码替换后: ', path.node.extra);
  8.             console.log('============================================================');
  9.         }
  10.     }
  11. })
复制代码
  效果

  字符串相加

   demo.js
  1. 'a' + 'b' + 'c' + 'd';
  2. 'e' + 'f';
复制代码
  AST.js
  1. // 字符串相加
  2. function strConcat(path) {
  3.     for (let i = 0; i <= 2; i++) {
  4.         let node = path.node
  5.         // left 节点为 StringLiteral 类型
  6.         // right 节点为 StringLiteral 类型
  7.         // operator 操作符属性为字符串 +
  8.         if (types.isStringLiteral(node.left) && types.isStringLiteral(node.right) && node.operator === '+') {
  9.             // 例 'e' + 'f'
  10.             console.log('字符串相加前: ', path + '');
  11.             // 例 'e' + 'f'
  12.             let result = path.node.left.value + path.node.right.value;
  13.             // 例: 'e' + 'f'
  14.             // 替换成: 'ef'
  15.             path.replaceWith(types.valueToNode(result));
  16.             console.log('字符串相加后:  ', path + '');
  17.             console.log('============================================================');
  18.         } else {
  19.             // 递归是针对多个字符串相加的
  20.             // 例当前遍历到的节点: 'a' + 'b' + 'c' + 'd'
  21.             // 这个节点在上面是不会处理的
  22.             // path 对象的 traverse 方法是从当前节点继续遍历
  23.             // 传入 strConcat 方法的节点就为:  'a' + 'b' + 'c' + 'd'
  24.             // 调用过后还是会再次进入到 path.traverse 因为还是会有多个字符串相加
  25.             // 上一次传入的节点被处理过了
  26.             // 所以这一次传入的节点代码就为 'ab' + 'c' + 'd'
  27.             // 一直递归到节点为 'abc' + 'd' 就会停止递归
  28.             // 'abc' + 'd' 在 for 循环中会二次处理 (可以试着for循环只遍历一次看看效果
  29.             path.traverse({
  30.                 BinaryExpression(path_) {
  31.                     strConcat(path_)
  32.                 }
  33.             })
  34.         }
  35.     }
  36. }
  37. traverse(ast, {
  38.     BinaryExpression(path) {  // 遍历 BinaryExpression 节点
  39.         strConcat(path)
  40.     }
  41. })
复制代码
  效果

  花指令(对象)

   demo.js
  1. let obj = {};
  2. obj['StringLiteral'] = 'abc';
  3. obj['BinaryExpression'] = 'abc' + 'def';
  4. obj['funcCallExpression1'] = function (a, b){
  5.     return a(b);
  6. }
  7. obj['funcCallExpression2'] = function (a){
  8.     return a();
  9. }
  10. obj['funcBinaryExpression'] = function(a, b){
  11.     return a + b
  12. }
  13. let c = obj;
  14. let d = c['StringLiteral'];
  15. let e = c['BinaryExpression'];
  16. function demo(){}
  17. let f = c['funcCallExpression1'](demo, '123');
  18. let g = c['funcCallExpression2'](demo);
  19. let h = c['funcBinaryExpression']('1', '2');
复制代码
  AST.js
  1. // 花指令
  2. traverse(ast, {
  3.     VariableDeclarator(path){  // 遍历 VariableDeclarator 节点
  4.         if (types.isObjectExpression(path.node.init)){  // init 类型为 ObjectExpression 类型
  5.             let objName = path.node.id.name;  // 获取对应的标识符
  6.             let objBinding = path.scope.getBinding(objName);  // 获取标识符对应的引用
  7.             let objRefer = objBinding.referencePaths;  // 获取标识符引用对应的数组
  8.             let newObj = {}
  9.             // 将给对象属性赋值的所有变量存入 newObj
  10.             for (const refer in objRefer){  // refer 为索引值从 0 开始
  11.                 // objRefer[refer] 为 obj
  12.                 // objRefer[refer].parentPath 为 obj['str']
  13.                 // objRefer[refer].parentPath.parentPath 为 obj['str'] = 'abc'
  14.                 let grandPath = objRefer[refer].parentPath.parentPath;  // 获取该节点的整段代码
  15.                 // 该节点的类型为 AssignmentExpression 类型
  16.                 // 节点中 left 属性的类型为 MemberExpression 类型
  17.                 if (grandPath.isAssignmentExpression() && grandPath.get('left').isMemberExpression()){
  18.                     // obj['str'] 中的 str 字符串
  19.                     let key = grandPath.node.left.property.value;  // 获取 .property.value 的属性,作为新声明对象中的key
  20.                     newObj[key] = grandPath.node.right;  // right为该属性对应的 node 节点,直接存入 newObj 对象即可
  21.                 }
  22.             }
  23.             for (const refer in objRefer.reverse()){
  24.                 let grandPath = objRefer[refer].parentPath;
  25.                 if (grandPath.isVariableDeclarator()){  // 该节点的类型应为 VariableDeclarator
  26.                     // 例: c = obj
  27.                     let identName = grandPath.node.id.name;  // 获取标识符中对应的 name 属性 (例中的 c)
  28.                     // 例:
  29.                     // let d = c['StringLiteral'];
  30.                     // let e = c['BinaryExpression'];
  31.                     // let f = c['funcCallExpression1'](demo, '123');
  32.                     // let g = c['funcCallExpression2'](demo);
  33.                     // let h = c['funcBinaryExpression']('1' + '2');
  34.                     let identBinding = grandPath.scope.getBinding(identName);  // 获取标识符 c 对应的引用
  35.                     // 例:
  36.                     // [c, c, c, c, c]
  37.                     let identRefer = identBinding.referencePaths;  // 获取标识符引用对应的数组
  38.                     // 字符串花指令
  39.                     for (const idenKey in identRefer) {
  40.                         // identRefer[idenKey].parentPath
  41.                         // c['StringLiteral']
  42.                         // c['BinaryExpression']
  43.                         // c['funcCallExpression1']
  44.                         // c['funcCallExpression2']
  45.                         // c['funcBinaryExpression']
  46.                         let key = identRefer[idenKey].parentPath.node.property.value;  // 获取对应的属性值
  47.                         // 获取 newObj[key]  // obj[属性值]
  48.                         // newObj[key] 的属性值为 StringLiteral 或 BinaryExpression 节点
  49.                         // StringLiteral 为字符串 'abc';
  50.                         // BinaryExpression 为二项式 'abc' + 'def';
  51.                         if (types.isStringLiteral(newObj[key]) || types.isBinaryExpression(newObj[key])){  // 还原字符串
  52.                             console.log('花指令字符串替换前: ', identRefer[idenKey].parentPath + '')
  53.                             identRefer[idenKey].parentPath.replaceWith(newObj[key])  // 获取 obj 中对应的 StringLiteral 节点
  54.                             console.log('花指令字符串替换后: ', identRefer[idenKey].parentPath + '')
  55.                             console.log('====================================')
  56.                         }
  57.                     }
  58.                     // 数组翻转,从后向前遍历
  59.                     for (const idenKey in identRefer.reverse()) {
  60.                         // MemberExpression
  61.                         // 为 let d = c['StringLiteral']; 中的 c['StringLiteral']
  62.                         if (identRefer[idenKey].parentPath.isMemberExpression()){
  63.                             // 获取对应调用的属性值 c['StringLiteral'] 中的 'StringLiteral'
  64.                             let key = identRefer[idenKey].parentPath.node.property.value;
  65.                             // 如果 newObj 对应属性值为 FunctionExpression 类型
  66.                             if (types.isFunctionExpression(newObj[key])){
  67.                                 /*
  68.                                 function (){...}
  69.                                  */
  70.                                 // 拿到 return 语句
  71.                                 let retState = newObj[key].body.body[0].argument;
  72.                                 // 二元运算还原
  73.                                 // 例: return a + b
  74.                                 if (types.isBinaryExpression(retState)){
  75.                                     let operator = retState.operator;  // 拿到操作符 例: +
  76.                                     // 拿到参数数组
  77.                                     // c['funcBinaryExpression']('1', '2'); 中的 ['1', '2']
  78.                                     let Arg = identRefer[idenKey].parentPath.parentPath.node.arguments;
  79.                                     console.log('花指令二元替换前:  ', identRefer[idenKey].parentPath.parentPath + '')
  80.                                     // replaceWith 将当前的节点替换
  81.                                     // c['funcBinaryExpression']('1', '2');
  82.                                     // 替换成
  83.                                     // '1' + '2'
  84.                                     identRefer[idenKey].parentPath.parentPath.replaceWith(types.binaryExpression(operator, Arg[0], Arg[1]));
  85.                                     console.log('花指令二元替换后:  ', identRefer[idenKey].parentPath.parentPath + '')
  86.                                     console.log('=========================')
  87.                                 }
  88.                                 // 函数调用还原
  89.                                 // 例: return a(b) / return a()
  90.                                 // 这两个的差别只有调用的参数,一个对应调用的参数为 2, 一个调用对应的参数为 1
  91.                                 // CallExpression
  92.                                 // 例: return a(b)
  93.                                 if (types.isCallExpression(retState)){
  94.                                     // 获取该节点对应的参数
  95.                                     // 例: c['funcCallExpression1'](demo, '123');
  96.                                     // 中的
  97.                                     // demo, '123'
  98.                                     let Arg = identRefer[idenKey].parentPath.parentPath.node.arguments;
  99.                                     console.log('花指令函数调用替换前:  ', identRefer[idenKey].parentPath.parentPath + '')
  100.                                     // c['funcCallExpression'](demo, '123');
  101.                                     // 替换成
  102.                                     // demo('123');
  103.                                     identRefer[idenKey].parentPath.parentPath.replaceWith(types.callExpression(types.identifier(Arg[0].name), Arg.slice(1)));
  104.                                     console.log('花指令函数调用替换后:  ', identRefer[idenKey].parentPath.parentPath + '')
  105.                                     console.log('=========================')
  106.                                 }
  107.                             }
  108.                         }
  109.                     }
  110.                 }
  111.             }
  112.             // path.stop()
  113.         }
  114.     }
  115. })
复制代码
  还原前
  

   还原后
  

剔除无用代码

虚假 if

   demo.js
  1. if ('a' === 'a'){
  2.     console.log("'a' === 'a' true");
  3. }else{
  4.     console.log("'a' === 'a' false");
  5. }
  6. if ('a' !== 'a'){
  7.     console.log("'a' !== 'a' true");
  8. }else{
  9.     console.log("'a' !== 'a' false");
  10. }
  11. 'a' === 'a' ? console.log("'a' === 'a' true") : console.log("'a' === 'a' false")
  12. 'a' !== 'a' ? console.log("'a' !== 'a' true") : console.log("'a' !== 'a' false")
复制代码
  AST.js
  1. // 虚假 if
  2. traverse(ast, {
  3.     // IfStatement 为if判断语句
  4.     // ConditionalExpression 为三元表达式
  5.     "IfStatement|ConditionalExpression"(path){
  6.         // 该节点中的判断条件应该为 二元表达式
  7.         // left 节点应该为 StringLiteral 类型
  8.         // right 节点应该为 StringLiteral 类型
  9.         if(path.get('test').isBinaryExpression() && path.get('test.left').isStringLiteral() && path.get('test.right').isStringLiteral()){
  10.             // 取出判断条件中对应的值
  11.             // 例:  if ('a' === 'a') {  console.log("'a' === 'a' true");} else {  console.log("'a' === 'a' false");}
  12.             let operator = path.node.test.operator;  // 取出操作符 例: ===
  13.             let leftString = path.node.test.left.value;  // 左边的字符串 例: 'a'
  14.             let rightString = path.node.test.right.value;  // 右边的字符串 例: === 'a'
  15.             // 生成 eval 可判断的字符串
  16.             let vmRun = `"${leftString}"  ${operator} "${rightString}"`;  // 例: 'a' === 'a'
  17.             let result = eval(vmRun);
  18.             console.log('虚假 if:  ' + (path + '').replaceAll('\n', ''))
  19.             // 取出 if 与 else 中的代码块
  20.             // path.node.consequent.body 为 if(){}else{}; 形式取值
  21.             // path.node.consequent.arguments 为 statement ? true : false; 形式取值
  22.             let ifTrue = path.node.consequent.body || path.node.consequent.arguments;
  23.             let elFalse = path.node.alternate.body || path.node.alternate.arguments;
  24.             // 判断 result 的执行结果,替换对应的代码块 if 或 else
  25.             result ? path.replaceWithMultiple(ifTrue) : path.replaceWithMultiple(elFalse)
  26.         }
  27.     }
  28. })
复制代码
剔除无引用代码

  1. // 剔除无引用代码
  2. const refObj = {}
  3. traverse(ast, {
  4.     Identifier(path) {
  5.         let name = path.node.name;
  6.         if (!refObj[name]) {
  7.             refObj[name] = '1';
  8.             let binding = path.scope.getBinding(name);
  9.             let refPath = binding && binding.referencePaths;
  10.             if (refPath && refPath.length === 0) {
  11.                 path.parentPath.parentPath.isVariableDeclaration() && (console.log('删除的无用代码:  ', path.parentPath + ''), path.parentPath.remove())
  12.             }
  13.         }
  14.     }
  15. })
复制代码
剔除无引用的对象

  1. // 无引用的对象
  2. traverse(ast, {
  3.     VariableDeclarator(path) {  // 遍历 VariableDeclarator 节点
  4.         if (types.isObjectExpression(path.node.init)) {  // init 类型为 ObjectExpression 类型
  5.             let objName = path.node.id.name;  // 获取对应的标识符
  6.             let objBinding = path.scope.getBinding(objName);  // 获取标识符对应的引用
  7.             let objRefer = objBinding && objBinding.referencePaths;  // 获取标识符引用对应的数组
  8.             let quoteObj = false;
  9.             for (const index in objRefer) {
  10.                 let grandPath = objRefer[index].parentPath.parentPath;
  11.                 if (grandPath.isAssignmentExpression() && grandPath.get('left').isMemberExpression()) {
  12.                     if (grandPath.get('left.object').isIdentifier() && grandPath.node.left.object.name === objName) {
  13.                         console.log(grandPath + '');
  14.                         console.log('==============================')
  15.                     } else {
  16.                         quoteObj = true
  17.                     }
  18.                 }
  19.             }
  20.             if (!quoteObj) {
  21.                 for (const index in objRefer) {
  22.                     let grandPath = objRefer[index].parentPath.parentPath;
  23.                     grandPath.remove();
  24.                 }
  25.             }
  26.         }
  27.     }
  28. })
复制代码
数值还原

  1. // 数值还原
  2. traverse(ast, {
  3.     NumericLiteral(path){
  4.         console.log('替换前: ', path.node.extra);
  5.         delete path.node.extra.raw;
  6.         console.log('替换后: ', path.node.extra);
  7.         console.log('==============================');
  8.     }
  9. })
复制代码
switch 还原

  1. // 还原 switch
  2. traverse(ast, {
  3.     WhileStatement(path){
  4.         if (path.node.test.prefix && path.get('body').isBlockStatement() && types.isSwitchStatement(path.node.body.body[0])){
  5.             // 获取同级节点
  6.             let sibling = path.getSibling(0)
  7.             let whileIdx = (sibling.node.declarations[0].init.callee.object.value).split('|')
  8.             let idxObj = {}
  9.             let caseIdx = path.node.body.body[0].cases;
  10.             for (const index in caseIdx){
  11.                 let key = caseIdx[index].test.value;
  12.                 idxObj[key] = caseIdx[index].consequent[0];
  13.             }
  14.             let newArray = []
  15.             for (const index in whileIdx){
  16.                 newArray.push(idxObj[whileIdx[index]])
  17.             }
  18.             path.replaceWithMultiple(newArray);
  19.             // 删除同级节点
  20.             while(path.key--){
  21.                 path.getSibling(path.key).remove();
  22.             }
  23.         }
  24.     }
  25. })
复制代码
  还原前

    还原后

  完整的 AST 代码

代码

  1. // 安装 babel 库:  npm install @babel/coreconst fs = require('fs')const traverse = require('@babel/traverse').default  // 用于遍历 AST 节点const types = require('@babel/types')  // 用于判断, 生成 AST 节点const parser = require('@babel/parser')  // 将js代码剖析成ast节点const generator = require('@babel/generator').default  // 将ast节点转换成js代码// 读取(路径记得改)const ast_code = fs.readFileSync('demo.js', {    encoding: 'utf-8'})let ast = parser.parse(ast_code)  // 将js代码剖析成ast语法树// 这里插入剖析规则///// 解密函数中必要的 atob 函数global['atob'] = require('atob');  // npm install atob// 解密函数依靠的大数组var $dbsm_0x23b3 = ["QjjDhA==", "IyQb", "552u776q5L6D", "eCvDoA==", "EHwT", "wpdVw6I=", "RArDvA==", "Hk8D", "MUvCnA==", "wotlw5k=", "w7xTwrU=", "wrLCvT0=", "w5LCvUc=", "w6hIwrY=", "w716Rw==", "L8OzwpI=", "MlMA", "Gm8r", "WcKVw44=", "W8KKw5s=", "w6bCgUE=", "TSnDpg==", "aEXCuw==", "HMOzwrc=", "wqs3Bg==", "KHsW", "AcOtwp4=", "N8KeIA==", "cifCig==", "wrBZw7M=", "AMKtw4g=", "FMOkwqA=", "WwEa", "DjzDqA==", "wo7CnAs=", "wpdoAQ==", "JsOfwp0=", "J8KRKA==", "ZsOCw58=", "wojCiAQ=", "w7vCuMKR", "ATY3", "ZyfCvQ==", "dCJD", "UMKpVg==", "O2US", "wqE3LA==", "SMOtwqk=", "w5PCh8Ki", "bMKyaA==", "S8OjEw==", "AcKGw68=", "wpVFw5M=", "fDvDpw==", "w7Brwqk=", "dGYb", "eC45", "AsOGwrE=", "w7fDhcKz", "YATDlA==", "DsK6w6A=", "wrNLw7U=", "biAN", "TxVF", "VzJ2", "wr3CrRc=", "wr0WEQ==", "YAvDrw==", "wqtZNg==", "K0QC", "Y8KBw6c=", "Q8KEw6E=", "wrUhKQ==", "CXfDjA==", "G34/", "esOcTQ==", "wpFiDA==", "w4xCaQ==", "Blo7", "w6vDvcKT", "eyFl", "BE8K", "w6HCvUs=", "wplqw6M=", "wqdOw5Y=", "wqzDr8KW", "XsKdcw==", "VMKsag==", "ecO9w58=", "EkcB", "wpJIw5U=", "JFrDiA==", "YsO7cg==", "eTvCiA==", "wojCuxc=", "WyXDmw==", "MUrDtg==", "w5XDhcKw", "fMKLcw==", "eMOhw5w=", "EGnCjA==", "RcKTYg==", "OALDvQ==", "HlE/", "Q8KGag==", "wpQpFA==", "wqg5wqw=", "ZsOqw4A=", "wp1Ewpk=", "wpkPwro=", "UT9O", "XsOmw7g=", "CFkm", "W0gI", "P8Ouwrw=", "eEMQ", "L8KSw7k=", "ecOvw4Y=", "WT9O", "J8KYfw==", "BiEH", "w7VnwpM=", "w6dxbg==", "wo/Ci8Os", "wqgpAg==", "wozCm8OB", "clHCjA==", "QsOsw6Y=", "woZew44=", "Zz7DnA==", "RgzDrg==", "XMKAVw==", "SwBb", "VMKCSg==", "Ryp1", "wr9Mw44=", "w4rDqMK7", "UMOiw6E=", "w6fDo1U=", "VMOEw4c=", "EcKew4c=", "c8KRZQ==", "WsOOUQ==", "wodyLA==", "e8KMUg==", "w5TDln0=", "GcKbw4s=", "BMK0w7Y=", "wpIewoU=", "R8Kcw6k=", "wobDuMOi", "BsO/wp4=", "VcOnw6w=", "w5t0wok=", "wqgPwpA=", "woTCu8Or", "fg3DvQ==", "L8KEw6g=", "wphswpI=", "woYgIg==", "AXgq", "VTLCqg==", "wrRww4Q=", "wqM1Ig==", "YCzDjQ==", "EVkx", "PWsV", "JWbDjw==", "DF4M", "WcObw54=", "DMKXw6w=", "EcKmOA==", "WsOJw58=", "ajsY", "SsK1w4Q=", "w4zDqMK0", "Gics", "UTkL", "w754wrA=", "IBw2", "wopkDA==", "NFEb", "EFHDig==", "W8Okw40=", "C8KpVg==", "EmnDsQ==", "VhvDmA==", "wqTCoMOV", "fcOfw6A=", "JsKkNw==", "ecOjKg==", "aSTDsA==", "woYfOg==", "YcOyYA==", "fMOtw4E=", "eMOSw5A=", "w7jCn8KA", "LGI2", "asO0Ow==", "f2cW", "egvDuA==", "GcOeGQ==", "w4NYQw==", "IMKvw68=", "wrfDpsO6", "BcKjJA==", "w6PDu2g=", "ayTDrA==", "B0kt", "QsKTVg==", "wpvCuMO1", "YsOHw6M=", "B1XCuA==", "B8Kjw5w=", "Q8Oqw6g=", "RMOAw4c=", "w4/DssK0", "w4rDm8KQ", "ScOwQg==", "YsOGw5s=", "RjbDjQ==", "SCLDpg==", "VcOVMQ==", "KnHCgQ==", "JMONwrU=", "WcO/Cw==", "YcKuRQ==", "wr0MCw==", "WAHDnw==", "esKuUg==", "wp8mNA==", "MMOAEw==", "bcOBw4w=", "w5LCl8K/", "KXk3", "agpl", "wprChSg=", "w5BmYw==", "S2zCrg==", "BXIv", "EMOUwpA=", "WcKvVg==", "WsKkw4I=", "w69iwqQ=", "e8KYVw==", "Y8Ojw6s=", "KUUk", "LcOYwq0=", "Xj/DvQ==", "RiXDkg==", "wrbDiMOj", "Ujd6", "cAc+", "dzt2", "QsO9w6w=", "Ghg3", "ccKkcA==", "fRvDkA==", "KcK4Og==", "H30u", "PMKyw4Y=", "YyrDtw==", "wpDCiMOh", "wqwowoc=", "wojCjDQ=", "wqHCj8OU", "w7HCm8KR", "XsOVw7Q=", "w47Cp8Kj", "w6LCnMKo", "GsKMbw==", "w5J0wrU=", "RCnDuA==", "wpfCgjE=", "wrMnBw==", "w7bDqsK/", "KEM4", "a8OKwrw=", "wpBlw5Q=", "MTAo", "X8K2w5I=", "WsOvFQ==", "Yz7DkQ==", "W8Ocw54=", "ahtQ", "D2vDrg==", "VsKcw4o=", "Fy/CkQ==", "JnAI", "MMOswrA=", "w4zDt8KI", "wrDCksOj", "GBcc", "fcO9Sg==", "w4HDgXY=", "MsKeHA==", "ccOBw4o=", "QsOgw4M=", "Q8OjBg==", "EMK5FQ==", "R8OCw6o=", "XS9D", "d8KfcA==", "wpbCmSE=", "w4XChn8=", "aMKieA==", "woVhGQ==", "wo7CnsOK", "AXwd", "dCAI", "worDhsOC", "V8Krw4A=", "VxHCvA==", "woFywrg=", "w4ZRaA==", "VMO5w6Q=", "wp1zHg==", "wqw/wqo=", "BMKRw58=", "wpxjw7U=", "McKEw4o=", "YyIF", "fkME", "wp1xw6o=", "Sg80", "HMKbAQ==", "HHoX", "MsK7Cg==", "woZWCw==", "GsOKwrE=", "P8KPGg==", "bBDDhw==", "ewLDng==", "TSMk", "wrbCrT4=", "w7tkRg==", "DDQv", "wrdpLw==", "wonDmsKK", "Tx8o", "WMODw7I=", "MXgT", "w6PCrUw=", "wobCg8OR", "Z8Odw6U=", "w55LwrA=", "O8ORwqU=", "w5vDo10=", "wq3Cl8OT", "asKMUQ==", "woBpPg==", "SnPCrA==", "wo7Dn8KG", "wqVtw54=", "wo9WNA==", "QMObNw==", "TMKAw4Y=", "eHEn", "w5rDqcKk", "wqRlw68=", "CxYO", "WcK2VA==", "wpgrAw==", "wpHCgw4=", "wrHCklU=", "BkIZ", "woh4wqM=", "wpBICg==", "AcORGg==", "wpd0NQ==", "w4HDqsKa", "YcKvew==", "wpvCusOs", "K8K5JA==", "w7LCrGU=", "XkUT", "XMOow6s=", "w7/DqcKj", "NsOdwqQ=", "VcOsw7Q=", "eXED", "McKbdA==", "AHXCow==", "K8KeQg==", "ZgMB", "Hm4g", "f8Oqwow=", "AHPDpA==", "wq4Mwq0=", "WsKeYg==", "fDjCog==", "wpY/PQ==", "V8K9cg==", "OlAN", "esO8Xw==", "GsKaJA==", "WgjDnQ==", "DW7CrA==", "f8K1Qg==", "eSw0", "RAIx", "Cls9", "FMOYwqM=", "w4bCvVE=", "wovDkMKK", "WsK/Tw==", "QRrDgw==", "wpV9w4o=", "wrXCmxA=", "wpXChik=", "wq5kw7g=", "wo5jPA==", "w5VgZQ==", "wr1Cw4o=", "wpBYw60=", "woVOwpw=", "wpB2Cg==", "cBlA", "wo52Cg==", "QcO/w58=", "w65UwrM=", "fyfCng==", "w6TCp2s=", "wrRWJQ==", "w7bCv8KW", "XsKyeQ==", "MWbDiQ==", "w4jDscK1", "d8K1w4U=", "C34+", "wprDt8O9", "VsKlw7E=", "w4JdfQ==", "wos1Jg==", "PE7DuA==", "w4bDnsKM", "w5XDq8KA", "JTIy", "w5LDpMKu", "YArDsQ==", "K8K9IQ==", "DsKmw7E=", "BMKxw7A=", "wrvDncKg", "dzrChQ==", "G1nCjg==", "YEYA", "OsKzJg==", "wrfCugs=", "XlvCkA==", "fcKDw54=", "e8OMw40=", "wpBDw68=", "w45CwoY=", "WsONwpw=", "BFDCiQ==", "w7VidA==", "Aloq", "w73Cq8KT", "IkE4", "wqN0Nw==", "dBLDmw==", "wqlRw44=", "w7lleQ==", "C1TCgQ==", "PsKPJQ==", "VcK0bg==", "XcOBwo4=", "VMOjZQ==", "w7pjXg==", "wrBvFw==", "cARj", "w4JSaQ==", "MsK4w4Y=", "acOeeQ==", "AsOQIQ==", "wqUDBQ==", "X1Zb", "RMKKaA==", "w6fDs8KB", "HsKzdw==", "V8OJLA==", "XMOFwqo=", "V8Kybw==", "w5zDhG4=", "wrFHNQ==", "RcOhw6s=", "w6Vhbg==", "XcOow48=", "w5bCi24=", "NkfDgw==", "AcOyHA==", "XUzClw==", "w5XCgGY=", "w5rDhVA=", "a1c3", "WnzCsw==", "wrvDncK4", "w7pUwqk=", "QT1j", "DmLCuA==", "w69tVA==", "w6bCvMK+", "cVUo", "dcO8wqc=", "cBlK", "w5zDhWc=", "wpt+w6w=", "w6lFwrI=", "wojDiMOS", "XcOZw78=", "UwhO", "wotmw4M=", "RC4Y", "w77CjU0=", "S8O3w6U=", "PGAG", "WsKowq8=", "wqTDmsOo", "Hlo8", "I8OuwqQ=", "c8OAKA==", "cl7Cmw==", "V3PCvA==", "DnM2", "wqQTGQ==", "WWYV", "wozDosOV", "w7fDisKb", "csO+w4A=", "IsKiPw==", "w75iQA==", "Ww7CgA==", "wqtrLA==", "fsKtw6c=", "DsKbw5M=", "w5fDgMKO", "wrcaIQ==", "S1c5", "wrMaOQ==", "AcKIcA==", "Cjww", "w6VWYA==", "OQom", "ZxjDjQ==", "wrMoNw==", "VQXDmA==", "d8KeYQ==", "BEs8", "J0k9", "wpEeEQ==", "wqAHFQ==", "w6/DicKx", "ScOiCg==", "YxXCtg==", "dsOiw4k=", "THjCqQ==", "HMK+AA==", "wpQhHw==", "wr7CvcOq", "K0bDiw==", "eMOAcg==", "w60rdg==", "L1IC", "woNlw60=", "K8KDw4k=", "wrpFDg==", "wpFEMw==", "w6fCrGw=", "wo0mCA==", "cUTCtQ==", "w7LCqMKX", "W8OiwoQ=", "QAvDqQ==", "AD03", "aDfDiQ==", "UTHDpQ==", "ZhMa", "w6bDrMKs", "AkvCuw==", "wo8yBQ==", "wo4IPQ==", "M3QK", "TwrDnw==", "wqFcDw==", "e8O7bA==", "PkHDlg==", "esOBwqk=", "eRFw", "ZyvCnw==", "w7PDtcKx", "wpQ1woA=", "WwFc", "XRsF", "BMOCPQ==", "SHHCjA==", "XcOew5w=", "wqhaKA==", "YynCvg==", "XS3Chg==", "BFI0", "wr9HDA==", "wpx7w5o=", "w6DDmHU=", "bA84", "I3AA", "w7jCn2s=", "BWPClw==", "wpbDt8O1", "wpsKYw==", "wq9jw5I=", "woFQwp4=", "wpI9Mw==", "B8KwEQ==", "DmYq", "CcKbAQ==", "TS49", "w6bDvWU=", "YsOVNw==", "dMKBRQ==", "NXg8", "wrBJwoI=", "KsKAYQ==", "EcKNdQ==", "ecO7OA==", "wrV6w7I=", "WMOSw6Y=", "wqV6wqI=", "VcKyUA==", "fcO4Sg==", "IXQl", "Z8KaXw==", "VnvCnQ==", "wr9qOg==", "w6PDiGs=", "QD0a", "wrzCm8OQ", "w6LCp1w=", "bMK+w6A=", "w7PDn24=", "T2LClg==", "woBJw7c=", "SiPDjQ==", "wqbChTI=", "Wj3Dpg==", "fxgU", "YhzCuA==", "ETsw", "W8OdCA==", "GcOxIg==", "Kxkw", "B2zCuA==", "OBER", "Cl4R", "wrLDpMK8", "wq/CnsOZ", "w5XDv8Kw", "dysc", "Y8KjVQ==", "fcOvw40=", "CWjDug==", "bMObNg==", "ScOEw4c=", "w6RTwqM=", "wpJLEw==", "BTw5", "ScKDw4c=", "XMKbw5o=", "TxjDhw==", "w5pOew==", "wpJawp0=", "ZsKwQQ==", "FGMO", "GMKRw7o=", "QMO+OA==", "wrtaMQ==", "TMOUMA==", "J3jDuA==", "D8OnwqA=", "w7zCgcKv", "VnLCmw==", "Z8OJw4I=", "bADDng==", "ccKCZg==", "wrIUJA==", "XCHDow==", "w6DCsV8=", "ZsKafw==", "w5J7fg==", "M8OMwps=", "w7DDt8KG", "W8OYXw==", "EHDDhw==", "w63ChsKU", "O8Kiw4k=", "wrlxDA==", "wrnCkcON", "wqFfHg==", "wovDsMKh", "w67CmMKk", "w75Pwq8=", "wq/DnMKX", "SyhS", "wp1uOA==", "wr3Dt8KG", "DnI2", "OWEf", "w5PDisKX", "wr3CuRE=", "YBJu", "wrxgw58=", "wrEEIQ==", "Uy53", "V2/CjQ==", "ecOjw6Q=", "SMKjw5s=", "X8O5w7Y=", "RsK3w50=", "wpA+wro=", "aynDjQ==", "ccO5w6E=", "ezjCjw==", "BMOPJQ==", "w7FFwq8=", "QsOnw6Y=", "w5VRQQ==", "HmkA", "f8Oewr0=", "dsO7w78=", "w7PDrcKT", "w4vCr3E=", "X8O6w7s=", "CRTDqQ==", "VcO8w54=", "KmjDrA==", "w4dSfQ==", "BG7DpQ==", "bMOvw54=", "bi5F", "VDjDpQ==", "w6HCiFo=", "aMOYCA==", "w5fDqE8=", "CXbCpg==", "FMKwIg==", "w4BxSQ==", "QTbDow==", "J2si", "MsOxwpI=", "IsOdHA==", "wojDlsKP", "Hn44", "bMOQRg==", "dMKCWg==", "w7rDnF4=", "B8K5w58=", "WSjDpg==", "XsO5w5g=", "QTo7", "wqUZwoM=", "ecK1aA==", "esKDUA==", "woFCwrE=", "woISwos=", "dsODEw==", "McOrOQ==", "JVTDmA==", "XcKxbw==", "wqZZBg==", "OsKjFg==", "UQTDkg==", "woh3w4A=", "w5FXwpM=", "wpJAw7w=", "Ongr", "w41zwos=", "N8OGDw==", "w6DDicKj", "UQ0U", "CsKCTw==", "fTnDhA==", "w6TDqHA=", "AloY", "CV4e", "DsKJbQ==", "LyoG", "OFnChA==", "NFsh", "w596fA==", "w6FsYA==", "Pm/Chg==", "wrZ1Ew==", "wprDmcKo", "C3QW", "wo7CqDM=", "woYANg==", "wq3Dl8Ok", "wp7DlcKp", "csKXeA==", "wqVyHA==", "wptxw6k=", "IMOIwpE=", "HcKkw78=", "XzXDsg==", "Q8KAw48=", "QMOOWg==", "V3TClA==", "woY5Pw==", "K2jCng==", "c8OewoY=", "w5zDqVY=", "Al/Cmg==", "w7TDp8Kg", "wpjCoiU=", "G8ONAA==", "w7rCjMKO", "RSjDsg==", "esODbg==", "EWcq", "NsK4BA==", "PcKeEQ==", "GcOpJw==", "cTpO", "wrzDl8Kv", "CcKSw7I=", "fhPDpw==", "wqcfLg==", "B8KiIQ==", "OcKQw78=", "SjHDug==", "w4vDvcKd", "wq8kGQ==", "HH8J", "DVbDsg==", "LXHDrA==", "WCpe", "N8OjGQ==", "MVrDjA==", "ZB/Dpg==", "w7xvwpE=", "WwjDvA==", "wo4cIQ==", "esOvEw==", "wpJRw7Y=", "TRNg", "wrZ0Ag==", "dcOLcQ==", "bsKAw6E=", "wqdoPg==", "XDrCgg==", "wosKPw==", "bwTDvw==", "XQAy", "wpAUwoU=", "dB4t", "wpFRNw==", "UMKwQQ==", "ecOlw48=", "w6TChMKP", "XxFP", "A8K5Pg==", "w5dbfg==", "woDCtcOn", "IE3Cqg==", "JUvCqg==", "HzYw", "ecKEaA==", "fQEi", "fQR3", "J8KsEQ==", "b8Ofw6U=", "MsK6Jg==", "w7bDsMKT", "wqxuwps=", "XxPCrg==", "JcKQbg==", "FsOtAw==", "RcOBw6U=", "YcOxUg==", "EnAz", "ci8a", "VcO9w6E=", "Qj7Dvg==", "YMKEeQ==", "wqLDiMKl", "w5xawoM=", "TMOow6k=", "eRjDpQ==", "DXjCgQ==", "wq87HA==", "w5jCrMKw", "YsKzVw==", "fcOrwq8=", "wpNxw40=", "BgIo", "YcOEw6Q=", "BsKkw7M=", "L1XDiQ==", "DMKeaQ==", "cT3DmA==", "WDtL", "HVQy", "YTzDow==", "TsOZw5A=", "wpLCnSI=", "Ri8m", "w4fDiU0=", "ah5R", "w4TCuEs=", "w6bDusKY", "dgDDow==", "RAx3", "w71XVg==", "X8Obwoo=", "wrfDi8Kd", "ZsO+w5o=", "cB9B", "BH4p", "USBR", "w4bDksKn", "dSXDmQ==", "YMKew4A=", "V8O9BQ==", "wooxGQ==", "VX/Csg==", "XsOEw6Y=", "wrofBg==", "wpUBBw==", "wq87Gg==", "w4HCo0E=", "wpnCrAw=", "asOGwok=", "wqTChyA=", "wr91KA==", "FsKSLg==", "w5LDrMK5", "UxTDqw==", "JCMb", "IlfDmg==", "a8ONYA==", "IMO/wqM=", "OsOMwoI=", "YnM7", "YcOhcA==", "ZgDDhw==", "fcOnwq8=", "QAJu", "METDqw==", "HMKYRQ==", "IsKBw4g=", "wq9Cw5Y=", "WsOZFw==", "wrZkw60=", "aTAu", "bzgc", "RcOPBw==", "wqhlMQ==", "eMOrw48=", "O8Kjw68=", "STbDjA==", "wqvDgsOf", "G8K0bw==", "DsKdfQ==", "w4HCgWY=", "bgHDvw==", "CXPDlg==", "woFJFQ==", "wqDDlcKF", "QADDtg==", "w7tkSQ==", "Vgo3", "BEUK", "wrN2DA==", "wrHDlcKk", "XMOiEQ==", "wq/CnCU=", "QcKUUw==", "ODRV", "wpJuwpc=", "w67DkXY=", "NMOwwr0=", "VD8w", "KG4V", "acOAwqg=", "LMKWKg==", "wrLDmsK7", "a8K3bw==", "w6nDlMKA", "Y8OJw4s=", "w7xjSQ==", "AMKOdg==", "ay9S", "woFUPg==", "DcKVbA==", "Q8ODw4Y=", "w6JkTw==", "wrx5Hg==", "wr/DhsKl", "wo9QMQ==", "bSXDrg==", "eMOrWA==", "GMKpw78=", "w6fDuns=", "wqnDuMKI", "I1rDug==", "IHsb", "wqJMHw==", "OMOdwoM=", "HW4u", "w6JFQQ==", "wrJHEg==", "wpZcw7U=", "wq1tGw==", "wol2wog=", "w6nCu0s=", "wpLDl8KP", "woPCusOl", "wr7CtMOG", "wofDgsO2", "wprCuys=", "cD7Dhg==", "BWMM", "GMKYPA==", "WMOOw44=", "w4VFXA==", "w7DDmk0=", "F8KDOg==", "wo8jCQ==", "bcKEw44=", "aCkH", "cV0v", "aMO9Dg==", "cMOjw5E=", "CiM0", "Sy0W", "dTPCug==", "FsOuwp4=", "BkAs", "ZnkQ", "w7oxw4I=", "WMOPw4w=", "wqvCvyI=", "SRbDow==", "YinCjQ==", "cz4p", "w6PCqsKV", "VgVq", "BCE2", "w5LDrV4=", "TcO2Jw==", "eyRA", "a8Ouw7o=", "J1jDog==", "QcO5w40=", "FkvDjA==", "GMKpLg==", "ZwTDsg==", "wqzCsMOJ", "YS7ClA==", "w4bCuk0=", "ZMOOIA==", "wo4fwpQ=", "S8K6Vg==", "QcObw6U=", "wq9DHQ==", "IXgZ", "FFwc", "wqhvOA==", "wqBnwrw=", "QsOfJg==", "NW8A", "RRPDow==", "VAIr", "D8Kaw4s=", "X8OcGQ==", "JGEU", "eMKTbg==", "Y8OYbA==", "XcKaRQ==", "FMOrAQ==", "fwjCoA==", "wqnDhMK7", "wqkVwq8=", "P8KUfQ==", "Yh7DpA==", "BAsm", "RMK2w50=", "PcOwKg==", "CcKbw6w=", "HsKWTw==", "eyrDmA==", "woDDi8KC", "A2fDjw==", "YRTDlg==", "UsOow64=", "LCsE", "wo4dOg==", "wphxwpE=", "woUcAA==", "wqMfAA==", "TMKAw4U=", "GsKDw7k=", "PTE8", "wrlPGA==", "wqPDn8OT", "ZcOBw60=", "wrjCuMOq", "W8Kmw5k=", "XMOaw7k=", "wqxzwpM=", "fhDCqg==", "QMO+w7E=", "DVgs", "w6lSwrg=", "VMOHw6g=", "P8Oowrg=", "w7zDqHk=", "wq4CAw==", "wqpTDw==", "bDpH", "QcOYw4M=", "SBkv", "worCicOp", "wo0hGQ==", "w5JgWA==", "YQ5g", "AsK+Xg==", "XMOEwoo=", "ZiAN", "IsKsBQ==", "w6PDpVw=", "wrrCjSY=", "TcK+w6M=", "wp/DkMKL", "fhwQ", "ZHcF", "VDXDqw==", "w7rDg8Kg", "w5pywpc=", "UH3Cqg==", "AMOJwpI=", "wpxwwrU=", "SsONwo0=", "Az8p", "U2fCnA==", "wrLDlcKB", "XSlH", "QcOhKA==", "LG7CnQ==", "w6LDlsKm", "w5hkYQ==", "wqvDi8OU", "wo7CqDE=", "fAvCgQ==", "G8Kzw7A=", "YVAg", "wo/CnSY=", "Dk7CgQ==", "RzzCmw==", "P8OdAA==", "wqFcDQ==", "K8KVSA==", "woVawp8=", "JnEi", "w67DmsKc", "w6JRTw==", "DMK9cA==", "aBhR", "Zi4W", "dhzDvw==", "RsO7wq4=", "ecOcw6E=", "JcOmwqY=", "EcKwVg==", "WsKXeg==", "Byo1", "ElYq", "BloJ", "XMO4Ew==", "wo5+w7g=", "Mkk8", "wqAhJw==", "bjjDuw==", "w7bCpsKR", "Z8O7aw==", "d3fCvw==", "wpbDpcOF", "ScK7w7I=", "CkfDjg==", "ecOafA==", "YMOBw4A=", "wo0dwq4=", "dsKWTQ==", "DcKQZA==", "IEvCpw==", "w7fDulQ=", "aXnCkg==", "woMpJg==", "fWQq", "NnPDkQ==", "USBV", "U2gZ", "RsKBZw==", "e8K/cg==", "WMK5w4s=", "wrFww5I=", "w5PDhHk=", "ZsOxwos=", "wp3DisKX", "w7DCmVg=", "w6x4Rg==", "LH4K", "O20W", "ZMOZw7U=", "PMKfaA==", "bRhn", "Izwv", "w4cfwqU=", "w4fCpG0=", "aBvDoA==", "RMKveA==", "QcOxSg==", "V8K7cw==", "J8KeQg==", "w4LDiX0=", "IsKSUQ==", "VQXDkw==", "LXMp", "IsKgw6w=", "TCU4", "ayl1", "w6TDksK+", "Zn0Q", "AHbDug==", "w7JSwpg=", "G8OpwoM=", "fS1h", "wrxxw4s=", "wogKAw==", "wpYvwqA=", "eWXCkw==", "U8Ofw70=", "e2sT", "woUBAw==", "w6LDjmw=", "a8OPw54=", "U8KHbw==", "HTA7", "wonDs8Kk", "BFQG", "w5PDolU=", "ciXDkA==", "NcOSwrg=", "fCTDow==", "woYuwpQ=", "alQl", "S8Kbw5U=", "woRaw7M=", "E34q", "O8KdJg==", "WAHDng==", "w6DCmnA=", "OkYH", "Y8KWRQ==", "w5VNwpk=", "I0HDpg==", "wrQSJA==", "aQ9P", "HcKBw6g=", "eQnDsA==", "wpAcOw==", "w5HDmsKC", "w5tWwrs=", "ecOcIQ==", "JcKvMA==", "bRh5", "cB0F", "VjTDgA==", "wptrw7s=", "WDnDrw==", "Rz09", "wpYdAA==", "wrpUwpM=", "DcKifg==", "wp/DusKm", "wqAoOg==", "a17Cmw==", "J2k1"];// 解密函数var $dbsm_0x4638 = function (_0x1e1b14, _0x23b316) {    _0x1e1b14 = _0x1e1b14 - 0x0;    var _0x4638d3 = $dbsm_0x23b3[_0x1e1b14];    if ($dbsm_0x4638['lIzlCZ'] === undefined) {        (function () {            var _0x4b121c;            try {                var _0x1d5b59 = Function('return\x20(function()\x20' + '{}.constructor(\x22return\x20this\x22)(\x20)' + ');');                _0x4b121c = _0x1d5b59();            } catch (_0x4f5869) {                _0x4b121c = window;            }            var _0x55f54d = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';            _0x4b121c['atob'] || (_0x4b121c['atob'] = function (_0x2337bc) {                    var _0x94736f = String(_0x2337bc)['replace'](/=+$/, '');                    var _0x5e548f = '';                    for (var _0x588d26 = 0x0, _0x5d3f20, _0x558d8e, _0x49832a = 0x0; _0x558d8e = _0x94736f['charAt'](_0x49832a++); ~_0x558d8e && (_0x5d3f20 = _0x588d26 % 0x4 ? _0x5d3f20 * 0x40 + _0x558d8e : _0x558d8e,                    _0x588d26++ % 0x4) ? _0x5e548f += String['fromCharCode'](0xff & _0x5d3f20 >> (-0x2 * _0x588d26 & 0x6)) : 0x0) {                        _0x558d8e = _0x55f54d['indexOf'](_0x558d8e);                    }                    return _0x5e548f;                }            );        }());        var _0x2ef3c5 = function (_0x49a1eb, _0x27f9fb) {            var _0x26a837 = [], _0x90ed46 = 0x0, _0x1e184c, _0x229955 = '', _0x28a13b = '';            _0x49a1eb = atob(_0x49a1eb);            for (var _0x4237c8 = 0x0, _0x18c69a = _0x49a1eb['length']; _0x4237c8 < _0x18c69a; _0x4237c8++) {                _0x28a13b += '%' + ('00' + _0x49a1eb['charCodeAt'](_0x4237c8)['toString'](0x10))['slice'](-0x2);            }            _0x49a1eb = decodeURIComponent(_0x28a13b);            var _0x2c4f5b;            for (_0x2c4f5b = 0x0; _0x2c4f5b < 0x100; _0x2c4f5b++) {                _0x26a837[_0x2c4f5b] = _0x2c4f5b;            }            for (_0x2c4f5b = 0x0; _0x2c4f5b < 0x100; _0x2c4f5b++) {                _0x90ed46 = (_0x90ed46 + _0x26a837[_0x2c4f5b] + _0x27f9fb['charCodeAt'](_0x2c4f5b % _0x27f9fb['length'])) % 0x100;                _0x1e184c = _0x26a837[_0x2c4f5b];                _0x26a837[_0x2c4f5b] = _0x26a837[_0x90ed46];                _0x26a837[_0x90ed46] = _0x1e184c;            }            _0x2c4f5b = 0x0;            _0x90ed46 = 0x0;            for (var _0x4fe42c = 0x0; _0x4fe42c < _0x49a1eb['length']; _0x4fe42c++) {                _0x2c4f5b = (_0x2c4f5b + 0x1) % 0x100;                _0x90ed46 = (_0x90ed46 + _0x26a837[_0x2c4f5b]) % 0x100;                _0x1e184c = _0x26a837[_0x2c4f5b];                _0x26a837[_0x2c4f5b] = _0x26a837[_0x90ed46];                _0x26a837[_0x90ed46] = _0x1e184c;                _0x229955 += String['fromCharCode'](_0x49a1eb['charCodeAt'](_0x4fe42c) ^ _0x26a837[(_0x26a837[_0x2c4f5b] + _0x26a837[_0x90ed46]) % 0x100]);            }            return _0x229955;        };        $dbsm_0x4638['UYyCMO'] = _0x2ef3c5;        $dbsm_0x4638['nMtFyB'] = {};        $dbsm_0x4638['lIzlCZ'] = !![];    }    var _0x57b28f = $dbsm_0x4638['nMtFyB'][_0x1e1b14];    if (_0x57b28f === undefined) {        if ($dbsm_0x4638['DwWKuR'] === undefined) {            var _0x9e4186 = function (_0x3712d5) {                this['kHsRXo'] = _0x3712d5;                this['nWOEyU'] = [0x1, 0x0, 0x0];                this['tpblbK'] = function () {                    return 'newState';                }                ;                this['lAcsth'] = '\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*';                this['foeeRg'] = '[\x27|\x22].+[\x27|\x22];?\x20*}';            };            _0x9e4186['prototype']['RuyyZP'] = function () {                var _0x20d28 = new RegExp(this['lAcsth'] + this['foeeRg']);                var _0x5e0e5f = true ? --this['nWOEyU'][0x1] : --this['nWOEyU'][0x0];                return this['XVTLWU'](_0x5e0e5f);            };            _0x9e4186['prototype']['XVTLWU'] = function (_0x3ab8dc) {                if (!Boolean(~_0x3ab8dc)) {                    return _0x3ab8dc;                }                return this['HxFvMA'](this['kHsRXo']);            }            ;            _0x9e4186['prototype']['HxFvMA'] = function (_0x13037d) {                for (var _0x3bdd37 = 0x0, _0x49b603 = this['nWOEyU']['length']; _0x3bdd37 < _0x49b603; _0x3bdd37++) {                    this['nWOEyU']['push'](Math['round'](Math['random']()));                    _0x49b603 = this['nWOEyU']['length'];                }                return _0x13037d(this['nWOEyU'][0x0]);            }            ;            new _0x9e4186($dbsm_0x4638)['RuyyZP']();            $dbsm_0x4638['DwWKuR'] = !![];        }        _0x4638d3 = $dbsm_0x4638['UYyCMO'](_0x4638d3, _0x23b316);        $dbsm_0x4638['nMtFyB'][_0x1e1b14] = _0x4638d3;    } else {        _0x4638d3 = _0x57b28f;    }    return _0x4638d3;};// 解密函数还原字符串规则traverse(ast, {    CallExpression(path) {  // 遍历 CallExpression 节点        // callee 属性为 Identifier 范例        // 且 name 属性为 $dbsm_0x4638 解密函数名        if (types.isIdentifier(path.node.callee, {name: '$dbsm_0x4638'})) {            // 取出对应的参数            // 例: $dbsm_0x4638('\x30\x78\x32\x39', '\x72\x69\x63\x50')            let callArg = path.node.arguments;  // 例 ['\x30\x78\x32\x39', '\x72\x69\x63\x50']            let arg1 = callArg[0].type;  // 例 '\x30\x78\x32\x39'            let arg2 = callArg[1].type;  // 例 '\x72\x69\x63\x50'            // 将对应的参数取出后, 拿到 $dbsm_0x4638 解密函数执行            let result = $dbsm_0x4638(callArg[0].value, callArg[1].value)            // 将对应的节点更换成 解密函数执行后的结果            // 例            //    将节点:  $dbsm_0x4638('\x30\x78\x33\x66\x36', '\x68\x32\x25\x5e')            //    更换成:  "hei"            console.log('解密函数执行前的节点: ', path + '')            path.replaceWith(types.valueToNode(result));            console.log('解密函数还原后的节点: ', path + '')            console.log('==============================');        }    }})// ASCII 码还原
  2. traverse(ast, {
  3.     StringLiteral(path) {
  4.         if (path.node.extra) {
  5.             console.log('ASCII码替换前: ', path.node.extra);
  6.             path.node.extra.raw = `'${path.node.extra.rawValue}'`
  7.             console.log('ASCII码替换后: ', path.node.extra);
  8.             console.log('============================================================');
  9.         }
  10.     }
  11. })
  12. // 字符串相加
  13. function strConcat(path) {
  14.     for (let i = 0; i <= 2; i++) {
  15.         let node = path.node
  16.         // left 节点为 StringLiteral 类型
  17.         // right 节点为 StringLiteral 类型
  18.         // operator 操作符属性为字符串 +
  19.         if (types.isStringLiteral(node.left) && types.isStringLiteral(node.right) && node.operator === '+') {
  20.             // 例 'e' + 'f'
  21.             console.log('字符串相加前: ', path + '');
  22.             // 例 'e' + 'f'
  23.             let result = path.node.left.value + path.node.right.value;
  24.             // 例: 'e' + 'f'
  25.             // 替换成: 'ef'
  26.             path.replaceWith(types.valueToNode(result));
  27.             console.log('字符串相加后:  ', path + '');
  28.             console.log('============================================================');
  29.         } else {
  30.             // 递归是针对多个字符串相加的
  31.             // 例当前遍历到的节点: 'a' + 'b' + 'c' + 'd'
  32.             // 这个节点在上面是不会处理的
  33.             // path 对象的 traverse 方法是从当前节点继续遍历
  34.             // 传入 strConcat 方法的节点就为:  'a' + 'b' + 'c' + 'd'
  35.             // 调用过后还是会再次进入到 path.traverse 因为还是会有多个字符串相加
  36.             // 上一次传入的节点被处理过了
  37.             // 所以这一次传入的节点代码就为 'ab' + 'c' + 'd'
  38.             // 一直递归到节点为 'abc' + 'd' 就会停止递归
  39.             // 'abc' + 'd' 在 for 循环中会二次处理 (可以试着for循环只遍历一次看看效果
  40.             path.traverse({
  41.                 BinaryExpression(path_) {
  42.                     strConcat(path_)
  43.                 }
  44.             })
  45.         }
  46.     }
  47. }
  48. traverse(ast, {
  49.     BinaryExpression(path) {  // 遍历 BinaryExpression 节点
  50.         strConcat(path)
  51.     }
  52. })
  53. // 花指令
  54. traverse(ast, {
  55.     VariableDeclarator(path){  // 遍历 VariableDeclarator 节点
  56.         if (types.isObjectExpression(path.node.init)){  // init 类型为 ObjectExpression 类型
  57.             let objName = path.node.id.name;  // 获取对应的标识符
  58.             let objBinding = path.scope.getBinding(objName);  // 获取标识符对应的引用
  59.             let objRefer = objBinding.referencePaths;  // 获取标识符引用对应的数组
  60.             let newObj = {}
  61.             // 将给对象属性赋值的所有变量存入 newObj
  62.             for (const refer in objRefer){  // refer 为索引值从 0 开始
  63.                 // objRefer[refer] 为 obj
  64.                 // objRefer[refer].parentPath 为 obj['str']
  65.                 // objRefer[refer].parentPath.parentPath 为 obj['str'] = 'abc'
  66.                 let grandPath = objRefer[refer].parentPath.parentPath;  // 获取该节点的整段代码
  67.                 // 该节点的类型为 AssignmentExpression 类型
  68.                 // 节点中 left 属性的类型为 MemberExpression 类型
  69.                 if (grandPath.isAssignmentExpression() && grandPath.get('left').isMemberExpression()){
  70.                     // obj['str'] 中的 str 字符串
  71.                     let key = grandPath.node.left.property.value;  // 获取 .property.value 的属性,作为新声明对象中的key
  72.                     newObj[key] = grandPath.node.right;  // right为该属性对应的 node 节点,直接存入 newObj 对象即可
  73.                 }
  74.             }
  75.             for (const refer in objRefer.reverse()){
  76.                 let grandPath = objRefer[refer].parentPath;
  77.                 if (grandPath.isVariableDeclarator()){  // 该节点的类型应为 VariableDeclarator
  78.                     // 例: c = obj
  79.                     let identName = grandPath.node.id.name;  // 获取标识符中对应的 name 属性 (例中的 c)
  80.                     // 例:
  81.                     // let d = c['StringLiteral'];
  82.                     // let e = c['BinaryExpression'];
  83.                     // let f = c['funcCallExpression1'](demo, '123');
  84.                     // let g = c['funcCallExpression2'](demo);
  85.                     // let h = c['funcBinaryExpression']('1' + '2');
  86.                     let identBinding = grandPath.scope.getBinding(identName);  // 获取标识符 c 对应的引用
  87.                     // 例:
  88.                     // [c, c, c, c, c]
  89.                     let identRefer = identBinding.referencePaths;  // 获取标识符引用对应的数组
  90.                     // 字符串花指令
  91.                     for (const idenKey in identRefer) {
  92.                         // identRefer[idenKey].parentPath
  93.                         // c['StringLiteral']
  94.                         // c['BinaryExpression']
  95.                         // c['funcCallExpression1']
  96.                         // c['funcCallExpression2']
  97.                         // c['funcBinaryExpression']
  98.                         let key = identRefer[idenKey].parentPath.node.property.value;  // 获取对应的属性值
  99.                         // 获取 newObj[key]  // obj[属性值]
  100.                         // newObj[key] 的属性值为 StringLiteral 或 BinaryExpression 节点
  101.                         // StringLiteral 为字符串 'abc';
  102.                         // BinaryExpression 为二项式 'abc' + 'def';
  103.                         if (types.isStringLiteral(newObj[key]) || types.isBinaryExpression(newObj[key])){  // 还原字符串
  104.                             console.log('花指令字符串替换前: ', identRefer[idenKey].parentPath + '')
  105.                             identRefer[idenKey].parentPath.replaceWith(newObj[key])  // 获取 obj 中对应的 StringLiteral 节点
  106.                             console.log('花指令字符串替换后: ', identRefer[idenKey].parentPath + '')
  107.                             console.log('====================================')
  108.                         }
  109.                     }
  110.                     // 数组翻转,从后向前遍历
  111.                     for (const idenKey in identRefer.reverse()) {
  112.                         // MemberExpression
  113.                         // 为 let d = c['StringLiteral']; 中的 c['StringLiteral']
  114.                         if (identRefer[idenKey].parentPath.isMemberExpression()){
  115.                             // 获取对应调用的属性值 c['StringLiteral'] 中的 'StringLiteral'
  116.                             let key = identRefer[idenKey].parentPath.node.property.value;
  117.                             // 如果 newObj 对应属性值为 FunctionExpression 类型
  118.                             if (types.isFunctionExpression(newObj[key])){
  119.                                 /*
  120.                                 function (){...}
  121.                                  */
  122.                                 // 拿到 return 语句
  123.                                 let retState = newObj[key].body.body[0].argument;
  124.                                 // 二元运算还原
  125.                                 // 例: return a + b
  126.                                 if (types.isBinaryExpression(retState)){
  127.                                     let operator = retState.operator;  // 拿到操作符 例: +
  128.                                     // 拿到参数数组
  129.                                     // c['funcBinaryExpression']('1', '2'); 中的 ['1', '2']
  130.                                     let Arg = identRefer[idenKey].parentPath.parentPath.node.arguments;
  131.                                     console.log('花指令二元替换前:  ', identRefer[idenKey].parentPath.parentPath + '')
  132.                                     // replaceWith 将当前的节点替换
  133.                                     // c['funcBinaryExpression']('1', '2');
  134.                                     // 替换成
  135.                                     // '1' + '2'
  136.                                     identRefer[idenKey].parentPath.parentPath.replaceWith(types.binaryExpression(operator, Arg[0], Arg[1]));
  137.                                     console.log('花指令二元替换后:  ', identRefer[idenKey].parentPath.parentPath + '')
  138.                                     console.log('=========================')
  139.                                 }
  140.                                 // 函数调用还原
  141.                                 // 例: return a(b) / return a()
  142.                                 // 这两个的差别只有调用的参数,一个对应调用的参数为 2, 一个调用对应的参数为 1
  143.                                 // CallExpression
  144.                                 // 例: return a(b)
  145.                                 if (types.isCallExpression(retState)){
  146.                                     // 获取该节点对应的参数
  147.                                     // 例: c['funcCallExpression1'](demo, '123');
  148.                                     // 中的
  149.                                     // demo, '123'
  150.                                     let Arg = identRefer[idenKey].parentPath.parentPath.node.arguments;
  151.                                     console.log('花指令函数调用替换前:  ', identRefer[idenKey].parentPath.parentPath + '')
  152.                                     // c['funcCallExpression'](demo, '123');
  153.                                     // 替换成
  154.                                     // demo('123');
  155.                                     identRefer[idenKey].parentPath.parentPath.replaceWith(types.callExpression(types.identifier(Arg[0].name), Arg.slice(1)));
  156.                                     console.log('花指令函数调用替换后:  ', identRefer[idenKey].parentPath.parentPath + '')
  157.                                     console.log('=========================')
  158.                                 }
  159.                             }
  160.                         }
  161.                     }
  162.                 }
  163.             }
  164.             // path.stop()
  165.         }
  166.     }
  167. })
  168. // 虚假 if
  169. traverse(ast, {
  170.     // IfStatement 为if判断语句
  171.     // ConditionalExpression 为三元表达式
  172.     "IfStatement|ConditionalExpression"(path){
  173.         // 该节点中的判断条件应该为 二元表达式
  174.         // left 节点应该为 StringLiteral 类型
  175.         // right 节点应该为 StringLiteral 类型
  176.         if(path.get('test').isBinaryExpression() && path.get('test.left').isStringLiteral() && path.get('test.right').isStringLiteral()){
  177.             // 取出判断条件中对应的值
  178.             // 例:  if ('a' === 'a') {  console.log("'a' === 'a' true");} else {  console.log("'a' === 'a' false");}
  179.             let operator = path.node.test.operator;  // 取出操作符 例: ===
  180.             let leftString = path.node.test.left.value;  // 左边的字符串 例: 'a'
  181.             let rightString = path.node.test.right.value;  // 右边的字符串 例: === 'a'
  182.             // 生成 eval 可判断的字符串
  183.             let vmRun = `"${leftString}"  ${operator} "${rightString}"`;  // 例: 'a' === 'a'
  184.             let result = eval(vmRun);
  185.             console.log('虚假 if:  ' + (path + '').replaceAll('\n', ''))
  186.             // 取出 if 与 else 中的代码块
  187.             // path.node.consequent.body 为 if(){}else{}; 形式取值
  188.             // path.node.consequent.arguments 为 statement ? true : false; 形式取值
  189.             let ifTrue = path.node.consequent.body || path.node.consequent.arguments;
  190.             let elFalse = path.node.alternate.body || path.node.alternate.arguments;
  191.             // 判断 result 的执行结果,替换对应的代码块 if 或 else
  192.             result ? path.replaceWithMultiple(ifTrue) : path.replaceWithMultiple(elFalse)
  193.         }
  194.     }
  195. })
  196. // 剔除无引用代码
  197. const refObj = {}
  198. traverse(ast, {
  199.     Identifier(path) {
  200.         let name = path.node.name;
  201.         if (!refObj[name]) {
  202.             refObj[name] = '1';
  203.             let binding = path.scope.getBinding(name);
  204.             let refPath = binding && binding.referencePaths;
  205.             if (refPath && refPath.length === 0) {
  206.                 path.parentPath.parentPath.isVariableDeclaration() && (console.log('删除的无用代码:  ', path.parentPath + ''), path.parentPath.remove())
  207.             }
  208.         }
  209.     }
  210. })
  211. // 无引用的对象
  212. traverse(ast, {
  213.     VariableDeclarator(path) {  // 遍历 VariableDeclarator 节点
  214.         if (types.isObjectExpression(path.node.init)) {  // init 类型为 ObjectExpression 类型
  215.             let objName = path.node.id.name;  // 获取对应的标识符
  216.             let objBinding = path.scope.getBinding(objName);  // 获取标识符对应的引用
  217.             let objRefer = objBinding && objBinding.referencePaths;  // 获取标识符引用对应的数组
  218.             let quoteObj = false;
  219.             for (const index in objRefer) {
  220.                 let grandPath = objRefer[index].parentPath.parentPath;
  221.                 if (grandPath.isAssignmentExpression() && grandPath.get('left').isMemberExpression()) {
  222.                     if (grandPath.get('left.object').isIdentifier() && grandPath.node.left.object.name === objName) {
  223.                         console.log(grandPath + '');
  224.                         console.log('==============================')
  225.                     } else {
  226.                         quoteObj = true
  227.                     }
  228.                 }
  229.             }
  230.             if (!quoteObj) {
  231.                 for (const index in objRefer) {
  232.                     let grandPath = objRefer[index].parentPath.parentPath;
  233.                     grandPath.remove();
  234.                 }
  235.             }
  236.         }
  237.     }
  238. })
  239. // 数值还原
  240. traverse(ast, {
  241.     NumericLiteral(path){
  242.         console.log('替换前: ', path.node.extra);
  243.         delete path.node.extra.raw;
  244.         console.log('替换后: ', path.node.extra);
  245.         console.log('==============================');
  246.     }
  247. })
  248. // 还原 switchtraverse(ast, {    WhileStatement(path){        if (path.node.test.prefix && path.get('body').isBlockStatement() && types.isSwitchStatement(path.node.body.body[0])){            // 获取同级节点            let sibling = path.getSibling(1)            let whileIdx = (sibling.node.declarations[0].init.callee.object.value).split('|')            let idxObj = {}            let caseIdx = path.node.body.body[0].cases;            for (const index in caseIdx){                let key = caseIdx[index].test.value;                idxObj[key] = caseIdx[index].consequent[0];            }            let newArray = []            for (const index in whileIdx){                newArray.push(idxObj[whileIdx[index]])            }            path.replaceWithMultiple(newArray);            // 删除同级节点            while(path.key--){                console.log('还原switch删除的节点:  ', path.getSibling(path.key) + '');                path.getSibling(path.key).remove();            }        }    }})///js_code = generator(ast, {    compact: false,  // 是否压缩,默认 false}).code  // 将ast节点转换成js代码// 写入(路径记得改)fs.writeFileSync('New_demo.js', js_code, {    encoding: 'utf-8',})
复制代码
  还原前的代码量

    还原后的代码量

  注意

   转换好的代码直接放欣赏器上会卡死,由于有格式化检测
    方法1: 在编译成 js 代码时开启压缩 compact: true
  1. js_code = generator(ast, {
  2.     compact: true,  // 是否压缩,默认 false
  3. }).code  // 将ast节点转换成js代码
复制代码
  方法2: 全局搜索 test,将格式化检测的位置全部改成 true

    AST转换后的代码还是会有debugger
这里是生成 debugger 的位置 $dbsm_0x36da24 函数时生成 debugger 的

将 debugger 字符串删除即可

  还原加密

   将处理好的代码更换到 2.html 文件中
在 document[‘cookie’] 处打上断点

革新页面开始调试

检察上一层堆栈
传进来的 _0x29c654 参数是 Date[“parse”](new Date()); 生成的

回到加密点 _0x2fdc55() 方法返回空字符串(不消管)

    _0x691b6d() 方法返回的是加密值, 所以只要扣这个方法就可以了

点击 vm 进入这个方法


由于 _0x4a2ede, _0x47e4dd 永久都是undefined,所以 return 可以改写成

结果是一样的

再接着往上 缺啥补啥就可以了
    补完运行时会报 qz is not defined(这是一个条件判断)

欣赏器中的 qz 是一个 大数组 是执行 setInterval 后生成的 所以只要将 if 代码块中的代码放出来就可以了

  扣完以后校验一下是否准确即可

请求代码

   python
  1. import requests
  2. import execjs
  3. import time
  4. def call_js(file_name, func_name, *args):
  5.     with open(file_name, mode='r', encoding='utf-8') as f:
  6.         js_code = execjs.compile(f.read())
  7.     return js_code.call(func_name, *args)
  8. headers = {
  9.     "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
  10. }
  11. cookies = {
  12.     "sessionid": "你的sessionid"
  13. }
  14. def get_data(page):
  15.     url = "https://match.yuanrenxue.cn/api/match/2"
  16.     time_ = int(str(int(time.time() * 1000))[:10] + '000')
  17.     cookies['m'] = f"{call_js('2.js', '_0x691b6d', time_)}|{time_}"
  18.     print(cookies)
  19.     params = {
  20.         "page": f'{page}'
  21.     }
  22.     response = requests.get(url, headers=headers, cookies=cookies, params=params)
  23.     print(response.json())
  24. if __name__ == '__main__':
  25.     get_data(1)
复制代码
  javascript
  1. function _0x691b6d(_0x2de515, _0x4a2ede, _0x47e4dd) {
  2.     return _0x396668(_0x2de515);
  3. }
  4. function _0x396668(_0xa25649) {
  5.     return _0xef0b5b(_0x2985eb(_0xa25649));
  6. }
  7. function _0x2985eb(_0x2f966f) {
  8.     return _0x513ef6(_0x130879(_0x2f966f));
  9. }
  10. function _0x130879(_0x1b540c) {
  11.     var _0x553c57 = {};
  12.     return unescape(encodeURIComponent(_0x1b540c));
  13. }
  14. function _0x513ef6(_0x2957b6) {
  15.     var _0x4c198e = {};
  16.     return _0x1fd78f(_0x1e5972(_0x32960f(_0x2957b6), 8 * _0x2957b6["length"]));
  17. }
  18. function _0xef0b5b(_0x10bf06) {
  19.     var _0x2c2190,
  20.         _0x20ca0c,
  21.         _0x18d0e1 = "0123456789abcdef",
  22.         _0xedd57d = '';
  23.     for (_0x20ca0c = 0; _0x20ca0c < _0x10bf06["length"]; _0x20ca0c += 1) _0x2c2190 = _0x10bf06["charCodeAt"](_0x20ca0c), _0xedd57d += _0x18d0e1["charAt"](_0x2c2190 >>> 4 & 15) + _0x18d0e1["charAt"](15 & _0x2c2190);
  24.     return _0xedd57d;
  25. }
  26. function _0x1e5972(_0x132f3d, _0x23ca08) {
  27.     var _0x323bcd = {};
  28.     _0x132f3d[_0x23ca08 >> 5] |= 128 << _0x23ca08 % 32, _0x132f3d[14 + (_0x23ca08 + 64 >>> 9 << 4)] = _0x23ca08;
  29.     var _0x1ee0c6,
  30.         _0x1e8f34,
  31.         _0x429ecb,
  32.         _0x5c3723,
  33.         _0xde6a8e,
  34.         _0x4f8eee = 1732584193,
  35.         _0x12b681 = -271733879,
  36.         _0x34e741 = -1732584194,
  37.         _0x4aa794 = 271733878;
  38.     for (_0x1ee0c6 = 0; _0x1ee0c6 < _0x132f3d["length"]; _0x1ee0c6 += 16) _0x1e8f34 = _0x4f8eee, _0x429ecb = _0x12b681, _0x5c3723 = _0x34e741, _0xde6a8e = _0x4aa794, _0x4f8eee = _0x5655af(_0x4f8eee, _0x12b681, _0x34e741, _0x4aa794, _0x132f3d[_0x1ee0c6], 7, -680876936), _0x4aa794 = _0x5655af(_0x4aa794, _0x4f8eee, _0x12b681, _0x34e741, _0x132f3d[_0x1ee0c6 + 1], 12, -389564586), _0x34e741 = _0x5655af(_0x34e741, _0x4aa794, _0x4f8eee, _0x12b681, _0x132f3d[_0x1ee0c6 + 2], 17, 606105819), _0x12b681 = _0x5655af(_0x12b681, _0x34e741, _0x4aa794, _0x4f8eee, _0x132f3d[_0x1ee0c6 + 3], 22, -1044525330), _0x4f8eee = _0x5655af(_0x4f8eee, _0x12b681, _0x34e741, _0x4aa794, _0x132f3d[_0x1ee0c6 + 4], 7, -176418897), _0x4aa794 = _0x5655af(_0x4aa794, _0x4f8eee, _0x12b681, _0x34e741, _0x132f3d[_0x1ee0c6 + 5], 12, 1200080426), _0x34e741 = _0x5655af(_0x34e741, _0x4aa794, _0x4f8eee, _0x12b681, _0x132f3d[_0x1ee0c6 + 6], 17, -1473231341), _0x12b681 = _0x5655af(_0x12b681, _0x34e741, _0x4aa794, _0x4f8eee, _0x132f3d[_0x1ee0c6 + 7], 22, -45705983), _0x4f8eee = _0x5655af(_0x4f8eee, _0x12b681, _0x34e741, _0x4aa794, _0x132f3d[_0x1ee0c6 + 8], 7, 1770010416), _0x4aa794 = _0x5655af(_0x4aa794, _0x4f8eee, _0x12b681, _0x34e741, _0x132f3d[_0x1ee0c6 + 9], 12, -1958414417), _0x34e741 = _0x5655af(_0x34e741, _0x4aa794, _0x4f8eee, _0x12b681, _0x132f3d[_0x1ee0c6 + 10], 17, -42063), _0x12b681 = _0x5655af(_0x12b681, _0x34e741, _0x4aa794, _0x4f8eee, _0x132f3d[_0x1ee0c6 + 11], 22, -1990404162), _0x4f8eee = _0x5655af(_0x4f8eee, _0x12b681, _0x34e741, _0x4aa794, _0x132f3d[_0x1ee0c6 + 12], 7, 1804603682), _0x4aa794 = _0x5655af(_0x4aa794, _0x4f8eee, _0x12b681, _0x34e741, _0x132f3d[_0x1ee0c6 + 13], 12, -40341101), _0x34e741 = _0x5655af(_0x34e741, _0x4aa794, _0x4f8eee, _0x12b681, _0x132f3d[_0x1ee0c6 + 14], 17, -1502882290), _0x12b681 = _0x5655af(_0x12b681, _0x34e741, _0x4aa794, _0x4f8eee, _0x132f3d[_0x1ee0c6 + 15], 22, 1236535329), _0x4f8eee = _0xafe18(_0x4f8eee, _0x12b681, _0x34e741, _0x4aa794, _0x132f3d[_0x1ee0c6 + 1], 5, -165796510), _0x4aa794 = _0xafe18(_0x4aa794, _0x4f8eee, _0x12b681, _0x34e741, _0x132f3d[_0x1ee0c6 + 6], 9, -1069501632), _0x34e741 = _0xafe18(_0x34e741, _0x4aa794, _0x4f8eee, _0x12b681, _0x132f3d[_0x1ee0c6 + 11], 14, 643717713), _0x12b681 = _0xafe18(_0x12b681, _0x34e741, _0x4aa794, _0x4f8eee, _0x132f3d[_0x1ee0c6], 20, -373897302), _0x4f8eee = _0xafe18(_0x4f8eee, _0x12b681, _0x34e741, _0x4aa794, _0x132f3d[_0x1ee0c6 + 5], 5, -701558691), _0x4aa794 = _0xafe18(_0x4aa794, _0x4f8eee, _0x12b681, _0x34e741, _0x132f3d[_0x1ee0c6 + 10], 9, 38016083), _0x34e741 = _0xafe18(_0x34e741, _0x4aa794, _0x4f8eee, _0x12b681, _0x132f3d[_0x1ee0c6 + 15], 14, -660478335), _0x12b681 = _0xafe18(_0x12b681, _0x34e741, _0x4aa794, _0x4f8eee, _0x132f3d[_0x1ee0c6 + 4], 20, -405537848), _0x4f8eee = _0xafe18(_0x4f8eee, _0x12b681, _0x34e741, _0x4aa794, _0x132f3d[_0x1ee0c6 + 9], 5, 568446438), _0x4aa794 = _0xafe18(_0x4aa794, _0x4f8eee, _0x12b681, _0x34e741, _0x132f3d[_0x1ee0c6 + 14], 9, -1019803690), _0x34e741 = _0xafe18(_0x34e741, _0x4aa794, _0x4f8eee, _0x12b681, _0x132f3d[_0x1ee0c6 + 3], 14, -187363961), _0x12b681 = _0xafe18(_0x12b681, _0x34e741, _0x4aa794, _0x4f8eee, _0x132f3d[_0x1ee0c6 + 8], 20, 1163531501), _0x4f8eee = _0xafe18(_0x4f8eee, _0x12b681, _0x34e741, _0x4aa794, _0x132f3d[_0x1ee0c6 + 13], 5, -1444681467), _0x4aa794 = _0xafe18(_0x4aa794, _0x4f8eee, _0x12b681, _0x34e741, _0x132f3d[_0x1ee0c6 + 2], 9, -51403784), _0x34e741 = _0xafe18(_0x34e741, _0x4aa794, _0x4f8eee, _0x12b681, _0x132f3d[_0x1ee0c6 + 7], 14, 1735328473), _0x12b681 = _0xafe18(_0x12b681, _0x34e741, _0x4aa794, _0x4f8eee, _0x132f3d[_0x1ee0c6 + 12], 20, -1926607734), _0x4f8eee = _0x57cdb6(_0x4f8eee, _0x12b681, _0x34e741, _0x4aa794, _0x132f3d[_0x1ee0c6 + 5], 4, -378558), _0x4aa794 = _0x57cdb6(_0x4aa794, _0x4f8eee, _0x12b681, _0x34e741, _0x132f3d[_0x1ee0c6 + 8], 11, -2022574463), _0x34e741 = _0x57cdb6(_0x34e741, _0x4aa794, _0x4f8eee, _0x12b681, _0x132f3d[_0x1ee0c6 + 11], 16, 1839030562), _0x12b681 = _0x57cdb6(_0x12b681, _0x34e741, _0x4aa794, _0x4f8eee, _0x132f3d[_0x1ee0c6 + 14], 23, -35309556), _0x4f8eee = _0x57cdb6(_0x4f8eee, _0x12b681, _0x34e741, _0x4aa794, _0x132f3d[_0x1ee0c6 + 1], 4, -1530992060), _0x4aa794 = _0x57cdb6(_0x4aa794, _0x4f8eee, _0x12b681, _0x34e741, _0x132f3d[_0x1ee0c6 + 4], 11, 1272893353), _0x34e741 = _0x57cdb6(_0x34e741, _0x4aa794, _0x4f8eee, _0x12b681, _0x132f3d[_0x1ee0c6 + 7], 16, -155497632), _0x12b681 = _0x57cdb6(_0x12b681, _0x34e741, _0x4aa794, _0x4f8eee, _0x132f3d[_0x1ee0c6 + 10], 23, -1094730640), _0x4f8eee = _0x57cdb6(_0x4f8eee, _0x12b681, _0x34e741, _0x4aa794, _0x132f3d[_0x1ee0c6 + 13], 4, 681279174), _0x4aa794 = _0x57cdb6(_0x4aa794, _0x4f8eee, _0x12b681, _0x34e741, _0x132f3d[_0x1ee0c6], 11, -358537222), _0x34e741 = _0x57cdb6(_0x34e741, _0x4aa794, _0x4f8eee, _0x12b681, _0x132f3d[_0x1ee0c6 + 3], 16, -722521979), _0x12b681 = _0x57cdb6(_0x12b681, _0x34e741, _0x4aa794, _0x4f8eee, _0x132f3d[_0x1ee0c6 + 6], 23, 76029189), _0x4f8eee = _0x57cdb6(_0x4f8eee, _0x12b681, _0x34e741, _0x4aa794, _0x132f3d[_0x1ee0c6 + 9], 4, -640364487), _0x4aa794 = _0x57cdb6(_0x4aa794, _0x4f8eee, _0x12b681, _0x34e741, _0x132f3d[_0x1ee0c6 + 12], 11, -421815835), _0x34e741 = _0x57cdb6(_0x34e741, _0x4aa794, _0x4f8eee, _0x12b681, _0x132f3d[_0x1ee0c6 + 15], 16, 530742520), _0x12b681 = _0x57cdb6(_0x12b681, _0x34e741, _0x4aa794, _0x4f8eee, _0x132f3d[_0x1ee0c6 + 2], 23, -995338651), _0x4f8eee = _0x2ba84c(_0x4f8eee, _0x12b681, _0x34e741, _0x4aa794, _0x132f3d[_0x1ee0c6], 6, -198630844), _0x4aa794 = _0x2ba84c(_0x4aa794, _0x4f8eee, _0x12b681, _0x34e741, _0x132f3d[_0x1ee0c6 + 7], 10, 1126891415), _0x34e741 = _0x2ba84c(_0x34e741, _0x4aa794, _0x4f8eee, _0x12b681, _0x132f3d[_0x1ee0c6 + 14], 15, -1416354905), _0x12b681 = _0x2ba84c(_0x12b681, _0x34e741, _0x4aa794, _0x4f8eee, _0x132f3d[_0x1ee0c6 + 5], 21, -57434055), _0x4f8eee = _0x2ba84c(_0x4f8eee, _0x12b681, _0x34e741, _0x4aa794, _0x132f3d[_0x1ee0c6 + 12], 6, 1700485571), _0x4aa794 = _0x2ba84c(_0x4aa794, _0x4f8eee, _0x12b681, _0x34e741, _0x132f3d[_0x1ee0c6 + 3], 10, -1894986606), _0x34e741 = _0x2ba84c(_0x34e741, _0x4aa794, _0x4f8eee, _0x12b681, _0x132f3d[_0x1ee0c6 + 10], 15, -1051523), _0x12b681 = _0x2ba84c(_0x12b681, _0x34e741, _0x4aa794, _0x4f8eee, _0x132f3d[_0x1ee0c6 + 1], 21, -2054922799), _0x4f8eee = _0x2ba84c(_0x4f8eee, _0x12b681, _0x34e741, _0x4aa794, _0x132f3d[_0x1ee0c6 + 8], 6, 1873313359), _0x4aa794 = _0x2ba84c(_0x4aa794, _0x4f8eee, _0x12b681, _0x34e741, _0x132f3d[_0x1ee0c6 + 15], 10, -30611744), _0x34e741 = _0x2ba84c(_0x34e741, _0x4aa794, _0x4f8eee, _0x12b681, _0x132f3d[_0x1ee0c6 + 6], 15, -1560198380), _0x12b681 = _0x2ba84c(_0x12b681, _0x34e741, _0x4aa794, _0x4f8eee, _0x132f3d[_0x1ee0c6 + 13], 21, 1309151649), _0x4f8eee = _0x2ba84c(_0x4f8eee, _0x12b681, _0x34e741, _0x4aa794, _0x132f3d[_0x1ee0c6 + 4], 6, -145523070), _0x4aa794 = _0x2ba84c(_0x4aa794, _0x4f8eee, _0x12b681, _0x34e741, _0x132f3d[_0x1ee0c6 + 11], 10, -1120210379), _0x34e741 = _0x2ba84c(_0x34e741, _0x4aa794, _0x4f8eee, _0x12b681, _0x132f3d[_0x1ee0c6 + 2], 15, 718787259), _0x12b681 = _0x2ba84c(_0x12b681, _0x34e741, _0x4aa794, _0x4f8eee, _0x132f3d[_0x1ee0c6 + 9], 21, -343485441), _0x4f8eee = _0x564a36(_0x4f8eee, _0x1e8f34), _0x12b681 = _0x564a36(_0x12b681, _0x429ecb), _0x34e741 = _0x564a36(_0x34e741, _0x5c3723), _0x4aa794 = _0x564a36(_0x4aa794, _0xde6a8e);
  39.     return [_0x4f8eee, _0x12b681, _0x34e741, _0x4aa794];
  40. }
  41. function _0xafe18(_0x59972b, _0x357d2b, _0x37f1e6, _0x40c0ec, _0x457a54, _0x27a208, _0x1291f9) {
  42.     return _0x93484(_0x357d2b & _0x40c0ec | _0x37f1e6 & ~_0x40c0ec, _0x59972b, _0x357d2b, _0x457a54, _0x27a208, _0x1291f9);
  43. }
  44. function _0x2ba84c(_0x25c369, _0x2fa4cf, _0x10bc95, _0x133659, _0x3e51d8, _0x4a9786, _0x5ad3d9) {
  45.     return _0x93484(_0x10bc95 ^ (_0x2fa4cf | ~_0x133659), _0x25c369, _0x2fa4cf, _0x3e51d8, _0x4a9786, _0x5ad3d9);
  46. }
  47. function _0x57cdb6(_0x24e055, _0x43d7e3, _0x11af5a, _0xde9c8, _0x3f9877, _0x3e6fd3, _0x45d799) {
  48.     return _0x93484(_0x43d7e3 ^ _0x11af5a ^ _0xde9c8, _0x24e055, _0x43d7e3, _0x3f9877, _0x3e6fd3, _0x45d799);
  49. }
  50. function _0x3243aa(_0xdd939c, _0x39e4e0) {
  51.     return _0xdd939c << _0x39e4e0 | _0xdd939c >>> 32 - _0x39e4e0;
  52. }
  53. function _0x564a36(_0x3c4e40, _0x45890c) {
  54.     var _0x1e7f33 = {};
  55.     var _0x474c37 = (65535 & _0x3c4e40) + (65535 & _0x45890c);
  56.     return (_0x3c4e40 >> 16) + (_0x45890c >> 16) + (_0x474c37 >> 16) << 16 | 65535 & _0x474c37;
  57. }
  58. function _0x93484(_0x1f657e, _0x172cfb, _0x14882e, _0x31dde3, _0x16e397, _0x330a90) {
  59.     return _0x564a36(_0x3243aa(_0x564a36(_0x564a36(_0x172cfb, _0x1f657e), _0x564a36(_0x31dde3, _0x330a90)), _0x16e397), _0x14882e);
  60. }
  61. function _0x5655af(_0x5ec922, _0x49f6b4, _0x357fa0, _0x1558be, _0x3b2d74, _0x5bb480, _0x36aa69) {
  62.     return _0x93484(_0x49f6b4 & _0x357fa0 | ~_0x49f6b4 & _0x1558be, _0x5ec922, _0x49f6b4, _0x3b2d74, _0x5bb480, _0x36aa69);
  63. }
  64. function _0x32960f(_0x2752b7) {
  65.     var _0x1e1be5,
  66.         _0x5928bd = [];
  67.     for (_0x5928bd[(_0x2752b7["length"] >> 2) - 1] = void 0, _0x1e1be5 = 0; _0x1e1be5 < _0x5928bd["length"]; _0x1e1be5 += 1) _0x5928bd[_0x1e1be5] = 0;
  68.     var _0x2e5130 = 8 * _0x2752b7["length"];
  69.     for (_0x1e1be5 = 0; _0x1e1be5 < _0x2e5130; _0x1e1be5 += 8) _0x5928bd[_0x1e1be5 >> 5] |= (255 & _0x2752b7["charCodeAt"](_0x1e1be5 / 8)) << _0x1e1be5 % 32;
  70.     return _0x5928bd;
  71. }
  72. function _0x1fd78f(_0x461924) {
  73.     var _0x51955d,
  74.         _0x47ef66 = '',
  75.         _0x264aa7 = 32 * _0x461924["length"];
  76.     for (_0x51955d = 0; _0x51955d < _0x264aa7; _0x51955d += 8) _0x47ef66 += String["fromCharCode"](_0x461924[_0x51955d >> 5] >>> _0x51955d % 32 & 255);
  77.     return _0x47ef66;
  78. }
  79. // console.log(_0x691b6d(1723380724000));
  80. // '75bcb82b08198abbec49a4248c6aae02|1723380724000'
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

一给

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表