调试干扰
进入标题正常加载数据后
打开调试工具,等待一会(2~3分钟) 革新页面 cookie 失效以后会弹窗
删除 cookie 中的 m 字段再革新页面也是一样的
点击确定后,页面主动革新完会进入 无限 debugger
检察上一层堆栈
生成 debugger 的代码 是经过混淆的
手动解混淆后的代码
- (function () {
- // function 中的代码并不会执行,debugger主要是靠 ['constructor'](('debugger'))['call']('action') 执行
- }['constructor'](('debugger'))['call']('action'))
- // function(){}['constructor'] 是 Function
- // 上面的代码也也可以写成
- Function.prototype.constructor('debugger')()
复制代码
Hook Function
这个 debugger 是靠 Function 的构造器生成的
Hook Function.prototype.constructor 就可以过掉这个 debugger
- let _Function = Function.prototype.constructor;
- Function.prototype.constructor = function(Value){
- if (Value.indexOf('debugger') !== -1){
- return _Function.call(this, '')
- }
- return _Function.call(this, Value)
- };
复制代码 将代码在控制台运行就可以正常调试了
加密参数定位
数据接口在 https://match.yuanrenxue.cn/api/match 里
对应的请求参数为 page(页码)
加密参数在 cookie m字段
hook Cookie
删除cookie中对应的 m 字段
hook cookie 找到 m字段加密的位置(加上 hook Function 的代码)
- // Hook Functionlet _Function = Function.prototype.constructor;
- Function.prototype.constructor = function(Value){
- if (Value.indexOf('debugger') !== -1){
- return _Function.call(this, '')
- }
- return _Function.call(this, Value)
- };
- // 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 到本地
字符串解密
先看看混淆代码
- 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']);
- location['\x72\x65\x6c' + $dbsm_0x4638('\x30\x78\x31\x31\x63', '\x6e\x34\x54\x28')]();
- // 解混淆后
- document['cookie'] = (((((('m' + (_0x2fdc55())) + '=') + _0x691b6d(_0x29c654)) + '|') + _0x29c654) + '; path=/');
- 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 是解密函数
- // 安装 babel 库: npm install @babel/core
- const 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'})) {
- console.log('遍历到的节点: ', path + '')
- // 取出对应的参数
- // 例: $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"
- path.replaceWith(types.valueToNode(result));
- console.log('替换后的节点: ', path + '')
- console.log('==============================');
- }
- }
- })
- ///
- js_code = generator(ast).code // 将ast节点转换成js代码
- // 写入(路径记得改)
- fs.writeFileSync('New_demo.js', js_code, {
- encoding: 'utf-8'
- })
复制代码 剖析前的代码

剖析后的代码

ASCII 编码字符串还原
还原思路在 1. js混淆-源码乱码 中有提到
- // ASCII 码还原
- traverse(ast, {
- StringLiteral(path) {
- if (path.node.extra) {
- console.log('ASCII码替换前: ', path.node.extra);
- path.node.extra.raw = `'${path.node.extra.rawValue}'`
- console.log('ASCII码替换后: ', path.node.extra);
- console.log('============================================================');
- }
- }
- })
复制代码 效果
字符串相加
demo.js
- 'a' + 'b' + 'c' + 'd';
- 'e' + 'f';
复制代码 AST.js
- // 字符串相加
- function strConcat(path) {
- for (let i = 0; i <= 2; i++) {
- let node = path.node
- // left 节点为 StringLiteral 类型
- // right 节点为 StringLiteral 类型
- // operator 操作符属性为字符串 +
- if (types.isStringLiteral(node.left) && types.isStringLiteral(node.right) && node.operator === '+') {
- // 例 'e' + 'f'
- console.log('字符串相加前: ', path + '');
- // 例 'e' + 'f'
- let result = path.node.left.value + path.node.right.value;
- // 例: 'e' + 'f'
- // 替换成: 'ef'
- path.replaceWith(types.valueToNode(result));
- console.log('字符串相加后: ', path + '');
- console.log('============================================================');
- } else {
- // 递归是针对多个字符串相加的
- // 例当前遍历到的节点: 'a' + 'b' + 'c' + 'd'
- // 这个节点在上面是不会处理的
- // path 对象的 traverse 方法是从当前节点继续遍历
- // 传入 strConcat 方法的节点就为: 'a' + 'b' + 'c' + 'd'
- // 调用过后还是会再次进入到 path.traverse 因为还是会有多个字符串相加
- // 上一次传入的节点被处理过了
- // 所以这一次传入的节点代码就为 'ab' + 'c' + 'd'
- // 一直递归到节点为 'abc' + 'd' 就会停止递归
- // 'abc' + 'd' 在 for 循环中会二次处理 (可以试着for循环只遍历一次看看效果
- path.traverse({
- BinaryExpression(path_) {
- strConcat(path_)
- }
- })
- }
- }
- }
- traverse(ast, {
- BinaryExpression(path) { // 遍历 BinaryExpression 节点
- strConcat(path)
- }
- })
复制代码 效果

花指令(对象)
demo.js
- let obj = {};
- obj['StringLiteral'] = 'abc';
- obj['BinaryExpression'] = 'abc' + 'def';
- obj['funcCallExpression1'] = function (a, b){
- return a(b);
- }
- obj['funcCallExpression2'] = function (a){
- return a();
- }
- obj['funcBinaryExpression'] = function(a, b){
- return a + b
- }
- let c = obj;
- let d = c['StringLiteral'];
- let e = c['BinaryExpression'];
- function demo(){}
- let f = c['funcCallExpression1'](demo, '123');
- let g = c['funcCallExpression2'](demo);
- let h = c['funcBinaryExpression']('1', '2');
复制代码 AST.js
- // 花指令
- traverse(ast, {
- VariableDeclarator(path){ // 遍历 VariableDeclarator 节点
- if (types.isObjectExpression(path.node.init)){ // init 类型为 ObjectExpression 类型
- let objName = path.node.id.name; // 获取对应的标识符
- let objBinding = path.scope.getBinding(objName); // 获取标识符对应的引用
- let objRefer = objBinding.referencePaths; // 获取标识符引用对应的数组
- let newObj = {}
- // 将给对象属性赋值的所有变量存入 newObj
- for (const refer in objRefer){ // refer 为索引值从 0 开始
- // objRefer[refer] 为 obj
- // objRefer[refer].parentPath 为 obj['str']
- // objRefer[refer].parentPath.parentPath 为 obj['str'] = 'abc'
- let grandPath = objRefer[refer].parentPath.parentPath; // 获取该节点的整段代码
- // 该节点的类型为 AssignmentExpression 类型
- // 节点中 left 属性的类型为 MemberExpression 类型
- if (grandPath.isAssignmentExpression() && grandPath.get('left').isMemberExpression()){
- // obj['str'] 中的 str 字符串
- let key = grandPath.node.left.property.value; // 获取 .property.value 的属性,作为新声明对象中的key
- newObj[key] = grandPath.node.right; // right为该属性对应的 node 节点,直接存入 newObj 对象即可
- }
- }
- for (const refer in objRefer.reverse()){
- let grandPath = objRefer[refer].parentPath;
- if (grandPath.isVariableDeclarator()){ // 该节点的类型应为 VariableDeclarator
- // 例: c = obj
- let identName = grandPath.node.id.name; // 获取标识符中对应的 name 属性 (例中的 c)
- // 例:
- // let d = c['StringLiteral'];
- // let e = c['BinaryExpression'];
- // let f = c['funcCallExpression1'](demo, '123');
- // let g = c['funcCallExpression2'](demo);
- // let h = c['funcBinaryExpression']('1' + '2');
- let identBinding = grandPath.scope.getBinding(identName); // 获取标识符 c 对应的引用
- // 例:
- // [c, c, c, c, c]
- let identRefer = identBinding.referencePaths; // 获取标识符引用对应的数组
- // 字符串花指令
- for (const idenKey in identRefer) {
- // identRefer[idenKey].parentPath
- // c['StringLiteral']
- // c['BinaryExpression']
- // c['funcCallExpression1']
- // c['funcCallExpression2']
- // c['funcBinaryExpression']
- let key = identRefer[idenKey].parentPath.node.property.value; // 获取对应的属性值
- // 获取 newObj[key] // obj[属性值]
- // newObj[key] 的属性值为 StringLiteral 或 BinaryExpression 节点
- // StringLiteral 为字符串 'abc';
- // BinaryExpression 为二项式 'abc' + 'def';
- if (types.isStringLiteral(newObj[key]) || types.isBinaryExpression(newObj[key])){ // 还原字符串
- console.log('花指令字符串替换前: ', identRefer[idenKey].parentPath + '')
- identRefer[idenKey].parentPath.replaceWith(newObj[key]) // 获取 obj 中对应的 StringLiteral 节点
- console.log('花指令字符串替换后: ', identRefer[idenKey].parentPath + '')
- console.log('====================================')
- }
- }
- // 数组翻转,从后向前遍历
- for (const idenKey in identRefer.reverse()) {
- // MemberExpression
- // 为 let d = c['StringLiteral']; 中的 c['StringLiteral']
- if (identRefer[idenKey].parentPath.isMemberExpression()){
- // 获取对应调用的属性值 c['StringLiteral'] 中的 'StringLiteral'
- let key = identRefer[idenKey].parentPath.node.property.value;
- // 如果 newObj 对应属性值为 FunctionExpression 类型
- if (types.isFunctionExpression(newObj[key])){
- /*
- function (){...}
- */
- // 拿到 return 语句
- let retState = newObj[key].body.body[0].argument;
- // 二元运算还原
- // 例: return a + b
- if (types.isBinaryExpression(retState)){
- let operator = retState.operator; // 拿到操作符 例: +
- // 拿到参数数组
- // c['funcBinaryExpression']('1', '2'); 中的 ['1', '2']
- let Arg = identRefer[idenKey].parentPath.parentPath.node.arguments;
- console.log('花指令二元替换前: ', identRefer[idenKey].parentPath.parentPath + '')
- // replaceWith 将当前的节点替换
- // c['funcBinaryExpression']('1', '2');
- // 替换成
- // '1' + '2'
- identRefer[idenKey].parentPath.parentPath.replaceWith(types.binaryExpression(operator, Arg[0], Arg[1]));
- console.log('花指令二元替换后: ', identRefer[idenKey].parentPath.parentPath + '')
- console.log('=========================')
- }
- // 函数调用还原
- // 例: return a(b) / return a()
- // 这两个的差别只有调用的参数,一个对应调用的参数为 2, 一个调用对应的参数为 1
- // CallExpression
- // 例: return a(b)
- if (types.isCallExpression(retState)){
- // 获取该节点对应的参数
- // 例: c['funcCallExpression1'](demo, '123');
- // 中的
- // demo, '123'
- let Arg = identRefer[idenKey].parentPath.parentPath.node.arguments;
- console.log('花指令函数调用替换前: ', identRefer[idenKey].parentPath.parentPath + '')
- // c['funcCallExpression'](demo, '123');
- // 替换成
- // demo('123');
- identRefer[idenKey].parentPath.parentPath.replaceWith(types.callExpression(types.identifier(Arg[0].name), Arg.slice(1)));
- console.log('花指令函数调用替换后: ', identRefer[idenKey].parentPath.parentPath + '')
- console.log('=========================')
- }
- }
- }
- }
- }
- }
- // path.stop()
- }
- }
- })
复制代码 还原前

还原后

剔除无用代码
虚假 if
demo.js
- if ('a' === 'a'){
- console.log("'a' === 'a' true");
- }else{
- console.log("'a' === 'a' false");
- }
- if ('a' !== 'a'){
- console.log("'a' !== 'a' true");
- }else{
- console.log("'a' !== 'a' false");
- }
- 'a' === 'a' ? console.log("'a' === 'a' true") : console.log("'a' === 'a' false")
- 'a' !== 'a' ? console.log("'a' !== 'a' true") : console.log("'a' !== 'a' false")
复制代码 AST.js
- // 虚假 if
- traverse(ast, {
- // IfStatement 为if判断语句
- // ConditionalExpression 为三元表达式
- "IfStatement|ConditionalExpression"(path){
- // 该节点中的判断条件应该为 二元表达式
- // left 节点应该为 StringLiteral 类型
- // right 节点应该为 StringLiteral 类型
- if(path.get('test').isBinaryExpression() && path.get('test.left').isStringLiteral() && path.get('test.right').isStringLiteral()){
- // 取出判断条件中对应的值
- // 例: if ('a' === 'a') { console.log("'a' === 'a' true");} else { console.log("'a' === 'a' false");}
- let operator = path.node.test.operator; // 取出操作符 例: ===
- let leftString = path.node.test.left.value; // 左边的字符串 例: 'a'
- let rightString = path.node.test.right.value; // 右边的字符串 例: === 'a'
- // 生成 eval 可判断的字符串
- let vmRun = `"${leftString}" ${operator} "${rightString}"`; // 例: 'a' === 'a'
- let result = eval(vmRun);
- console.log('虚假 if: ' + (path + '').replaceAll('\n', ''))
- // 取出 if 与 else 中的代码块
- // path.node.consequent.body 为 if(){}else{}; 形式取值
- // path.node.consequent.arguments 为 statement ? true : false; 形式取值
- let ifTrue = path.node.consequent.body || path.node.consequent.arguments;
- let elFalse = path.node.alternate.body || path.node.alternate.arguments;
- // 判断 result 的执行结果,替换对应的代码块 if 或 else
- result ? path.replaceWithMultiple(ifTrue) : path.replaceWithMultiple(elFalse)
- }
- }
- })
复制代码 剔除无引用代码
- // 剔除无引用代码
- const refObj = {}
- traverse(ast, {
- Identifier(path) {
- let name = path.node.name;
- if (!refObj[name]) {
- refObj[name] = '1';
- let binding = path.scope.getBinding(name);
- let refPath = binding && binding.referencePaths;
- if (refPath && refPath.length === 0) {
- path.parentPath.parentPath.isVariableDeclaration() && (console.log('删除的无用代码: ', path.parentPath + ''), path.parentPath.remove())
- }
- }
- }
- })
复制代码 剔除无引用的对象
- // 无引用的对象
- traverse(ast, {
- VariableDeclarator(path) { // 遍历 VariableDeclarator 节点
- if (types.isObjectExpression(path.node.init)) { // init 类型为 ObjectExpression 类型
- let objName = path.node.id.name; // 获取对应的标识符
- let objBinding = path.scope.getBinding(objName); // 获取标识符对应的引用
- let objRefer = objBinding && objBinding.referencePaths; // 获取标识符引用对应的数组
- let quoteObj = false;
- for (const index in objRefer) {
- let grandPath = objRefer[index].parentPath.parentPath;
- if (grandPath.isAssignmentExpression() && grandPath.get('left').isMemberExpression()) {
- if (grandPath.get('left.object').isIdentifier() && grandPath.node.left.object.name === objName) {
- console.log(grandPath + '');
- console.log('==============================')
- } else {
- quoteObj = true
- }
- }
- }
- if (!quoteObj) {
- for (const index in objRefer) {
- let grandPath = objRefer[index].parentPath.parentPath;
- grandPath.remove();
- }
- }
- }
- }
- })
复制代码 数值还原
- // 数值还原
- traverse(ast, {
- NumericLiteral(path){
- console.log('替换前: ', path.node.extra);
- delete path.node.extra.raw;
- console.log('替换后: ', path.node.extra);
- console.log('==============================');
- }
- })
复制代码 switch 还原
- // 还原 switch
- traverse(ast, {
- WhileStatement(path){
- if (path.node.test.prefix && path.get('body').isBlockStatement() && types.isSwitchStatement(path.node.body.body[0])){
- // 获取同级节点
- let sibling = path.getSibling(0)
- 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--){
- path.getSibling(path.key).remove();
- }
- }
- }
- })
复制代码 还原前
还原后
完整的 AST 代码
代码
- // 安装 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 码还原
- traverse(ast, {
- StringLiteral(path) {
- if (path.node.extra) {
- console.log('ASCII码替换前: ', path.node.extra);
- path.node.extra.raw = `'${path.node.extra.rawValue}'`
- console.log('ASCII码替换后: ', path.node.extra);
- console.log('============================================================');
- }
- }
- })
- // 字符串相加
- function strConcat(path) {
- for (let i = 0; i <= 2; i++) {
- let node = path.node
- // left 节点为 StringLiteral 类型
- // right 节点为 StringLiteral 类型
- // operator 操作符属性为字符串 +
- if (types.isStringLiteral(node.left) && types.isStringLiteral(node.right) && node.operator === '+') {
- // 例 'e' + 'f'
- console.log('字符串相加前: ', path + '');
- // 例 'e' + 'f'
- let result = path.node.left.value + path.node.right.value;
- // 例: 'e' + 'f'
- // 替换成: 'ef'
- path.replaceWith(types.valueToNode(result));
- console.log('字符串相加后: ', path + '');
- console.log('============================================================');
- } else {
- // 递归是针对多个字符串相加的
- // 例当前遍历到的节点: 'a' + 'b' + 'c' + 'd'
- // 这个节点在上面是不会处理的
- // path 对象的 traverse 方法是从当前节点继续遍历
- // 传入 strConcat 方法的节点就为: 'a' + 'b' + 'c' + 'd'
- // 调用过后还是会再次进入到 path.traverse 因为还是会有多个字符串相加
- // 上一次传入的节点被处理过了
- // 所以这一次传入的节点代码就为 'ab' + 'c' + 'd'
- // 一直递归到节点为 'abc' + 'd' 就会停止递归
- // 'abc' + 'd' 在 for 循环中会二次处理 (可以试着for循环只遍历一次看看效果
- path.traverse({
- BinaryExpression(path_) {
- strConcat(path_)
- }
- })
- }
- }
- }
- traverse(ast, {
- BinaryExpression(path) { // 遍历 BinaryExpression 节点
- strConcat(path)
- }
- })
- // 花指令
- traverse(ast, {
- VariableDeclarator(path){ // 遍历 VariableDeclarator 节点
- if (types.isObjectExpression(path.node.init)){ // init 类型为 ObjectExpression 类型
- let objName = path.node.id.name; // 获取对应的标识符
- let objBinding = path.scope.getBinding(objName); // 获取标识符对应的引用
- let objRefer = objBinding.referencePaths; // 获取标识符引用对应的数组
- let newObj = {}
- // 将给对象属性赋值的所有变量存入 newObj
- for (const refer in objRefer){ // refer 为索引值从 0 开始
- // objRefer[refer] 为 obj
- // objRefer[refer].parentPath 为 obj['str']
- // objRefer[refer].parentPath.parentPath 为 obj['str'] = 'abc'
- let grandPath = objRefer[refer].parentPath.parentPath; // 获取该节点的整段代码
- // 该节点的类型为 AssignmentExpression 类型
- // 节点中 left 属性的类型为 MemberExpression 类型
- if (grandPath.isAssignmentExpression() && grandPath.get('left').isMemberExpression()){
- // obj['str'] 中的 str 字符串
- let key = grandPath.node.left.property.value; // 获取 .property.value 的属性,作为新声明对象中的key
- newObj[key] = grandPath.node.right; // right为该属性对应的 node 节点,直接存入 newObj 对象即可
- }
- }
- for (const refer in objRefer.reverse()){
- let grandPath = objRefer[refer].parentPath;
- if (grandPath.isVariableDeclarator()){ // 该节点的类型应为 VariableDeclarator
- // 例: c = obj
- let identName = grandPath.node.id.name; // 获取标识符中对应的 name 属性 (例中的 c)
- // 例:
- // let d = c['StringLiteral'];
- // let e = c['BinaryExpression'];
- // let f = c['funcCallExpression1'](demo, '123');
- // let g = c['funcCallExpression2'](demo);
- // let h = c['funcBinaryExpression']('1' + '2');
- let identBinding = grandPath.scope.getBinding(identName); // 获取标识符 c 对应的引用
- // 例:
- // [c, c, c, c, c]
- let identRefer = identBinding.referencePaths; // 获取标识符引用对应的数组
- // 字符串花指令
- for (const idenKey in identRefer) {
- // identRefer[idenKey].parentPath
- // c['StringLiteral']
- // c['BinaryExpression']
- // c['funcCallExpression1']
- // c['funcCallExpression2']
- // c['funcBinaryExpression']
- let key = identRefer[idenKey].parentPath.node.property.value; // 获取对应的属性值
- // 获取 newObj[key] // obj[属性值]
- // newObj[key] 的属性值为 StringLiteral 或 BinaryExpression 节点
- // StringLiteral 为字符串 'abc';
- // BinaryExpression 为二项式 'abc' + 'def';
- if (types.isStringLiteral(newObj[key]) || types.isBinaryExpression(newObj[key])){ // 还原字符串
- console.log('花指令字符串替换前: ', identRefer[idenKey].parentPath + '')
- identRefer[idenKey].parentPath.replaceWith(newObj[key]) // 获取 obj 中对应的 StringLiteral 节点
- console.log('花指令字符串替换后: ', identRefer[idenKey].parentPath + '')
- console.log('====================================')
- }
- }
- // 数组翻转,从后向前遍历
- for (const idenKey in identRefer.reverse()) {
- // MemberExpression
- // 为 let d = c['StringLiteral']; 中的 c['StringLiteral']
- if (identRefer[idenKey].parentPath.isMemberExpression()){
- // 获取对应调用的属性值 c['StringLiteral'] 中的 'StringLiteral'
- let key = identRefer[idenKey].parentPath.node.property.value;
- // 如果 newObj 对应属性值为 FunctionExpression 类型
- if (types.isFunctionExpression(newObj[key])){
- /*
- function (){...}
- */
- // 拿到 return 语句
- let retState = newObj[key].body.body[0].argument;
- // 二元运算还原
- // 例: return a + b
- if (types.isBinaryExpression(retState)){
- let operator = retState.operator; // 拿到操作符 例: +
- // 拿到参数数组
- // c['funcBinaryExpression']('1', '2'); 中的 ['1', '2']
- let Arg = identRefer[idenKey].parentPath.parentPath.node.arguments;
- console.log('花指令二元替换前: ', identRefer[idenKey].parentPath.parentPath + '')
- // replaceWith 将当前的节点替换
- // c['funcBinaryExpression']('1', '2');
- // 替换成
- // '1' + '2'
- identRefer[idenKey].parentPath.parentPath.replaceWith(types.binaryExpression(operator, Arg[0], Arg[1]));
- console.log('花指令二元替换后: ', identRefer[idenKey].parentPath.parentPath + '')
- console.log('=========================')
- }
- // 函数调用还原
- // 例: return a(b) / return a()
- // 这两个的差别只有调用的参数,一个对应调用的参数为 2, 一个调用对应的参数为 1
- // CallExpression
- // 例: return a(b)
- if (types.isCallExpression(retState)){
- // 获取该节点对应的参数
- // 例: c['funcCallExpression1'](demo, '123');
- // 中的
- // demo, '123'
- let Arg = identRefer[idenKey].parentPath.parentPath.node.arguments;
- console.log('花指令函数调用替换前: ', identRefer[idenKey].parentPath.parentPath + '')
- // c['funcCallExpression'](demo, '123');
- // 替换成
- // demo('123');
- identRefer[idenKey].parentPath.parentPath.replaceWith(types.callExpression(types.identifier(Arg[0].name), Arg.slice(1)));
- console.log('花指令函数调用替换后: ', identRefer[idenKey].parentPath.parentPath + '')
- console.log('=========================')
- }
- }
- }
- }
- }
- }
- // path.stop()
- }
- }
- })
- // 虚假 if
- traverse(ast, {
- // IfStatement 为if判断语句
- // ConditionalExpression 为三元表达式
- "IfStatement|ConditionalExpression"(path){
- // 该节点中的判断条件应该为 二元表达式
- // left 节点应该为 StringLiteral 类型
- // right 节点应该为 StringLiteral 类型
- if(path.get('test').isBinaryExpression() && path.get('test.left').isStringLiteral() && path.get('test.right').isStringLiteral()){
- // 取出判断条件中对应的值
- // 例: if ('a' === 'a') { console.log("'a' === 'a' true");} else { console.log("'a' === 'a' false");}
- let operator = path.node.test.operator; // 取出操作符 例: ===
- let leftString = path.node.test.left.value; // 左边的字符串 例: 'a'
- let rightString = path.node.test.right.value; // 右边的字符串 例: === 'a'
- // 生成 eval 可判断的字符串
- let vmRun = `"${leftString}" ${operator} "${rightString}"`; // 例: 'a' === 'a'
- let result = eval(vmRun);
- console.log('虚假 if: ' + (path + '').replaceAll('\n', ''))
- // 取出 if 与 else 中的代码块
- // path.node.consequent.body 为 if(){}else{}; 形式取值
- // path.node.consequent.arguments 为 statement ? true : false; 形式取值
- let ifTrue = path.node.consequent.body || path.node.consequent.arguments;
- let elFalse = path.node.alternate.body || path.node.alternate.arguments;
- // 判断 result 的执行结果,替换对应的代码块 if 或 else
- result ? path.replaceWithMultiple(ifTrue) : path.replaceWithMultiple(elFalse)
- }
- }
- })
- // 剔除无引用代码
- const refObj = {}
- traverse(ast, {
- Identifier(path) {
- let name = path.node.name;
- if (!refObj[name]) {
- refObj[name] = '1';
- let binding = path.scope.getBinding(name);
- let refPath = binding && binding.referencePaths;
- if (refPath && refPath.length === 0) {
- path.parentPath.parentPath.isVariableDeclaration() && (console.log('删除的无用代码: ', path.parentPath + ''), path.parentPath.remove())
- }
- }
- }
- })
- // 无引用的对象
- traverse(ast, {
- VariableDeclarator(path) { // 遍历 VariableDeclarator 节点
- if (types.isObjectExpression(path.node.init)) { // init 类型为 ObjectExpression 类型
- let objName = path.node.id.name; // 获取对应的标识符
- let objBinding = path.scope.getBinding(objName); // 获取标识符对应的引用
- let objRefer = objBinding && objBinding.referencePaths; // 获取标识符引用对应的数组
- let quoteObj = false;
- for (const index in objRefer) {
- let grandPath = objRefer[index].parentPath.parentPath;
- if (grandPath.isAssignmentExpression() && grandPath.get('left').isMemberExpression()) {
- if (grandPath.get('left.object').isIdentifier() && grandPath.node.left.object.name === objName) {
- console.log(grandPath + '');
- console.log('==============================')
- } else {
- quoteObj = true
- }
- }
- }
- if (!quoteObj) {
- for (const index in objRefer) {
- let grandPath = objRefer[index].parentPath.parentPath;
- grandPath.remove();
- }
- }
- }
- }
- })
- // 数值还原
- traverse(ast, {
- NumericLiteral(path){
- console.log('替换前: ', path.node.extra);
- delete path.node.extra.raw;
- console.log('替换后: ', path.node.extra);
- console.log('==============================');
- }
- })
- // 还原 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
- js_code = generator(ast, {
- compact: true, // 是否压缩,默认 false
- }).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
- import requests
- import execjs
- import time
- def call_js(file_name, func_name, *args):
- with open(file_name, mode='r', encoding='utf-8') as f:
- js_code = execjs.compile(f.read())
- return js_code.call(func_name, *args)
- headers = {
- "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",
- }
- cookies = {
- "sessionid": "你的sessionid"
- }
- def get_data(page):
- url = "https://match.yuanrenxue.cn/api/match/2"
- time_ = int(str(int(time.time() * 1000))[:10] + '000')
- cookies['m'] = f"{call_js('2.js', '_0x691b6d', time_)}|{time_}"
- print(cookies)
- params = {
- "page": f'{page}'
- }
- response = requests.get(url, headers=headers, cookies=cookies, params=params)
- print(response.json())
- if __name__ == '__main__':
- get_data(1)
复制代码 javascript
- function _0x691b6d(_0x2de515, _0x4a2ede, _0x47e4dd) {
- return _0x396668(_0x2de515);
- }
- function _0x396668(_0xa25649) {
- return _0xef0b5b(_0x2985eb(_0xa25649));
- }
- function _0x2985eb(_0x2f966f) {
- return _0x513ef6(_0x130879(_0x2f966f));
- }
- function _0x130879(_0x1b540c) {
- var _0x553c57 = {};
- return unescape(encodeURIComponent(_0x1b540c));
- }
- function _0x513ef6(_0x2957b6) {
- var _0x4c198e = {};
- return _0x1fd78f(_0x1e5972(_0x32960f(_0x2957b6), 8 * _0x2957b6["length"]));
- }
- function _0xef0b5b(_0x10bf06) {
- var _0x2c2190,
- _0x20ca0c,
- _0x18d0e1 = "0123456789abcdef",
- _0xedd57d = '';
- for (_0x20ca0c = 0; _0x20ca0c < _0x10bf06["length"]; _0x20ca0c += 1) _0x2c2190 = _0x10bf06["charCodeAt"](_0x20ca0c), _0xedd57d += _0x18d0e1["charAt"](_0x2c2190 >>> 4 & 15) + _0x18d0e1["charAt"](15 & _0x2c2190);
- return _0xedd57d;
- }
- function _0x1e5972(_0x132f3d, _0x23ca08) {
- var _0x323bcd = {};
- _0x132f3d[_0x23ca08 >> 5] |= 128 << _0x23ca08 % 32, _0x132f3d[14 + (_0x23ca08 + 64 >>> 9 << 4)] = _0x23ca08;
- var _0x1ee0c6,
- _0x1e8f34,
- _0x429ecb,
- _0x5c3723,
- _0xde6a8e,
- _0x4f8eee = 1732584193,
- _0x12b681 = -271733879,
- _0x34e741 = -1732584194,
- _0x4aa794 = 271733878;
- 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);
- return [_0x4f8eee, _0x12b681, _0x34e741, _0x4aa794];
- }
- function _0xafe18(_0x59972b, _0x357d2b, _0x37f1e6, _0x40c0ec, _0x457a54, _0x27a208, _0x1291f9) {
- return _0x93484(_0x357d2b & _0x40c0ec | _0x37f1e6 & ~_0x40c0ec, _0x59972b, _0x357d2b, _0x457a54, _0x27a208, _0x1291f9);
- }
- function _0x2ba84c(_0x25c369, _0x2fa4cf, _0x10bc95, _0x133659, _0x3e51d8, _0x4a9786, _0x5ad3d9) {
- return _0x93484(_0x10bc95 ^ (_0x2fa4cf | ~_0x133659), _0x25c369, _0x2fa4cf, _0x3e51d8, _0x4a9786, _0x5ad3d9);
- }
- function _0x57cdb6(_0x24e055, _0x43d7e3, _0x11af5a, _0xde9c8, _0x3f9877, _0x3e6fd3, _0x45d799) {
- return _0x93484(_0x43d7e3 ^ _0x11af5a ^ _0xde9c8, _0x24e055, _0x43d7e3, _0x3f9877, _0x3e6fd3, _0x45d799);
- }
- function _0x3243aa(_0xdd939c, _0x39e4e0) {
- return _0xdd939c << _0x39e4e0 | _0xdd939c >>> 32 - _0x39e4e0;
- }
- function _0x564a36(_0x3c4e40, _0x45890c) {
- var _0x1e7f33 = {};
- var _0x474c37 = (65535 & _0x3c4e40) + (65535 & _0x45890c);
- return (_0x3c4e40 >> 16) + (_0x45890c >> 16) + (_0x474c37 >> 16) << 16 | 65535 & _0x474c37;
- }
- function _0x93484(_0x1f657e, _0x172cfb, _0x14882e, _0x31dde3, _0x16e397, _0x330a90) {
- return _0x564a36(_0x3243aa(_0x564a36(_0x564a36(_0x172cfb, _0x1f657e), _0x564a36(_0x31dde3, _0x330a90)), _0x16e397), _0x14882e);
- }
- function _0x5655af(_0x5ec922, _0x49f6b4, _0x357fa0, _0x1558be, _0x3b2d74, _0x5bb480, _0x36aa69) {
- return _0x93484(_0x49f6b4 & _0x357fa0 | ~_0x49f6b4 & _0x1558be, _0x5ec922, _0x49f6b4, _0x3b2d74, _0x5bb480, _0x36aa69);
- }
- function _0x32960f(_0x2752b7) {
- var _0x1e1be5,
- _0x5928bd = [];
- for (_0x5928bd[(_0x2752b7["length"] >> 2) - 1] = void 0, _0x1e1be5 = 0; _0x1e1be5 < _0x5928bd["length"]; _0x1e1be5 += 1) _0x5928bd[_0x1e1be5] = 0;
- var _0x2e5130 = 8 * _0x2752b7["length"];
- for (_0x1e1be5 = 0; _0x1e1be5 < _0x2e5130; _0x1e1be5 += 8) _0x5928bd[_0x1e1be5 >> 5] |= (255 & _0x2752b7["charCodeAt"](_0x1e1be5 / 8)) << _0x1e1be5 % 32;
- return _0x5928bd;
- }
- function _0x1fd78f(_0x461924) {
- var _0x51955d,
- _0x47ef66 = '',
- _0x264aa7 = 32 * _0x461924["length"];
- for (_0x51955d = 0; _0x51955d < _0x264aa7; _0x51955d += 8) _0x47ef66 += String["fromCharCode"](_0x461924[_0x51955d >> 5] >>> _0x51955d % 32 & 255);
- return _0x47ef66;
- }
- // console.log(_0x691b6d(1723380724000));
- // '75bcb82b08198abbec49a4248c6aae02|1723380724000'
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |