├── .editorconfig ├── .gitignore ├── .vscode ├── launch.json └── settings.json ├── README.md ├── index.ts ├── package-lock.json ├── package.json ├── src ├── EspreeFacade.ts ├── control-flow.ts ├── deobfuscator.ts ├── espree.d.ts ├── literals.ts ├── member-expr.ts ├── protection.ts ├── string-array.ts └── utils.ts ├── test-data ├── test-obf1.js ├── test-obf2.js ├── test-obf3.js ├── test-obf4.js ├── test-obf5.js ├── test-obf6.js └── test-obf7.js └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = crlf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | charset = utf-8 12 | 13 | [*.{ts,js,json}] 14 | indent_style = space 15 | indent_size = 4 16 | 17 | [{package.json,tsd.json,tslint.json,bower.json}] 18 | indent_style = space 19 | indent_size = 2 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | 63 | # vuepress build output 64 | .vuepress/dist 65 | 66 | # Serverless directories 67 | .serverless 68 | 69 | .vscode/* 70 | !.vscode/settings.json 71 | !.vscode/tasks.json 72 | !.vscode/launch.json 73 | !.vscode/extensions.json 74 | 75 | *.js 76 | *.map 77 | !test-data/* -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Launch Program", 11 | "program": "${workspaceFolder}/index.js", 12 | "outFiles": [ 13 | "${workspaceFolder}/**/*.js" 14 | ], 15 | "args": [ 16 | "${workspaceFolder}/test-data/test-obf5.js" 17 | ] 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": { 3 | "**/.git": true, 4 | "**/.svn": true, 5 | "**/.hg": true, 6 | "**/CVS": true, 7 | "**/.DS_Store": true, 8 | "**/*.js": true, 9 | "**/*.js.map": true 10 | } 11 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # javascript-deobfuscator 2 | Deobfuscate code generated by [javascript-obfuscator](https://github.com/javascript-obfuscator/javascript-obfuscator) 3 | -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs'; 2 | import * as util from 'util'; 3 | import { Deobfuscator } from './src/deobfuscator'; 4 | 5 | if (process.argv.length < 4) { 6 | console.log('Usage: javascript-deobfuscator '); 7 | process.exit(1); 8 | } 9 | 10 | try { 11 | console.log('Loading file %s...', process.argv[2]); 12 | const code = fs.readFileSync(process.argv[2], 'utf8'); 13 | const deobf = new Deobfuscator(code); 14 | deobf.init(); 15 | const result = deobf.deobfuscate(); 16 | console.log(); 17 | if (process.argv[3] === '-') { 18 | console.log(result); 19 | } else { 20 | console.log('Writing result to %s...', process.argv[3]); 21 | fs.writeFileSync(process.argv[3], result, 'utf8'); 22 | } 23 | } catch (e) { 24 | console.error(e); 25 | console.error(e.stack); 26 | } 27 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "javascript-deobfuscator", 3 | "version": "0.1.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/escodegen": { 8 | "version": "0.0.6", 9 | "resolved": "https://registry.npmjs.org/@types/escodegen/-/escodegen-0.0.6.tgz", 10 | "integrity": "sha1-UjCpznluBCzabwhtvxnyLqMwZZw=", 11 | "dev": true 12 | }, 13 | "@types/estraverse": { 14 | "version": "0.0.6", 15 | "resolved": "https://registry.npmjs.org/@types/estraverse/-/estraverse-0.0.6.tgz", 16 | "integrity": "sha1-Zp9833KreX5hJfjQD+0z1M8wwiE=", 17 | "dev": true, 18 | "requires": { 19 | "@types/estree": "0.0.39" 20 | } 21 | }, 22 | "@types/estree": { 23 | "version": "0.0.39", 24 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", 25 | "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", 26 | "dev": true 27 | }, 28 | "@types/node": { 29 | "version": "10.3.1", 30 | "resolved": "https://registry.npmjs.org/@types/node/-/node-10.3.1.tgz", 31 | "integrity": "sha512-IsX9aDHDzJohkm3VCDB8tkzl5RQ34E/PFA29TQk6uDGb7Oc869ZBtmdKVDBzY3+h9GnXB8ssrRXEPVZrlIOPOw==", 32 | "dev": true 33 | }, 34 | "acorn": { 35 | "version": "5.6.2", 36 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.6.2.tgz", 37 | "integrity": "sha512-zUzo1E5dI2Ey8+82egfnttyMlMZ2y0D8xOCO3PNPPlYXpl8NZvF6Qk9L9BEtJs+43FqEmfBViDqc5d1ckRDguw==" 38 | }, 39 | "acorn-jsx": { 40 | "version": "3.0.1", 41 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", 42 | "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", 43 | "requires": { 44 | "acorn": "3.3.0" 45 | }, 46 | "dependencies": { 47 | "acorn": { 48 | "version": "3.3.0", 49 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", 50 | "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" 51 | } 52 | } 53 | }, 54 | "deep-is": { 55 | "version": "0.1.3", 56 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 57 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" 58 | }, 59 | "escodegen": { 60 | "version": "1.9.1", 61 | "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz", 62 | "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==", 63 | "requires": { 64 | "esprima": "3.1.3", 65 | "estraverse": "4.2.0", 66 | "esutils": "2.0.2", 67 | "optionator": "0.8.2", 68 | "source-map": "0.6.1" 69 | } 70 | }, 71 | "espree": { 72 | "version": "3.5.4", 73 | "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", 74 | "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", 75 | "requires": { 76 | "acorn": "5.6.2", 77 | "acorn-jsx": "3.0.1" 78 | } 79 | }, 80 | "esprima": { 81 | "version": "3.1.3", 82 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", 83 | "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" 84 | }, 85 | "estraverse": { 86 | "version": "4.2.0", 87 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", 88 | "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" 89 | }, 90 | "esutils": { 91 | "version": "2.0.2", 92 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", 93 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" 94 | }, 95 | "fast-levenshtein": { 96 | "version": "2.0.6", 97 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 98 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" 99 | }, 100 | "levn": { 101 | "version": "0.3.0", 102 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 103 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 104 | "requires": { 105 | "prelude-ls": "1.1.2", 106 | "type-check": "0.3.2" 107 | } 108 | }, 109 | "optionator": { 110 | "version": "0.8.2", 111 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", 112 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", 113 | "requires": { 114 | "deep-is": "0.1.3", 115 | "fast-levenshtein": "2.0.6", 116 | "levn": "0.3.0", 117 | "prelude-ls": "1.1.2", 118 | "type-check": "0.3.2", 119 | "wordwrap": "1.0.0" 120 | } 121 | }, 122 | "prelude-ls": { 123 | "version": "1.1.2", 124 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 125 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" 126 | }, 127 | "source-map": { 128 | "version": "0.6.1", 129 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 130 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 131 | "optional": true 132 | }, 133 | "type-check": { 134 | "version": "0.3.2", 135 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 136 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 137 | "requires": { 138 | "prelude-ls": "1.1.2" 139 | } 140 | }, 141 | "wordwrap": { 142 | "version": "1.0.0", 143 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", 144 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "javascript-deobfuscator", 3 | "version": "0.1.0", 4 | "description": "Deobfuscate code generated by javascript-obfuscator", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "kmvi", 10 | "license": "BSD-2-Clause", 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/kmvi/javascript-deobfuscator.git" 14 | }, 15 | "devDependencies": { 16 | "@types/escodegen": "0.0.6", 17 | "@types/estraverse": "0.0.6", 18 | "@types/estree": "0.0.39", 19 | "@types/node": "^10.3.1" 20 | }, 21 | "dependencies": { 22 | "escodegen": "^1.9.1", 23 | "espree": "^3.5.4", 24 | "estraverse": "^4.2.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/EspreeFacade.ts: -------------------------------------------------------------------------------- 1 | import * as espree from 'espree'; 2 | import * as ESTree from 'estree'; 3 | 4 | 5 | /** 6 | * Facade over `espree` 7 | */ 8 | export class EspreeFacade { 9 | /** 10 | * @type {Chalk} 11 | */ 12 | private static readonly colorError = (x: string) => x; 13 | 14 | /** 15 | * @type {number} 16 | */ 17 | private static readonly nearestSymbolsCount: number = 15; 18 | 19 | /** 20 | * @type {SourceType[]} 21 | */ 22 | private static readonly sourceTypes: espree.SourceType[] = [ 23 | 'script', 24 | 'module' 25 | ]; 26 | 27 | /** 28 | * @param {string} input 29 | * @param {Options} config 30 | * @returns {Program} 31 | */ 32 | public static parse (input: string, config: espree.ParseOptions): ESTree.Program | never { 33 | const sourceTypeLength: number = EspreeFacade.sourceTypes.length; 34 | 35 | for (let i: number = 0; i < sourceTypeLength; i++) { 36 | try { 37 | return EspreeFacade.parseType(input, config, EspreeFacade.sourceTypes[i]); 38 | } catch (error) { 39 | if (i < sourceTypeLength - 1) { 40 | continue; 41 | } 42 | 43 | throw new Error(EspreeFacade.processParsingError( 44 | input, 45 | error.message, 46 | { 47 | line: error.lineNumber, 48 | column: error.column, 49 | } 50 | )); 51 | } 52 | } 53 | 54 | throw new Error(`Espree parsing error`); 55 | } 56 | 57 | /** 58 | * @param {string} input 59 | * @param {ParseOptions} inputConfig 60 | * @param {SourceType} sourceType 61 | * @returns {Program} 62 | */ 63 | private static parseType ( 64 | input: string, 65 | inputConfig: espree.ParseOptions, 66 | sourceType: espree.SourceType 67 | ): ESTree.Program { 68 | const config: espree.ParseOptions = { ...inputConfig, sourceType }; 69 | 70 | return espree.parse(input, config); 71 | } 72 | 73 | /** 74 | * @param {string} sourceCode 75 | * @param {string} errorMessage 76 | * @param {Position} position 77 | * @returns {never} 78 | */ 79 | private static processParsingError (sourceCode: string, errorMessage: string, position: ESTree.Position | null): never { 80 | if (!position || !position.line || !position.column) { 81 | throw new Error(errorMessage); 82 | } 83 | 84 | const sourceCodeLines: string[] = sourceCode.split(/\r?\n/); 85 | const errorLine: string | undefined = sourceCodeLines[position.line - 1]; 86 | 87 | if (!errorLine) { 88 | throw new Error(errorMessage); 89 | } 90 | 91 | const startErrorIndex: number = Math.max(0, position.column - EspreeFacade.nearestSymbolsCount); 92 | const endErrorIndex: number = Math.min(errorLine.length, position.column + EspreeFacade.nearestSymbolsCount); 93 | 94 | const formattedPointer: string = EspreeFacade.colorError('>'); 95 | const formattedCodeSlice: string = `...${ 96 | errorLine.substring(startErrorIndex, endErrorIndex).replace(/^\s+/, '') 97 | }...`; 98 | 99 | throw new Error(`Line ${position.line}: ${errorMessage}\n${formattedPointer} ${formattedCodeSlice}`); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/control-flow.ts: -------------------------------------------------------------------------------- 1 | import * as espree from 'espree'; 2 | import * as estree from 'estree'; 3 | import { ProtectionBase } from "./protection"; 4 | import { VisitorOption, traverse, replace } from 'estraverse'; 5 | import * as Utils from './utils'; 6 | import { assert } from 'console'; 7 | 8 | type SwitchInfo = { 9 | discrVar: estree.VariableDeclaration; 10 | discr: estree.VariableDeclarator; 11 | loop: estree.WhileStatement; 12 | discrArray: string[]; 13 | sw: estree.SwitchStatement; 14 | parent: estree.BlockStatement; 15 | }; 16 | 17 | type Replace = { 18 | [key: string]: estree.Expression; 19 | }; 20 | 21 | type ObjReplace = { 22 | [varname: string]: Replace; 23 | }; 24 | 25 | export class BlockControlFlow extends ProtectionBase { 26 | 27 | private loops: SwitchInfo[] = []; 28 | 29 | constructor(code: string, ast: estree.Program) { 30 | super(code, ast); 31 | } 32 | 33 | detect(): boolean { 34 | this.active = false; 35 | this.loops = this.findLoops(); 36 | this.active = this.loops.length > 0; 37 | if (this.active) 38 | console.log('! Block control flow flattening detected.'); 39 | return this.active; 40 | } 41 | 42 | private fillDiscriminators(loop: SwitchInfo): void { 43 | assert(loop.discr.init && Utils.isCallExpression(loop.discr.init)); 44 | let call = loop.discr.init as estree.CallExpression; 45 | assert(call.arguments.length === 1 46 | && Utils.isLiteral(call.arguments[0]) 47 | && ( call.arguments[0]).value === '|'); 48 | assert(Utils.isMemberExpression(call.callee) 49 | && Utils.isLiteral(call.callee.property) 50 | && call.callee.property.value === 'split'); 51 | let obj = ( call.callee).object; 52 | if (Utils.isLiteral(obj) && typeof obj.value === 'string') { 53 | loop.discrArray = obj.value.split('|'); 54 | } else if (Utils.isMemberExpression(obj) 55 | && Utils.isIdentifier(obj.object) 56 | && Utils.isLiteral(obj.property)) 57 | { 58 | const val = this.findValue(obj.object.name, obj.property.value as string); 59 | if (val) { 60 | loop.discrArray = val.split('|'); 61 | } else { 62 | throw new Error('Unable to find value of ' + Utils.cutCode(this.code, obj)); 63 | } 64 | } else { 65 | throw new Error('Unexpected expression: ' + Utils.cutCode(this.code, obj)); 66 | } 67 | } 68 | 69 | private findValue(name: string, key: string): string | undefined { 70 | let result: string | undefined = undefined; 71 | traverse(this.ast, { 72 | enter: (node, parent) => { 73 | if (Utils.isVariableDeclaration(node)) { 74 | const decl = node.declarations.find(x => Utils.isIdentifier(x.id) && x.id.name === name); 75 | if (decl && decl.init && Utils.isObjectExpression(decl.init)) { 76 | let prop = decl.init.properties.find(x => 77 | Utils.isLiteral(x.key) && typeof x.key.value === 'string' && x.key.value === key); 78 | if (prop && Utils.isLiteral(prop.value) && typeof prop.value.value === 'string') { 79 | result = prop.value.value; 80 | return VisitorOption.Break; 81 | } else if (prop) { 82 | if (Utils.isMemberExpression(prop.value) 83 | && Utils.isIdentifier(prop.value.object) 84 | && Utils.isLiteral(prop.value.property)) 85 | { 86 | result = this.findValue(prop.value.object.name, 87 | prop.value.property.value as string); 88 | return VisitorOption.Break; 89 | } else { 90 | throw new Error('Unexpected property value: ' + 91 | Utils.cutCode(this.code, prop)); 92 | } 93 | } 94 | } 95 | } 96 | } 97 | }); 98 | return result; 99 | } 100 | 101 | private findLoops(): SwitchInfo[] { 102 | let loops: SwitchInfo[] = []; 103 | 104 | traverse(this.ast, { 105 | enter: (node, parent) => { 106 | const checkContinueAndReturn = function (e: estree.SwitchCase): boolean { 107 | return e.consequent.length > 0 108 | && (Utils.isContinueStatement(e.consequent[e.consequent.length - 1]) 109 | || Utils.isReturnStatement(e.consequent[0])); 110 | }; 111 | const isInfiniteWhile = function (e: estree.Node): e is estree.WhileStatement { 112 | return Utils.isWhileStatement(node) && 113 | Utils.isLiteral(node.test) && 114 | node.test.value === true; 115 | }; 116 | let sw: estree.SwitchStatement | null = null; 117 | if (isInfiniteWhile(node) && Utils.isBlockStatement(node.body) && node.body.body.length === 2) { 118 | const firstStmt = node.body.body[0]; 119 | const lastStmt = node.body.body[1]; 120 | if (Utils.isSwitchStatement(firstStmt) && 121 | firstStmt.cases.every(checkContinueAndReturn) && 122 | Utils.isBreakStatement(lastStmt)) 123 | { 124 | sw = firstStmt; 125 | } 126 | } 127 | if (!sw) return; 128 | if (Utils.isMemberExpression(sw.discriminant) && Utils.isIdentifier(sw.discriminant.object)) { 129 | assert(Utils.isUpdateExpression(sw.discriminant.property)); 130 | const switchArrayName = sw.discriminant.object.name; 131 | if (parent && Utils.isBlockStatement(parent)) { 132 | const loopIndex = parent.body.indexOf(node as estree.Statement); 133 | assert(loopIndex > 0); 134 | const prevStmt = parent.body[loopIndex-1]; 135 | if (Utils.isVariableDeclaration(prevStmt)) { 136 | const decl = prevStmt.declarations[0]; 137 | const name = ( decl.id).name; 138 | assert(name === switchArrayName); 139 | loops.push({ 140 | discrVar: prevStmt, 141 | discr: decl, 142 | loop: node as estree.WhileStatement, 143 | discrArray: [], 144 | sw: sw, 145 | parent: parent, 146 | }); 147 | } 148 | } 149 | } 150 | } 151 | }); 152 | 153 | return loops; 154 | } 155 | 156 | remove(): estree.Program { 157 | if (!this.active) 158 | return this.ast; 159 | 160 | process.stdout.write('* Removing switch statements...'); 161 | this.loops.forEach(x => this.fillDiscriminators(x)); 162 | for (const loop of this.loops) { 163 | replace(this.ast, { 164 | enter: (node, parent) => { 165 | if (node === loop.parent) { 166 | let result = { 167 | type: 'BlockStatement', 168 | body: [], 169 | }; 170 | for (const item of node.body) { 171 | if (item !== loop.loop && item !== loop.discrVar) 172 | result.body.push(item); 173 | } 174 | for (const i of loop.discrArray) { 175 | let $case = loop.sw.cases.find(x => i === ( x.test).value as string); 176 | if (!$case) 177 | throw new Error('Unable to find case ' + i); 178 | for (const stmt of $case.consequent) { 179 | if (!Utils.isContinueStatement(stmt)) { 180 | result.body.push(stmt); 181 | } 182 | } 183 | } 184 | return result; 185 | } 186 | } 187 | }); 188 | } 189 | process.stdout.write(' done.\n'); 190 | 191 | return this.ast; 192 | } 193 | } 194 | 195 | export class FunctionControlFlow extends ProtectionBase { 196 | 197 | private data: ObjReplace = {}; 198 | private decl: { [key: string]: estree.VariableDeclaration } = {}; 199 | 200 | constructor(code: string, ast: estree.Program) { 201 | super(code, ast); 202 | } 203 | 204 | detect(): boolean { 205 | this.active = false; 206 | traverse(this.ast, { 207 | enter: (node, parent) => { 208 | const isString = function (x: estree.Node): boolean { 209 | return Utils.isLiteral(x) && typeof x.value === 'string'; 210 | }; 211 | const checkProperty = function (x: estree.Node): boolean { 212 | return Utils.isLiteral(x) 213 | || (Utils.isFunctionExpression(x) && x.body.body.length === 1) 214 | || (Utils.isMemberExpression(x) && Utils.isLiteral(x.property)); 215 | }; 216 | if ((Utils.isFunctionExpression(node) 217 | || Utils.isArrowFunctionExpression(node) 218 | || Utils.isFunctionDeclaration(node)) 219 | && Utils.isBlockStatement(node.body) && node.body.body.length > 0) 220 | { 221 | for (let i = 0; i < node.body.body.length; ++i) { 222 | const stmt = node.body.body[i]; 223 | if (!Utils.isVariableDeclaration(stmt)) { 224 | break; 225 | } 226 | const id = stmt.declarations[0].id; 227 | const obj = stmt.declarations[0].init; 228 | if (Utils.isIdentifier(id) && obj 229 | && Utils.isObjectExpression(obj) 230 | && obj.properties.length > 0 231 | && obj.properties.every(x => isString(x.key)) 232 | && obj.properties.every(x => checkProperty(x.value))) 233 | { 234 | const result = this.processProperties(obj.properties); 235 | if (Object.keys(result).length > 0) { 236 | this.data[id.name] = result; 237 | this.decl[id.name] = stmt; 238 | } 239 | } 240 | } 241 | } 242 | } 243 | }); 244 | this.active = Object.keys(this.data).length > 0; 245 | if (this.active) 246 | console.log('! Function control flow flattening detected.'); 247 | return this.active; 248 | } 249 | 250 | private processProperties (props: estree.Property[]): Replace { 251 | let result: Replace = {}; 252 | for (const p of props) { 253 | const key = ( p.key).value as string; 254 | if (Utils.isLiteral(p.value) || Utils.isMemberExpression(p.value)) { 255 | result[key] = p.value; 256 | } else if (Utils.isFunctionExpression(p.value)) { 257 | const ret = p.value.body.body[0] as estree.ReturnStatement; 258 | assert(Utils.isReturnStatement(ret)); 259 | assert(ret.argument); 260 | result[key] = p.value; 261 | } else { 262 | throw new Error('Unexpected expression: ' + 263 | Utils.cutCode(this.code, p.value)); 264 | } 265 | } 266 | return result; 267 | }; 268 | 269 | remove(): estree.Program { 270 | if (!this.active) 271 | return this.ast; 272 | 273 | process.stdout.write('* Remove control flow flattening...'); 274 | for (const $var in this.data) { 275 | if (this.data.hasOwnProperty($var)) { 276 | this.removeMemeberExpr($var); 277 | this.replaceValue($var); 278 | } 279 | } 280 | 281 | for (const $var in this.decl) { 282 | if (this.decl.hasOwnProperty($var)) { 283 | replace(this.ast, { 284 | enter: (node, parent) => { 285 | if (node === this.decl[$var]) { 286 | return VisitorOption.Remove; 287 | } 288 | } 289 | }); 290 | } 291 | } 292 | process.stdout.write(' done.\n'); 293 | 294 | return this.ast; 295 | } 296 | 297 | private removeMemeberExpr(key: string): void { 298 | const obj = this.data[key]; 299 | let hasMemberExpr = true; 300 | while (hasMemberExpr) { 301 | hasMemberExpr = false; 302 | for (let key in obj) { 303 | if (obj.hasOwnProperty(key) && Utils.isMemberExpression(obj[key])) { 304 | hasMemberExpr = true; 305 | const m = obj[key] as estree.MemberExpression; 306 | const name = (m.object as estree.Identifier).name; 307 | const prop = (m.property as estree.Literal).value as string; 308 | obj[key] = this.data[name][prop]; 309 | } 310 | } 311 | } 312 | } 313 | 314 | private replaceValue(name: string): void { 315 | replace(this.ast, { 316 | enter: (node, parent) => { 317 | if (Utils.isCallExpression(node)) { 318 | if (!Utils.isMemberExpression(node.callee) 319 | || !Utils.isIdentifier(node.callee.object) 320 | || !Utils.isLiteral(node.callee.property) 321 | || typeof node.callee.property.value !== 'string') 322 | { 323 | return undefined; 324 | } 325 | if (node.callee.object.name === name) { 326 | const f = this.data[name][node.callee.property.value] as estree.FunctionExpression; 327 | return this.substParameters(f, node.arguments as estree.Expression[]); 328 | } 329 | } else if (Utils.isMemberExpression(node)) { 330 | if (!Utils.isIdentifier(node.object) 331 | || !Utils.isLiteral(node.property) 332 | || typeof node.property.value !== 'string') 333 | { 334 | return undefined; 335 | } 336 | if (node.object.name === name) { 337 | const l = this.data[name][node.property.value] as estree.Literal; 338 | assert(l); 339 | assert(l.type === 'Literal'); 340 | return { 341 | type: 'Literal', 342 | value: l.value, 343 | }; 344 | } 345 | } 346 | } 347 | }); 348 | } 349 | 350 | private substParameters(func: estree.FunctionExpression, args: estree.Expression[]): estree.Expression { 351 | let expr = (func.body.body[0] as estree.ReturnStatement).argument!; 352 | expr = JSON.parse(JSON.stringify(expr)); 353 | for (let i = 0; i < args.length; ++i) { 354 | const param = func.params[i] as estree.Identifier; 355 | replace(expr, { 356 | enter: (node, parent) => { 357 | if (Utils.isIdentifier(node) && node.name === param.name) { 358 | return JSON.parse(JSON.stringify(args[i])); 359 | } 360 | } 361 | }); 362 | } 363 | return expr; 364 | } 365 | } 366 | -------------------------------------------------------------------------------- /src/deobfuscator.ts: -------------------------------------------------------------------------------- 1 | import * as espree from 'espree'; 2 | import * as estree from 'estree'; 3 | import { generate } from 'escodegen'; 4 | import { EspreeFacade } from './EspreeFacade'; 5 | import { StringArrayProtection } from './string-array'; 6 | import { registerDecoders } from './utils'; 7 | import { ProtectionBase } from './protection'; 8 | import { StringSplit, BooleanLiterals } from './literals'; 9 | import { BlockControlFlow, FunctionControlFlow } from './control-flow'; 10 | import { MemberExpr } from './member-expr'; 11 | 12 | type ProtectionCtor = new (code: string, ast: estree.Program) => ProtectionBase; 13 | 14 | export class Deobfuscator { 15 | 16 | private static readonly espreeParseOptions: espree.ParseOptions = { 17 | attachComment: true, 18 | comment: true, 19 | ecmaFeatures: { 20 | experimentalObjectRestSpread: true 21 | }, 22 | ecmaVersion: 9, 23 | loc: true, 24 | range: true 25 | }; 26 | 27 | private ast: estree.Program | null = null; 28 | private protections: ProtectionCtor[] = [ 29 | StringSplit, 30 | BooleanLiterals, 31 | StringArrayProtection, 32 | BlockControlFlow, 33 | FunctionControlFlow, 34 | MemberExpr, 35 | ]; 36 | 37 | constructor (public code: string) { 38 | 39 | } 40 | 41 | init(): void { 42 | console.log('Parsing file...'); 43 | this.ast = EspreeFacade.parse(this.code, Deobfuscator.espreeParseOptions); 44 | registerDecoders(); 45 | } 46 | 47 | deobfuscate(): string { 48 | if (!this.ast) 49 | throw new Error('Call init() first.'); 50 | 51 | console.log('Removing protections...'); 52 | 53 | let code = this.code; 54 | let ast = this.ast; 55 | 56 | for (const ctor of this.protections) { 57 | const p = new ctor(code, ast); 58 | if (p.detect()) { 59 | ast = p.remove(); 60 | code = generate(ast); 61 | ast = EspreeFacade.parse(code, Deobfuscator.espreeParseOptions); 62 | } 63 | } 64 | 65 | console.log('Done.'); 66 | 67 | return code; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/espree.d.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:interface-name */ 2 | 3 | declare module 'espree' { 4 | import * as ESTree from 'estree'; 5 | 6 | export interface Comment { 7 | value: string; 8 | } 9 | 10 | export type SourceType = 'script' | 'module'; 11 | 12 | export interface ParseOptions { 13 | attachComment?: boolean; 14 | comment?: boolean; 15 | ecmaFeatures?: { 16 | experimentalObjectRestSpread?: boolean; 17 | globalReturn?: boolean; 18 | impliedStrict?: boolean; 19 | jsx?: boolean; 20 | }; 21 | ecmaVersion?: 3 | 5 | 6 | 7 | 8 | 9 | 2015 | 2016 | 2017 | 2018; 22 | loc?: boolean; 23 | range?: boolean; 24 | sourceType?: SourceType; 25 | } 26 | 27 | export function parse (code: string | Buffer, options: ParseOptions): ESTree.Program; 28 | } 29 | -------------------------------------------------------------------------------- /src/literals.ts: -------------------------------------------------------------------------------- 1 | import * as espree from 'espree'; 2 | import * as estree from 'estree'; 3 | import { ProtectionBase } from "./protection"; 4 | import { VisitorOption, traverse, replace } from 'estraverse'; 5 | import * as Utils from './utils'; 6 | 7 | export class StringSplit extends ProtectionBase { 8 | 9 | constructor(code: string, ast: estree.Program) { 10 | super(code, ast); 11 | this.active = true; 12 | } 13 | 14 | detect(): boolean { 15 | return this.active; 16 | } 17 | 18 | remove(): estree.Program { 19 | if (!this.active) 20 | return this.ast; 21 | 22 | process.stdout.write('* Merging string literals...'); 23 | this.ast = replace(this.ast, { 24 | enter: (node, parent) => { 25 | if (Utils.isBinaryExpression(node) && node.operator === '+' && 26 | Utils.isLiteral(node.left) && Utils.isLiteral(node.right) && 27 | typeof node.left.value === 'string' && typeof node.right.value === 'string') 28 | { 29 | return { 30 | type: 'Literal', 31 | value: node.left.value + node.right.value 32 | }; 33 | } 34 | } 35 | }); 36 | process.stdout.write(' done.\n'); 37 | 38 | return this.ast; 39 | } 40 | 41 | } 42 | 43 | export class BooleanLiterals extends ProtectionBase { 44 | 45 | constructor(code: string, ast: estree.Program) { 46 | super(code, ast); 47 | this.active = true; 48 | } 49 | 50 | detect(): boolean { 51 | return this.active; 52 | } 53 | 54 | remove(): estree.Program { 55 | if (!this.active) 56 | return this.ast; 57 | 58 | process.stdout.write('* Replacing bool expressions...'); 59 | this.ast = replace(this.ast, { 60 | enter: (node, parent) => { 61 | let isEmptyArray = function (e: estree.Node): e is estree.ArrayExpression { 62 | return Utils.isArrayExpression(e) && e.elements.length === 0; 63 | }; 64 | let isNegate = function (e: estree.Node): e is estree.UnaryExpression { 65 | return Utils.isUnaryExpression(e) && e.operator === '!'; 66 | }; 67 | if (isNegate(node)) { 68 | if (isNegate(node.argument) && isEmptyArray(node.argument.argument)) { 69 | return { 70 | type: 'Literal', 71 | value: true 72 | }; 73 | } else if (isEmptyArray(node.argument)) { 74 | return { 75 | type: 'Literal', 76 | value: false 77 | }; 78 | } 79 | } 80 | } 81 | }); 82 | process.stdout.write(' done.\n'); 83 | 84 | return this.ast; 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/member-expr.ts: -------------------------------------------------------------------------------- 1 | import * as espree from 'espree'; 2 | import * as estree from 'estree'; 3 | import { ProtectionBase } from "./protection"; 4 | import { VisitorOption, traverse, replace } from 'estraverse'; 5 | import * as Utils from './utils'; 6 | 7 | export class MemberExpr extends ProtectionBase { 8 | 9 | constructor(code: string, ast: estree.Program) { 10 | super(code, ast); 11 | this.active = true; 12 | } 13 | 14 | detect(): boolean { 15 | return this.active; 16 | } 17 | 18 | remove(): estree.Program { 19 | if (!this.active) 20 | return this.ast; 21 | 22 | process.stdout.write('* Removing computed member expressions...'); 23 | replace(this.ast, { 24 | enter: (node, parent) => { 25 | if (!Utils.isMemberExpression(node) || !node.computed) 26 | return undefined; 27 | if (Utils.isLiteral(node.property) && typeof node.property.value === 'string') { 28 | if (/^[_a-zA-Z][_0-9a-zA-Z]*$/.test(node.property.value)) { 29 | let result = JSON.parse(JSON.stringify(node)); 30 | result.computed = false; 31 | result.property = { 32 | type: 'Identifier', 33 | name: node.property.value 34 | }; 35 | return result; 36 | } 37 | } 38 | } 39 | }); 40 | process.stdout.write(' done.\n'); 41 | 42 | return this.ast; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/protection.ts: -------------------------------------------------------------------------------- 1 | import * as espree from 'espree'; 2 | import * as estree from 'estree'; 3 | 4 | export abstract class ProtectionBase { 5 | 6 | protected active: boolean = false; 7 | 8 | constructor ( 9 | protected code: string, 10 | protected ast: estree.Program) 11 | { 12 | 13 | } 14 | 15 | abstract detect(): boolean; 16 | abstract remove(): estree.Program; 17 | 18 | isActive() { 19 | return this.active; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/string-array.ts: -------------------------------------------------------------------------------- 1 | import * as espree from 'espree'; 2 | import * as estree from 'estree'; 3 | import { assert } from 'console'; 4 | import { VisitorOption, traverse, replace } from 'estraverse'; 5 | import { ProtectionBase } from "./protection"; 6 | import * as Utils from './utils'; 7 | 8 | type EncodingType = 'none' | 'base64' | 'rc4'; 9 | 10 | export class StringArrayProtection extends ProtectionBase { 11 | 12 | private arrayVar: string = ''; 13 | private array: string[] = []; 14 | private astArray: estree.Statement | null = null; 15 | 16 | private hasRotation: boolean = false; 17 | private rotFunc: string = ''; 18 | private astRot: estree.Statement | null = null; 19 | 20 | private hasEncoding: boolean = false; 21 | private encoding: EncodingType = 'none'; 22 | private astDecoder: estree.Statement | null = null; 23 | private decFuncName: string = ''; 24 | private rc4Keys: string[] = []; 25 | 26 | constructor(code: string, ast: estree.Program) { 27 | super(code, ast); 28 | } 29 | 30 | detect(): boolean { 31 | this.active = false; 32 | 33 | if (this.ast.body && this.ast.body.length > 0 && Utils.isVariableDeclaration(this.ast.body[0])) { 34 | const strArrayDef = this.ast.body[0]; 35 | if (strArrayDef.declarations && strArrayDef.declarations.length > 0) { 36 | const strArrayDecl = strArrayDef.declarations[0]; 37 | if (strArrayDecl.init && Utils.isArrayExpression(strArrayDecl.init) && Utils.isIdentifier(strArrayDecl.id)) { 38 | this.arrayVar = strArrayDecl.id.name; 39 | this.astArray = this.ast.body[0] as estree.Statement; 40 | this.array = strArrayDecl.init.elements.map(e => { 41 | assert(Utils.isLiteral(e)); 42 | assert(typeof ( e).value === 'string'); 43 | return ( e).value as string; 44 | }); 45 | this.active = true; 46 | this.detectRotation(); 47 | this.detectEncoding(); 48 | } 49 | } 50 | } 51 | if (this.active) 52 | console.log('! String array protection detected.'); 53 | if (this.hasRotation) 54 | console.log('! String array rotation detected.'); 55 | if (this.hasEncoding) 56 | console.log('! String array encoding detected: %s.', this.encoding); 57 | return this.active; 58 | } 59 | 60 | private detectRotation(): boolean { 61 | this.hasRotation = false; 62 | if (this.ast.body.length > 1 && Utils.isExpressionStatement(this.ast.body[1])) { 63 | const expr = this.ast.body[1]; 64 | if (Utils.isCallExpression(expr.expression)) { 65 | if (expr.expression.arguments.length === 2) { 66 | const id = expr.expression.arguments.find(Utils.isIdentifier); 67 | const cnt = expr.expression.arguments.find(Utils.isLiteral); 68 | if (id && id.name === this.arrayVar && cnt && typeof cnt.value === 'number') { 69 | this.hasRotation = true; 70 | this.rotFunc = Utils.cutCode(this.code, expr); 71 | this.astRot = this.ast.body[1] as estree.Statement; 72 | } 73 | } 74 | } 75 | } 76 | return this.hasRotation; 77 | } 78 | 79 | private detectEncoding(): boolean { 80 | this.hasEncoding = false; 81 | let index = this.hasRotation ? 2 : 1; 82 | if (this.ast.body.length > index && Utils.isVariableDeclaration(this.ast.body[index])) { 83 | const decVar = this.ast.body[index]; 84 | if (decVar.declarations && decVar.declarations.length > 0) { 85 | const decDecl = decVar.declarations[0]; 86 | if (Utils.isIdentifier(decDecl.id) && decDecl.init && Utils.isFunctionExpression(decDecl.init)) { 87 | if (decDecl.init.params.length === 2) { 88 | const decFuncCode = Utils.cutCode(this.code, decDecl.init); 89 | this.encoding = /\batob\b/.test(decFuncCode) 90 | ? (/%\s*(?:0x100|256)\D/.test(decFuncCode) ? 'rc4' : 'base64') 91 | : 'none'; 92 | this.astDecoder = this.ast.body[index] as estree.Statement; 93 | this.decFuncName = decDecl.id.name; 94 | this.hasEncoding = true; 95 | } 96 | } 97 | } 98 | } 99 | return this.hasEncoding; 100 | } 101 | 102 | remove(): estree.Program { 103 | let result = this.ast; 104 | if (!this.active) 105 | return result; 106 | 107 | process.stdout.write('* Rotating string array...'); 108 | if (this.hasRotation) { 109 | const func = new Function(this.arrayVar, this.rotFunc); 110 | func.call(undefined, this.array); 111 | } 112 | process.stdout.write(' done.\n'); 113 | 114 | process.stdout.write('* Decoding string array...'); 115 | if (this.hasEncoding && this.astDecoder) { 116 | if (this.encoding === 'base64') { 117 | for (let i = 0; i < this.array.length; ++i) 118 | this.array[i] = Utils.decodeBase64(this.array[i]); 119 | } else if (this.encoding === 'rc4') { 120 | this.fillKeys(); 121 | for (let i = 0; i < this.array.length; ++i) 122 | this.array[i] = Utils.decodeRC4(this.array[i], this.rc4Keys[i]); 123 | } 124 | this.removeDecoderCalls(); 125 | } 126 | process.stdout.write(' done.\n'); 127 | 128 | process.stdout.write('* Removing string array...'); 129 | if (this.hasRotation && this.astRot) { 130 | this.ast.body.splice(this.ast.body.indexOf(this.astRot), 1); 131 | } 132 | 133 | if (this.hasEncoding && this.astDecoder) { 134 | this.ast.body.splice(this.ast.body.indexOf(this.astDecoder), 1); 135 | } 136 | 137 | if (this.astArray) { 138 | this.ast.body.splice(this.ast.body.indexOf(this.astArray), 1); 139 | } 140 | process.stdout.write(' done.\n'); 141 | 142 | return result; 143 | } 144 | 145 | private fillKeys(): void { 146 | for (let i = 0; i < this.ast.body.length; ++i) { 147 | traverse(this.ast.body[i], { 148 | enter: (node, parentNode) => { 149 | let call = this.checkDecoderCall(node); 150 | if (call) { 151 | const index = ( call.arguments[0]).value - 0; 152 | this.rc4Keys[index] = ( call.arguments[1]).value as string; 153 | } 154 | } 155 | }); 156 | } 157 | } 158 | 159 | private removeDecoderCalls(): void { 160 | for (let i = 0; i < this.ast.body.length; ++i) { 161 | this.ast.body[i] = replace(this.ast.body[i], { 162 | enter: (node, parentNode) => { 163 | let call = this.checkDecoderCall(node); 164 | if (call) { 165 | const index = ( call.arguments[0]).value - 0; 166 | return { 167 | type: 'Literal', 168 | value: this.array[index] 169 | }; 170 | } 171 | } 172 | }); 173 | } 174 | } 175 | 176 | private checkDecoderCall(node: estree.Node): estree.CallExpression | null { 177 | if (Utils.isCallExpression(node) && Utils.isIdentifier(node.callee)) { 178 | if (node.callee.name === this.decFuncName) { 179 | assert(node.arguments.length === 1 || node.arguments.length === 2); 180 | assert(node.arguments.every(Utils.isLiteral)); 181 | return node; 182 | } 183 | } 184 | return null; 185 | } 186 | } 187 | 188 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | import * as espree from 'espree'; 2 | import * as estree from 'estree'; 3 | 4 | export function cutCode(code: string, node: estree.BaseNodeWithoutComments): string { 5 | if (!node || !node.range || node.range.length < 2) 6 | throw new Error('Node range is not specified.'); 7 | return code.slice(node.range[0], node.range[1]); 8 | } 9 | 10 | export function registerDecoders(): void { 11 | (function (that: any) { 12 | var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; 13 | that.atob || ( 14 | that.atob = function(input: any) { 15 | var str = String(input).replace(/=+$/, ''); 16 | for ( 17 | var bc = 0, bs = 0, buffer, idx = 0, output = ''; 18 | buffer = str.charAt(idx++); 19 | ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, 20 | bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0 21 | ) { 22 | buffer = chars.indexOf(buffer); 23 | } 24 | return output; 25 | }); 26 | })(global); 27 | 28 | (function (that: any) { 29 | that.rc4 || ( 30 | that.rc4 = function (str: any, key: any) { 31 | var s = [], j = 0, x, res = '', newStr = ''; 32 | 33 | str = that.atob(str); 34 | 35 | for (var k = 0, length = str.length; k < length; k++) { 36 | newStr += '%' + ('00' + str.charCodeAt(k).toString(16)).slice(-2); 37 | } 38 | 39 | str = decodeURIComponent(newStr); 40 | 41 | for (var i = 0; i < 256; i++) { 42 | s[i] = i; 43 | } 44 | 45 | for (i = 0; i < 256; i++) { 46 | j = (j + s[i] + key.charCodeAt(i % key.length)) % 256; 47 | x = s[i]; 48 | s[i] = s[j]; 49 | s[j] = x; 50 | } 51 | 52 | i = 0; 53 | j = 0; 54 | 55 | for (var y = 0; y < str.length; y++) { 56 | i = (i + 1) % 256; 57 | j = (j + s[i]) % 256; 58 | x = s[i]; 59 | s[i] = s[j]; 60 | s[j] = x; 61 | res += String.fromCharCode(str.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]); 62 | } 63 | 64 | return res; 65 | }); 66 | })(global); 67 | } 68 | 69 | export function decodeBase64(encoded: string): string { 70 | const g = global; 71 | if (!g.atob) 72 | throw new Error('Call registerDecoders() first.'); 73 | return g.atob(encoded); 74 | } 75 | 76 | export function decodeRC4(encoded: string, key: string): string { 77 | const g = global; 78 | if (!g.rc4) 79 | throw new Error('Call registerDecoders() first.'); 80 | return g.rc4(encoded, key); 81 | } 82 | 83 | export function isBinaryExpression(node: estree.Node): node is estree.BinaryExpression { 84 | return node.type === 'BinaryExpression'; 85 | } 86 | 87 | export function isLiteral(node: estree.Node): node is estree.Literal { 88 | return node.type === 'Literal'; 89 | } 90 | 91 | export function isVariableDeclaration(node: estree.Node): node is estree.VariableDeclaration { 92 | return node.type === 'VariableDeclaration'; 93 | } 94 | 95 | export function isIdentifier(node: estree.Node): node is estree.Identifier { 96 | return node.type === 'Identifier'; 97 | } 98 | 99 | export function isFunctionExpression(node: estree.Node): node is estree.FunctionExpression { 100 | return node.type === 'FunctionExpression'; 101 | } 102 | 103 | export function isCallExpression(node: estree.Node): node is estree.CallExpression { 104 | return node.type === 'CallExpression'; 105 | } 106 | 107 | export function isExpressionStatement(node: estree.Node): node is estree.ExpressionStatement { 108 | return node.type === 'ExpressionStatement'; 109 | } 110 | 111 | export function isArrayExpression(node: estree.Node): node is estree.ArrayExpression { 112 | return node.type === 'ArrayExpression'; 113 | } 114 | 115 | export function isUnaryExpression(node: estree.Node): node is estree.UnaryExpression { 116 | return node.type === 'UnaryExpression'; 117 | } 118 | 119 | export function isSwitchStatement(node: estree.Node): node is estree.SwitchStatement { 120 | return node.type === 'SwitchStatement'; 121 | } 122 | 123 | export function isContinueStatement(node: estree.Node): node is estree.ContinueStatement { 124 | return node.type === 'ContinueStatement'; 125 | } 126 | 127 | export function isWhileStatement(node: estree.Node): node is estree.WhileStatement { 128 | return node.type === 'WhileStatement'; 129 | } 130 | 131 | export function isBlockStatement(node: estree.Node): node is estree.BlockStatement { 132 | return node.type === 'BlockStatement'; 133 | } 134 | 135 | export function isBreakStatement(node: estree.Node): node is estree.BreakStatement { 136 | return node.type === 'BreakStatement'; 137 | } 138 | 139 | export function isMemberExpression(node: estree.Node): node is estree.MemberExpression { 140 | return node.type === 'MemberExpression'; 141 | } 142 | 143 | export function isUpdateExpression(node: estree.Node): node is estree.UpdateExpression { 144 | return node.type === 'UpdateExpression'; 145 | } 146 | 147 | export function isReturnStatement(node: estree.Node): node is estree.ReturnStatement { 148 | return node.type === 'ReturnStatement'; 149 | } 150 | 151 | export function isObjectExpression(node: estree.Node): node is estree.ObjectExpression { 152 | return node.type === 'ObjectExpression'; 153 | } 154 | 155 | export function isArrowFunctionExpression(node: estree.Node): node is estree.ArrowFunctionExpression { 156 | return node.type === 'ArrowFunctionExpression'; 157 | } 158 | 159 | export function isFunctionDeclaration(node: estree.Node): node is estree.FunctionDeclaration { 160 | return node.type === 'FunctionDeclaration'; 161 | } 162 | -------------------------------------------------------------------------------- /test-data/test-obf1.js: -------------------------------------------------------------------------------- 1 | var _0x4a4f=['test1','test2','Hello\x20World!','log'];(function(_0x4d84b7,_0x173d36){var _0xcdb8b2=function(_0x479d14){while(--_0x479d14){_0x4d84b7['push'](_0x4d84b7['shift']());}};_0xcdb8b2(++_0x173d36);}(_0x4a4f,0x166));var _0x34e8=function(_0xb94811,_0x4bdeb8){_0xb94811=_0xb94811-0x0;var _0x1e2cb9=_0x4a4f[_0xb94811];return _0x1e2cb9;};function hi(){console['log'](_0x34e8('0x0'));console[_0x34e8('0x1')](_0x34e8('0x2'));console['log'](_0x34e8('0x3'));}hi(); -------------------------------------------------------------------------------- /test-data/test-obf2.js: -------------------------------------------------------------------------------- 1 | var a=['SGVsbG8gV29ybGQh','dGVzdDE=','dGVzdDI=','dGVzdDQ=','bG9n'];(function(c,d){var e=function(f){while(--f){c['push'](c['shift']());}};e(++d);}(a,0x9a));var b=function(c,d){c=c-0x0;var e=a[c];if(b['mySENN']===undefined){(function(){var f=function(){var g;try{g=Function('return\x20(function()\x20'+'{}.constructor(\x22return\x20this\x22)(\x20)'+');')();}catch(h){g=window;}return g;};var i=f();var j='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';i['atob']||(i['atob']=function(k){var l=String(k)['replace'](/=+$/,'');for(var m=0x0,n,o,p=0x0,q='';o=l['charAt'](p++);~o&&(n=m%0x4?n*0x40+o:o,m++%0x4)?q+=String['fromCharCode'](0xff&n>>(-0x2*m&0x6)):0x0){o=j['indexOf'](o);}return q;});}());b['MvuiPJ']=function(r){var s=atob(r);var t=[];for(var u=0x0,v=s['length'];u>(-0x2*m&0x6)):0x0){o=j['indexOf'](o);}return q;});}()); 6 | 7 | var r=function(s,t){var u=[],v=0x0,w,x='',y='';s=atob(s);for(var z=0x0,A=s['length'];z _0x509ede; 56 | }, 57 | 'NxdrI': function (_0x4e416b, _0x5bd697) { 58 | return _0x4e416b < _0x5bd697; 59 | }, 60 | 'BKgTu': function (_0x131587, _0x414bcd, _0x3af0b3) { 61 | return _0x131587(_0x414bcd, _0x3af0b3); 62 | }, 63 | 'KfeMM': function (_0x40fa4a, _0x2b5df7) { 64 | return _0x40fa4a == _0x2b5df7; 65 | }, 66 | 'TaOdZ': function (_0x1cabf8, _0x4939e4) { 67 | return _0x1cabf8 == _0x4939e4; 68 | }, 69 | 'CCFFm': function (_0x5a8fc9, _0x340a66) { 70 | return _0x5a8fc9 == _0x340a66; 71 | }, 72 | 'BZxYf': function (_0x396cbf, _0x5ba639) { 73 | return _0x396cbf > _0x5ba639; 74 | }, 75 | 'eZvbe': function (_0x43ebfb, _0x5bb1f0) { 76 | return _0x43ebfb % _0x5bb1f0; 77 | }, 78 | 'oQeNp': function (_0x4282dd, _0x2660cb) { 79 | return _0x4282dd <= _0x2660cb; 80 | }, 81 | 'oLgQL': function (_0x544ce3, _0x304f85, _0x287bce, _0x41c6eb) { 82 | return _0x544ce3(_0x304f85, _0x287bce, _0x41c6eb); 83 | }, 84 | 'AxejU': function (_0x29fb40, _0xd34c4b, _0x9debcc, _0x45fadf) { 85 | return _0x29fb40(_0xd34c4b, _0x9debcc, _0x45fadf); 86 | }, 87 | 'HCjrQ': function (_0x4137f1, _0x1ca493, _0x5ac81a) { 88 | return _0x4137f1(_0x1ca493, _0x5ac81a); 89 | }, 90 | 'GpSvB': '1|2|4|3|0|5|6', 91 | 'HaWuM': function (_0x4446fa) { 92 | return _0x4446fa(); 93 | }, 94 | 'hvjdO': function (_0x4db47d) { 95 | return _0x4db47d(); 96 | }, 97 | 'sLDuo': function (_0x2b0e95, _0x517e98) { 98 | return _0x2b0e95 !== _0x517e98; 99 | }, 100 | 'xcBtf': 'bug-string-char-index', 101 | 'FDJjR': function (_0x5dd827, _0x36f541) { 102 | return _0x5dd827 == _0x36f541; 103 | }, 104 | 'ZZKEe': 'json-stringify', 105 | 'BHQSn': 'json-parse', 106 | 'nScSB': function (_0x3568e2, _0x481e92) { 107 | return _0x3568e2(_0x481e92); 108 | }, 109 | 'mRDrt': '[null]', 110 | 'xPNZz': function (_0x357a7f, _0x1c6c43) { 111 | return _0x357a7f == _0x1c6c43; 112 | }, 113 | 'fdiXm': function (_0x3b2cfe, _0x4cb002) { 114 | return _0x3b2cfe(_0x4cb002); 115 | }, 116 | 'gFkyt': '[null,null,null]', 117 | 'bzkit': '\x0a\x0c\x0d\x09', 118 | 'EOZXS': function (_0x2b9c18, _0x18684d) { 119 | return _0x2b9c18 == _0x18684d; 120 | }, 121 | 'ZqPVQ': '[\x0a\x201,\x0a\x202\x0a]', 122 | 'vSbTT': function (_0x9423d9, _0x529f53) { 123 | return _0x9423d9(_0x529f53); 124 | }, 125 | 'fnPUL': '\x22-000001-01-01T00:00:00.000Z\x22', 126 | 'tZzGg': '\x221969-12-31T23:59:59.999Z\x22', 127 | 'IYBFC': function (_0x76cd01, _0x526802) { 128 | return _0x76cd01 === _0x526802; 129 | }, 130 | 'FHYdW': function (_0x18c01f, _0x389777) { 131 | return _0x18c01f(_0x389777); 132 | }, 133 | 'LLcRv': '\x22\x09\x22', 134 | 'tkdpk': function (_0x5c2e60, _0x1f3e9f) { 135 | return _0x5c2e60 in _0x1f3e9f; 136 | }, 137 | 'btlbl': function (_0x2086bc, _0x35d19d) { 138 | return _0x2086bc in _0x35d19d; 139 | }, 140 | 'lepWt': '2|4|3|0|1', 141 | 'ASrjm': function (_0x90bb21, _0x379913) { 142 | return _0x90bb21 in _0x379913; 143 | }, 144 | 'ghwQW': 'prototype', 145 | 'TAgvq': function (_0x1d4c37, _0x4354ec) { 146 | return _0x1d4c37 || _0x4354ec; 147 | }, 148 | 'pPACx': function (_0x57578f, _0x5507d1, _0x53d907, _0x1fd028, _0x7c8a8f, _0x2f1bd4, _0x1eba2f, _0x54d89b) { 149 | return _0x57578f(_0x5507d1, _0x53d907, _0x1fd028, _0x7c8a8f, _0x2f1bd4, _0x1eba2f, _0x54d89b); 150 | }, 151 | 'AtIvQ': 'null', 152 | 'nRaoz': function (_0x52d349, _0x261b3a) { 153 | return _0x52d349 + _0x261b3a; 154 | }, 155 | 'rcBVT': function (_0x433e88, _0x14cd35) { 156 | return _0x433e88(_0x14cd35); 157 | }, 158 | 'mKaTB': 'object', 159 | 'LUwPG': function (_0x56048a) { 160 | return _0x56048a(); 161 | }, 162 | 'ysedV': function (_0x1ae177, _0x1b724f) { 163 | return _0x1ae177 == _0x1b724f; 164 | }, 165 | 'LcFin': function (_0x3ad97a, _0x227470) { 166 | return _0x3ad97a - _0x227470; 167 | }, 168 | 'IIJws': '1|5|0|4|2|3|6', 169 | 'yzMfQ': function (_0x469616, _0x18d7fc) { 170 | return _0x469616 + _0x18d7fc; 171 | }, 172 | 'XIOqN': function (_0x5eb486, _0x488b6c) { 173 | return _0x5eb486 + _0x488b6c; 174 | }, 175 | 'IwBGs': function (_0x265401, _0x21fcaa) { 176 | return _0x265401 >= _0x21fcaa; 177 | }, 178 | 'lGmrZ': function (_0x315ff2, _0x4aadd7) { 179 | return _0x315ff2 <= _0x4aadd7; 180 | }, 181 | 'OZjaJ': function (_0x4b5d4a, _0x5c9d45) { 182 | return _0x4b5d4a == _0x5c9d45; 183 | }, 184 | 'ieIhY': function (_0x26f9d4, _0x4e9daa) { 185 | return _0x26f9d4 == _0x4e9daa; 186 | }, 187 | 'jWFEf': 'true', 188 | 'gVwKj': function (_0x46c856, _0x58af24) { 189 | return _0x46c856 == _0x58af24; 190 | }, 191 | 'pnbIy': function (_0x44fe0e, _0x191e04) { 192 | return _0x44fe0e + _0x191e04; 193 | }, 194 | 'oWzxS': 'false', 195 | 'tamnc': 'string', 196 | 'PIohJ': function (_0x454148, _0x2cdb09) { 197 | return _0x454148 == _0x2cdb09; 198 | }, 199 | 'HhJGs': function (_0x12580d) { 200 | return _0x12580d(); 201 | }, 202 | 'JxcFr': function (_0x36a185, _0x270a4a) { 203 | return _0x36a185 == _0x270a4a; 204 | }, 205 | 'SbxpF': function (_0x3a8340, _0x493e39) { 206 | return _0x3a8340 == _0x493e39; 207 | }, 208 | 'pSiEo': function (_0x1a9fe8, _0x1d32a6) { 209 | return _0x1a9fe8 != _0x1d32a6; 210 | }, 211 | 'XXedW': function (_0x5e0a2b, _0x22dc2a, _0x5e6819, _0x3eadc6) { 212 | return _0x5e0a2b(_0x22dc2a, _0x5e6819, _0x3eadc6); 213 | }, 214 | 'fPxyA': 'Object', 215 | 'UtwWn': 'Number', 216 | 'JJeKi': 'String', 217 | 'cvyvX': 'Date', 218 | 'reDxJ': 'SyntaxError', 219 | 'vgSrM': 'TypeError', 220 | 'yrVPF': 'Math', 221 | 'kQXGT': 'JSON', 222 | 'taJZh': function (_0x40b567, _0x5b76cb) { 223 | return _0x40b567 == _0x5b76cb; 224 | }, 225 | 'VOOKO': 'json', 226 | 'RWync': '[object\x20Function]', 227 | 'aIjHw': '[object\x20Date]', 228 | 'PepER': '[object\x20Number]', 229 | 'kPRbR': '[object\x20String]', 230 | 'xylhM': '[object\x20Boolean]', 231 | 'wLDEJ': function (_0x499359, _0x22043f) { 232 | return _0x499359(_0x22043f); 233 | }, 234 | 'EfALB': '000000', 235 | 'vLwaj': function (_0x487aa8, _0x180e91) { 236 | return _0x487aa8(_0x180e91); 237 | }, 238 | 'wltow': function (_0x575da0, _0x429a3c) { 239 | return _0x575da0 === _0x429a3c; 240 | }, 241 | 'LqSjt': 'global', 242 | 'rHryx': function (_0x3079c1, _0x37b3de) { 243 | return _0x3079c1 === _0x37b3de; 244 | }, 245 | 'pAEcG': 'window', 246 | 'poOgB': function (_0x425c98, _0x44b977) { 247 | return _0x425c98 === _0x44b977; 248 | }, 249 | 'gfKJS': 'self', 250 | 'IvMhj': function (_0xa9e071, _0x4e981b) { 251 | return _0xa9e071 && _0x4e981b; 252 | }, 253 | 'BOzBt': function (_0x5e767c, _0x456adc, _0x58734a) { 254 | return _0x5e767c(_0x456adc, _0x58734a); 255 | }, 256 | 'ADXrQ': 'JSON3', 257 | 'oNCQS': function (_0x1667d2, _0x502a8a, _0x5f3d3c) { 258 | return _0x1667d2(_0x502a8a, _0x5f3d3c); 259 | } 260 | }; 261 | var _0x1cabc2 = typeof define === 'function' && define['amd']; 262 | var _0x43469f = { 263 | 'function': !![], 264 | 'object': !![] 265 | }; 266 | var _0x12373f = _0x43469f[typeof exports] && exports && !exports['nodeType'] && exports; 267 | var _0x211a8c = _0x43469f[typeof window] && window || this, _0x35c465 = _0x12373f && _0x43469f[typeof module] && module && !module['nodeType'] && _0x4eeb0f['taJZh'](typeof global, 'object') && global; 268 | if (_0x35c465 && (_0x4eeb0f['wltow'](_0x35c465[_0x4eeb0f['LqSjt']], _0x35c465) || _0x4eeb0f['rHryx'](_0x35c465[_0x4eeb0f['pAEcG']], _0x35c465) || _0x4eeb0f['poOgB'](_0x35c465[_0x4eeb0f['gfKJS']], _0x35c465))) { 269 | _0x211a8c = _0x35c465; 270 | } 271 | function _0x415768(_0x316a1c, _0x2daf34) { 272 | var _0x3d7ea1 = { 273 | 'ofzdj': function (_0x2e0931, _0x5ec051) { 274 | return _0x4eeb0f['sLDuo'](_0x2e0931, _0x5ec051); 275 | }, 276 | 'SRBWM': function (_0xcaf69a, _0x5be80c) { 277 | return _0x4eeb0f['CCFFm'](_0xcaf69a, _0x5be80c); 278 | }, 279 | 'CBeXt': _0x4eeb0f['xcBtf'], 280 | 'GhCad': function (_0x249af4, _0x326378) { 281 | return _0x4eeb0f['FDJjR'](_0x249af4, _0x326378); 282 | }, 283 | 'FIXiH': 'json', 284 | 'MnxTf': function (_0x210523, _0x224cdd) { 285 | return _0x4eeb0f['plTcp'](_0x210523, _0x224cdd); 286 | }, 287 | 'pZWmm': _0x4eeb0f['ZZKEe'], 288 | 'ZjCPP': function (_0x214c8b, _0x4adc21) { 289 | return _0x4eeb0f['plTcp'](_0x214c8b, _0x4adc21); 290 | }, 291 | 'hCQlJ': _0x4eeb0f['BHQSn'], 292 | 'pqMHh': '{\x22a\x22:[1,true,false,null,\x22\x5cu0000\x5cb\x5cn\x5cf\x5cr\x5ct\x22]}', 293 | 'wOqLR': _0x4eeb0f['LmWUQ'], 294 | 'AqlKj': function (_0x207478, _0x3990f0) { 295 | return _0x207478 === _0x3990f0; 296 | }, 297 | 'BHlrV': function (_0x5c7058, _0x59c22f) { 298 | return _0x4eeb0f['plTcp'](_0x5c7058, _0x59c22f); 299 | }, 300 | 'wkbaD': function (_0x1e2198, _0x5ac069) { 301 | return _0x1e2198(_0x5ac069); 302 | }, 303 | 'UKAau': function (_0x2ffc33, _0x48a7cd) { 304 | return _0x4eeb0f['nScSB'](_0x2ffc33, _0x48a7cd); 305 | }, 306 | 'zZNuE': function (_0x2c6e75, _0x39ea6c) { 307 | return _0x2c6e75 === _0x39ea6c; 308 | }, 309 | 'WNtqx': function (_0x57abdc) { 310 | return _0x57abdc(); 311 | }, 312 | 'xiSHW': function (_0x4bb147, _0x15f953) { 313 | return _0x4bb147 == _0x15f953; 314 | }, 315 | 'wkOtw': _0x4eeb0f['mRDrt'], 316 | 'TdAKL': function (_0xdc911f, _0x181b58) { 317 | return _0x4eeb0f['xPNZz'](_0xdc911f, _0x181b58); 318 | }, 319 | 'UOMmJ': function (_0x5994de, _0x1d03f4) { 320 | return _0x4eeb0f['fdiXm'](_0x5994de, _0x1d03f4); 321 | }, 322 | 'rCKVB': _0x4eeb0f['gFkyt'], 323 | 'TbhET': _0x4eeb0f['bzkit'], 324 | 'uBxCf': function (_0x56b36a, _0x331a1e, _0x56e5a7) { 325 | return _0x4eeb0f['HCjrQ'](_0x56b36a, _0x331a1e, _0x56e5a7); 326 | }, 327 | 'ApLGk': function (_0x49d162, _0x1b0e6c) { 328 | return _0x4eeb0f['EOZXS'](_0x49d162, _0x1b0e6c); 329 | }, 330 | 'OwxeN': _0x4eeb0f['ZqPVQ'], 331 | 'ARfmW': function (_0xf7bcf4, _0x189234) { 332 | return _0x4eeb0f['vSbTT'](_0xf7bcf4, _0x189234); 333 | }, 334 | 'xgFZr': _0x4eeb0f['fnPUL'], 335 | 'pdQKW': function (_0x1a2761, _0x582359) { 336 | return _0x4eeb0f['EOZXS'](_0x1a2761, _0x582359); 337 | }, 338 | 'xzIup': function (_0x366a27, _0x5bdd54) { 339 | return _0x366a27(_0x5bdd54); 340 | }, 341 | 'nRFnb': _0x4eeb0f['tZzGg'], 342 | 'KMiDn': function (_0x25e53d, _0x321067) { 343 | return _0x4eeb0f['EOZXS'](_0x25e53d, _0x321067); 344 | }, 345 | 'ainGk': function (_0xa03dd0, _0x432c97) { 346 | return _0x4eeb0f['EOZXS'](_0xa03dd0, _0x432c97); 347 | }, 348 | 'AGExd': function (_0x149f96, _0xf28409) { 349 | return _0x4eeb0f['vSbTT'](_0x149f96, _0xf28409); 350 | }, 351 | 'xCNPL': function (_0x35265a, _0x13f6e2) { 352 | return _0x4eeb0f['IYBFC'](_0x35265a, _0x13f6e2); 353 | }, 354 | 'EmcWG': function (_0x1a48ed, _0x2c28f6) { 355 | return _0x4eeb0f['FHYdW'](_0x1a48ed, _0x2c28f6); 356 | }, 357 | 'qHxLA': _0x4eeb0f['LLcRv'], 358 | 'fgefx': function (_0x5acd42, _0x22b1f0) { 359 | return _0x4eeb0f['sLDuo'](_0x5acd42, _0x22b1f0); 360 | }, 361 | 'GqWGS': function (_0x1cd1d7, _0x41b981) { 362 | return _0x4eeb0f['FHYdW'](_0x1cd1d7, _0x41b981); 363 | }, 364 | 'BHbjT': function (_0x1b03d0, _0x2e08f7) { 365 | return _0x4eeb0f['tkdpk'](_0x1b03d0, _0x2e08f7); 366 | }, 367 | 'fbeCR': function (_0x3de586, _0x18e9a1) { 368 | return _0x4eeb0f['btlbl'](_0x3de586, _0x18e9a1); 369 | }, 370 | 'UuzbN': _0x4eeb0f['lepWt'], 371 | 'XEbIg': function (_0x5b5116, _0x170e8e) { 372 | return _0x4eeb0f['ASrjm'](_0x5b5116, _0x170e8e); 373 | }, 374 | 'JGXSV': function (_0x294ed3, _0x55372b) { 375 | return _0x294ed3 != _0x55372b; 376 | }, 377 | 'UTFTS': _0x4eeb0f['ghwQW'], 378 | 'gOatN': function (_0x372c08, _0x4e02aa) { 379 | return _0x372c08(_0x4e02aa); 380 | }, 381 | 'Xxmyg': 'constructor', 382 | 'DqXff': function (_0x14945f, _0x5e258d) { 383 | return _0x4eeb0f['ErziL'](_0x14945f, _0x5e258d); 384 | }, 385 | 'RYJix': function (_0x17681e, _0x1191c7) { 386 | return _0x4eeb0f['TAgvq'](_0x17681e, _0x1191c7); 387 | }, 388 | 'ubXcW': function (_0x452407, _0x42f8a7, _0x4e883f, _0x1956ce, _0x450f2b, _0xba7567, _0x247320, _0x2159e2) { 389 | return _0x4eeb0f['pPACx'](_0x452407, _0x42f8a7, _0x4e883f, _0x1956ce, _0x450f2b, _0xba7567, _0x247320, _0x2159e2); 390 | }, 391 | 'aGnYu': function (_0x5c5278, _0x95454c) { 392 | return _0x5c5278 + _0x95454c; 393 | }, 394 | 'xFXRi': function (_0x3b46de, _0x37e3ea) { 395 | return _0x3b46de + _0x37e3ea; 396 | }, 397 | 'fDleW': function (_0x4c9118, _0x35ce70) { 398 | return _0x4eeb0f['FHYdW'](_0x4c9118, _0x35ce70); 399 | }, 400 | 'UcISs': '5|0|7|6|1|3|2|4', 401 | 'jcELh': _0x4eeb0f['AtIvQ'], 402 | 'zNXPZ': function (_0xe24f34, _0x2608b5) { 403 | return _0x4eeb0f['nRaoz'](_0xe24f34, _0x2608b5); 404 | }, 405 | 'NayAA': function (_0x2fcec0, _0x52817f) { 406 | return _0x4eeb0f['BZxYf'](_0x2fcec0, _0x52817f); 407 | }, 408 | 'GWrML': function (_0x2f6c42, _0x390b33) { 409 | return _0x4eeb0f['gPwdD'](_0x2f6c42, _0x390b33); 410 | }, 411 | 'kkdxN': function (_0x2e0b6f, _0x2d624d) { 412 | return _0x4eeb0f['NxdrI'](_0x2e0b6f, _0x2d624d); 413 | }, 414 | 'ukxRU': function (_0x590f28, _0x11e04e) { 415 | return _0x590f28 == _0x11e04e; 416 | }, 417 | 'lvJGW': function (_0x47baf6, _0x4cc015) { 418 | return _0x4eeb0f['rcBVT'](_0x47baf6, _0x4cc015); 419 | }, 420 | 'wUSAL': function (_0x3c72ee, _0x492a6d) { 421 | return _0x3c72ee == _0x492a6d; 422 | }, 423 | 'mIlCL': _0x4eeb0f['mKaTB'], 424 | 'DPdRl': function (_0x8ce22b) { 425 | return _0x4eeb0f['LUwPG'](_0x8ce22b); 426 | }, 427 | 'ZkaZr': function (_0x3b4d99, _0x29fd82) { 428 | return _0x4eeb0f['ysedV'](_0x3b4d99, _0x29fd82); 429 | }, 430 | 'zjICl': function (_0x4cfc3a, _0xc7a8d9, _0x21d98b, _0x425b13, _0x41bf1d, _0x30fa7b, _0x2f786d, _0x5214e9) { 431 | return _0x4eeb0f['pPACx'](_0x4cfc3a, _0xc7a8d9, _0x21d98b, _0x425b13, _0x41bf1d, _0x30fa7b, _0x2f786d, _0x5214e9); 432 | }, 433 | 'amsyw': function (_0x1e3d01, _0x253dca) { 434 | return _0x1e3d01 + _0x253dca; 435 | }, 436 | 'ulHNw': function (_0x48fc83, _0x3de338, _0x5e1372) { 437 | return _0x4eeb0f['HCjrQ'](_0x48fc83, _0x3de338, _0x5e1372); 438 | }, 439 | 'TUocI': function (_0x107f2f, _0x2d6d5b) { 440 | return _0x4eeb0f['TAgvq'](_0x107f2f, _0x2d6d5b); 441 | }, 442 | 'gwrcF': function (_0x4b9eb5, _0x17d2f5) { 443 | return _0x4eeb0f['nRaoz'](_0x4b9eb5, _0x17d2f5); 444 | }, 445 | 'wbayg': function (_0x427c22, _0x2fdaad) { 446 | return _0x4eeb0f['nRaoz'](_0x427c22, _0x2fdaad); 447 | }, 448 | 'VDQrq': 'toJSON', 449 | 'iSncQ': function (_0x6bd905, _0x514337) { 450 | return _0x6bd905 > _0x514337; 451 | }, 452 | 'mHXkh': function (_0x368528, _0xb48d67) { 453 | return _0x4eeb0f['LcFin'](_0x368528, _0xb48d67); 454 | }, 455 | 'yoOdO': function (_0x41425e, _0x11e468) { 456 | return _0x41425e <= _0x11e468; 457 | }, 458 | 'IGblR': function (_0x11d200, _0x26abb6) { 459 | return _0x4eeb0f['rcBVT'](_0x11d200, _0x26abb6); 460 | }, 461 | 'vRQcl': function (_0x196cf4, _0x4e7e7f) { 462 | return _0x4eeb0f['eZvbe'](_0x196cf4, _0x4e7e7f); 463 | }, 464 | 'MvVwR': function (_0x34f211, _0x3c4974) { 465 | return _0x34f211(_0x3c4974); 466 | }, 467 | 'KRHnN': _0x4eeb0f['IIJws'], 468 | 'gfRMW': function (_0x56326b, _0x2af766) { 469 | return _0x4eeb0f['nRaoz'](_0x56326b, _0x2af766); 470 | }, 471 | 'mxxsu': function (_0x2bb397, _0x49cb9a) { 472 | return _0x2bb397 + _0x49cb9a; 473 | }, 474 | 'qbBAu': function (_0x32edc7, _0x265280) { 475 | return _0x4eeb0f['yzMfQ'](_0x32edc7, _0x265280); 476 | }, 477 | 'AMtEs': function (_0x2b3c25, _0x541a80) { 478 | return _0x4eeb0f['XIOqN'](_0x2b3c25, _0x541a80); 479 | }, 480 | 'nFwDL': function (_0x472500, _0x4c946b) { 481 | return _0x4eeb0f['XIOqN'](_0x472500, _0x4c946b); 482 | }, 483 | 'MtPiI': function (_0x3d37bd, _0x331695) { 484 | return _0x4eeb0f['XIOqN'](_0x3d37bd, _0x331695); 485 | }, 486 | 'wGUIG': function (_0x8dc814, _0x3e25b1) { 487 | return _0x4eeb0f['IwBGs'](_0x8dc814, _0x3e25b1); 488 | }, 489 | 'ycFHY': function (_0x217756, _0x5a2a42) { 490 | return _0x217756 + _0x5a2a42; 491 | }, 492 | 'LrSAD': function (_0x1f4d82, _0x318a8f) { 493 | return _0x1f4d82 < _0x318a8f; 494 | }, 495 | 'bHmZN': function (_0x1dd3a9, _0x466e17, _0x2260d8) { 496 | return _0x4eeb0f['HCjrQ'](_0x1dd3a9, _0x466e17, _0x2260d8); 497 | }, 498 | 'Yducx': function (_0x4109e6, _0x3a4564, _0x33cf81) { 499 | return _0x4109e6(_0x3a4564, _0x33cf81); 500 | }, 501 | 'Gyxyy': function (_0x51b611, _0x109e56, _0x27ccc0) { 502 | return _0x4eeb0f['HCjrQ'](_0x51b611, _0x109e56, _0x27ccc0); 503 | }, 504 | 'NZBmi': function (_0x4c886d, _0x216f94, _0x469c90) { 505 | return _0x4eeb0f['HCjrQ'](_0x4c886d, _0x216f94, _0x469c90); 506 | }, 507 | 'DImZI': function (_0x56bc7e, _0x578981) { 508 | return _0x4eeb0f['AIzDb'](_0x56bc7e, _0x578981); 509 | }, 510 | 'tDivX': function (_0x273ed1, _0x380d98) { 511 | return _0x4eeb0f['NxdrI'](_0x273ed1, _0x380d98); 512 | }, 513 | 'TfJdW': function (_0x4c6157) { 514 | return _0x4eeb0f['LUwPG'](_0x4c6157); 515 | }, 516 | 'ecEKd': function (_0x47e3f0, _0x17ff81) { 517 | return _0x4eeb0f['NxdrI'](_0x47e3f0, _0x17ff81); 518 | }, 519 | 'kKGQe': function (_0x423a46, _0xbf5917) { 520 | return _0x4eeb0f['IwBGs'](_0x423a46, _0xbf5917); 521 | }, 522 | 'jnaam': function (_0x94ce98, _0x4bad6e) { 523 | return _0x4eeb0f['oQeNp'](_0x94ce98, _0x4bad6e); 524 | }, 525 | 'eeohb': function (_0x2f4184, _0x629bb9) { 526 | return _0x4eeb0f['lGmrZ'](_0x2f4184, _0x629bb9); 527 | }, 528 | 'GbaUR': function (_0x1597d9) { 529 | return _0x4eeb0f['LUwPG'](_0x1597d9); 530 | }, 531 | 'fDdJv': function (_0x17b881, _0x29e777) { 532 | return _0x17b881 + _0x29e777; 533 | }, 534 | 'AgHJY': function (_0x1f00e7) { 535 | return _0x1f00e7(); 536 | }, 537 | 'hMvJG': function (_0x3a98f7, _0xc3607b) { 538 | return _0x4eeb0f['ysedV'](_0x3a98f7, _0xc3607b); 539 | }, 540 | 'RZeUQ': function (_0x2def57, _0x45b465) { 541 | return _0x2def57 >= _0x45b465; 542 | }, 543 | 'endfM': function (_0x4a9a85, _0x38d6ec) { 544 | return _0x4eeb0f['AIzDb'](_0x4a9a85, _0x38d6ec); 545 | }, 546 | 'ALniQ': function (_0x79ad58, _0x1360ab) { 547 | return _0x79ad58 != _0x1360ab; 548 | }, 549 | 'VVeQe': function (_0x39d208, _0x3d2235) { 550 | return _0x4eeb0f['OZjaJ'](_0x39d208, _0x3d2235); 551 | }, 552 | 'iRsDl': function (_0x47b456, _0x5d0eb6) { 553 | return _0x4eeb0f['lGmrZ'](_0x47b456, _0x5d0eb6); 554 | }, 555 | 'Xhsmz': function (_0x9100b8, _0x11c4bc) { 556 | return _0x9100b8 < _0x11c4bc; 557 | }, 558 | 'GYVlu': function (_0x3dc15d, _0x11ee95) { 559 | return _0x4eeb0f['IwBGs'](_0x3dc15d, _0x11ee95); 560 | }, 561 | 'YydmY': function (_0x47eecf, _0xd00540) { 562 | return _0x4eeb0f['OZjaJ'](_0x47eecf, _0xd00540); 563 | }, 564 | 'LMyTq': function (_0xaba942, _0x425dc1) { 565 | return _0x4eeb0f['NxdrI'](_0xaba942, _0x425dc1); 566 | }, 567 | 'yjsru': function (_0x2861a9, _0x75778) { 568 | return _0x4eeb0f['ieIhY'](_0x2861a9, _0x75778); 569 | }, 570 | 'egPym': '1|4|2|3|0', 571 | 'snzrN': function (_0x5262b8, _0x242ac5) { 572 | return _0x4eeb0f['IwBGs'](_0x5262b8, _0x242ac5); 573 | }, 574 | 'kFsxf': function (_0x42a2a7, _0x39e1f9) { 575 | return _0x4eeb0f['ieIhY'](_0x42a2a7, _0x39e1f9); 576 | }, 577 | 'FqfZy': _0x4eeb0f['jWFEf'], 578 | 'hiNYj': function (_0x218800, _0x4e4ab0) { 579 | return _0x4eeb0f['gVwKj'](_0x218800, _0x4e4ab0); 580 | }, 581 | 'ofOPe': function (_0x36df79, _0x3943b4) { 582 | return _0x4eeb0f['pnbIy'](_0x36df79, _0x3943b4); 583 | }, 584 | 'TikKY': _0x4eeb0f['oWzxS'], 585 | 'rHYVa': function (_0x231458, _0x55db30) { 586 | return _0x4eeb0f['gVwKj'](_0x231458, _0x55db30); 587 | }, 588 | 'DYuUU': _0x4eeb0f['tamnc'], 589 | 'SBEes': function (_0x48755f, _0xd59e9d) { 590 | return _0x4eeb0f['gVwKj'](_0x48755f, _0xd59e9d); 591 | }, 592 | 'lWlzb': function (_0x310892, _0x2899a6) { 593 | return _0x4eeb0f['gVwKj'](_0x310892, _0x2899a6); 594 | }, 595 | 'mgBrM': function (_0x4feb4f, _0x478e09) { 596 | return _0x4eeb0f['PIohJ'](_0x4feb4f, _0x478e09); 597 | }, 598 | 'wkCNu': function (_0x5f497a) { 599 | return _0x4eeb0f['LUwPG'](_0x5f497a); 600 | }, 601 | 'kMUuc': function (_0x276b9c, _0x568925) { 602 | return _0x4eeb0f['PIohJ'](_0x276b9c, _0x568925); 603 | }, 604 | 'IBZcU': function (_0x386336) { 605 | return _0x4eeb0f['HhJGs'](_0x386336); 606 | }, 607 | 'jWTZK': function (_0x5ab6f6, _0x477827) { 608 | return _0x4eeb0f['JxcFr'](_0x5ab6f6, _0x477827); 609 | }, 610 | 'ZAJUh': function (_0x527559, _0x1cd1b8) { 611 | return _0x4eeb0f['JxcFr'](_0x527559, _0x1cd1b8); 612 | }, 613 | 'KJQFG': function (_0x451bf4, _0xcda06a) { 614 | return _0x4eeb0f['SbxpF'](_0x451bf4, _0xcda06a); 615 | }, 616 | 'nalzl': function (_0x20e9ef, _0x51c1f9) { 617 | return _0x4eeb0f['pSiEo'](_0x20e9ef, _0x51c1f9); 618 | }, 619 | 'PlXmJ': function (_0x5b5721, _0x366866) { 620 | return _0x4eeb0f['pSiEo'](_0x5b5721, _0x366866); 621 | }, 622 | 'MIzBX': function (_0x2fd833) { 623 | return _0x4eeb0f['HhJGs'](_0x2fd833); 624 | }, 625 | 'FTxBu': function (_0x366a5e) { 626 | return _0x4eeb0f['HhJGs'](_0x366a5e); 627 | }, 628 | 'XMlJo': function (_0x5922d0) { 629 | return _0x4eeb0f['HhJGs'](_0x5922d0); 630 | }, 631 | 'qiKbz': function (_0x384b83, _0x3abdc5, _0x23817e, _0x21ea1c) { 632 | return _0x4eeb0f['XXedW'](_0x384b83, _0x3abdc5, _0x23817e, _0x21ea1c); 633 | }, 634 | 'qUvwH': function (_0x3a6bee, _0x1217a7) { 635 | return _0x4eeb0f['IYBFC'](_0x3a6bee, _0x1217a7); 636 | } 637 | }; 638 | _0x316a1c || (_0x316a1c = _0x211a8c[_0x4eeb0f['fPxyA']]()); 639 | _0x2daf34 || (_0x2daf34 = _0x211a8c[_0x4eeb0f['fPxyA']]()); 640 | var _0x3b259b = _0x316a1c[_0x4eeb0f['UtwWn']] || _0x211a8c[_0x4eeb0f['UtwWn']], _0x3285fb = _0x316a1c['String'] || _0x211a8c[_0x4eeb0f['JJeKi']], _0x446edd = _0x316a1c[_0x4eeb0f['fPxyA']] || _0x211a8c[_0x4eeb0f['fPxyA']], _0x2079bf = _0x316a1c[_0x4eeb0f['cvyvX']] || _0x211a8c[_0x4eeb0f['cvyvX']], _0x551b05 = _0x316a1c[_0x4eeb0f['reDxJ']] || _0x211a8c[_0x4eeb0f['reDxJ']], _0x3438ee = _0x316a1c[_0x4eeb0f['vgSrM']] || _0x211a8c[_0x4eeb0f['vgSrM']], _0x492af4 = _0x316a1c[_0x4eeb0f['yrVPF']] || _0x211a8c['Math'], _0x16cdef = _0x316a1c[_0x4eeb0f['kQXGT']] || _0x211a8c['JSON']; 641 | if (_0x4eeb0f['SbxpF'](typeof _0x16cdef, 'object') && _0x16cdef) { 642 | _0x2daf34['stringify'] = _0x16cdef['stringify']; 643 | _0x2daf34['parse'] = _0x16cdef['parse']; 644 | } 645 | var _0x121b91 = _0x446edd['prototype'], _0x55d5eb = _0x121b91['toString'], _0x46d96e, _0x5c9475, _0x56a5b8; 646 | var _0x54bf6f = new _0x2079bf(-0xc782b5b800cec); 647 | try { 648 | _0x54bf6f = _0x4eeb0f['SbxpF'](_0x54bf6f['getUTCFullYear'](), -0x1aac4) && _0x4eeb0f['IYBFC'](_0x54bf6f['getUTCMonth'](), 0x0) && _0x4eeb0f['IYBFC'](_0x54bf6f['getUTCDate'](), 0x1) && _0x4eeb0f['SbxpF'](_0x54bf6f['getUTCHours'](), 0xa) && _0x4eeb0f['taJZh'](_0x54bf6f['getUTCMinutes'](), 0x25) && _0x54bf6f['getUTCSeconds']() == 0x6 && _0x54bf6f['getUTCMilliseconds']() == 0x2c4; 649 | } catch (_0x362cc1) { 650 | } 651 | function _0x3e6dad(_0x2f47db) { 652 | if (_0x3d7ea1['ofzdj'](_0x3e6dad[_0x2f47db], _0x56a5b8)) { 653 | return _0x3e6dad[_0x2f47db]; 654 | } 655 | var _0x3dc44b; 656 | if (_0x3d7ea1['SRBWM'](_0x2f47db, _0x3d7ea1['CBeXt'])) { 657 | _0x3dc44b = 'a'[0x0] != 'a'; 658 | } else if (_0x3d7ea1['GhCad'](_0x2f47db, _0x3d7ea1['FIXiH'])) { 659 | _0x3dc44b = _0x3d7ea1['MnxTf'](_0x3e6dad, _0x3d7ea1['pZWmm']) && _0x3d7ea1['ZjCPP'](_0x3e6dad, _0x3d7ea1['hCQlJ']); 660 | } else { 661 | var _0x3839dd, _0xe4f7b6 = _0x3d7ea1['pqMHh']; 662 | if (_0x3d7ea1['GhCad'](_0x2f47db, 'json-stringify')) { 663 | var _0x3999ba = _0x2daf34['stringify'], _0x12d13d = _0x3d7ea1['GhCad'](typeof _0x3999ba, _0x3d7ea1['wOqLR']) && _0x54bf6f; 664 | if (_0x12d13d) { 665 | (_0x3839dd = function () { 666 | return 0x1; 667 | })['toJSON'] = _0x3839dd; 668 | try { 669 | _0x12d13d = _0x3d7ea1['AqlKj'](_0x3d7ea1['ZjCPP'](_0x3999ba, 0x0), '0') && _0x3d7ea1['AqlKj'](_0x3999ba(new _0x3b259b()), '0') && _0x3d7ea1['GhCad'](_0x3d7ea1['BHlrV'](_0x3999ba, new _0x3285fb()), '\x22\x22') && _0x3d7ea1['wkbaD'](_0x3999ba, _0x55d5eb) === _0x56a5b8 && _0x3d7ea1['UKAau'](_0x3999ba, _0x56a5b8) === _0x56a5b8 && _0x3d7ea1['zZNuE'](_0x3d7ea1['WNtqx'](_0x3999ba), _0x56a5b8) && _0x3d7ea1['UKAau'](_0x3999ba, _0x3839dd) === '1' && _0x3d7ea1['xiSHW'](_0x3d7ea1['UKAau'](_0x3999ba, [_0x3839dd]), '[1]') && _0x3d7ea1['UKAau'](_0x3999ba, [_0x56a5b8]) == _0x3d7ea1['wkOtw'] && _0x3d7ea1['TdAKL'](_0x3999ba(null), 'null') && _0x3d7ea1['UOMmJ'](_0x3999ba, [ 670 | _0x56a5b8, 671 | _0x55d5eb, 672 | null 673 | ]) == _0x3d7ea1['rCKVB'] && _0x3d7ea1['TdAKL'](_0x3999ba({ 674 | 'a': [ 675 | _0x3839dd, 676 | !![], 677 | ![], 678 | null, 679 | _0x3d7ea1['TbhET'] 680 | ] 681 | }), _0xe4f7b6) && _0x3d7ea1['zZNuE'](_0x3d7ea1['uBxCf'](_0x3999ba, null, _0x3839dd), '1') && _0x3d7ea1['ApLGk'](_0x3999ba([ 682 | 0x1, 683 | 0x2 684 | ], null, 0x1), _0x3d7ea1['OwxeN']) && _0x3d7ea1['UOMmJ'](_0x3999ba, new _0x2079bf(-0x1eb208c2dc0000)) == '\x22-271821-04-20T00:00:00.000Z\x22' && _0x3d7ea1['UOMmJ'](_0x3999ba, new _0x2079bf(0x1eb208c2dc0000)) == '\x22+275760-09-13T00:00:00.000Z\x22' && _0x3d7ea1['ApLGk'](_0x3d7ea1['ARfmW'](_0x3999ba, new _0x2079bf(-0x3891c6b58c00)), _0x3d7ea1['xgFZr']) && _0x3d7ea1['pdQKW'](_0x3d7ea1['xzIup'](_0x3999ba, new _0x2079bf(-0x1)), _0x3d7ea1['nRFnb']); 685 | } catch (_0x13f8c6) { 686 | _0x12d13d = ![]; 687 | } 688 | } 689 | _0x3dc44b = _0x12d13d; 690 | } 691 | if (_0x3d7ea1['KMiDn'](_0x2f47db, _0x3d7ea1['hCQlJ'])) { 692 | var _0xa2b2a4 = _0x2daf34['parse']; 693 | if (_0x3d7ea1['ainGk'](typeof _0xa2b2a4, _0x3d7ea1['wOqLR'])) { 694 | try { 695 | if (_0x3d7ea1['zZNuE'](_0xa2b2a4('0'), 0x0) && !_0xa2b2a4(![])) { 696 | _0x3839dd = _0x3d7ea1['AGExd'](_0xa2b2a4, _0xe4f7b6); 697 | var _0x3f8b20 = _0x3839dd['a']['length'] == 0x5 && _0x3d7ea1['xCNPL'](_0x3839dd['a'][0x0], 0x1); 698 | if (_0x3f8b20) { 699 | try { 700 | _0x3f8b20 = !_0x3d7ea1['EmcWG'](_0xa2b2a4, _0x3d7ea1['qHxLA']); 701 | } catch (_0x492329) { 702 | } 703 | if (_0x3f8b20) { 704 | try { 705 | _0x3f8b20 = _0xa2b2a4('01') !== 0x1; 706 | } catch (_0x2013eb) { 707 | } 708 | } 709 | if (_0x3f8b20) { 710 | try { 711 | _0x3f8b20 = _0x3d7ea1['fgefx'](_0x3d7ea1['GqWGS'](_0xa2b2a4, '1.'), 0x1); 712 | } catch (_0x4bf035) { 713 | } 714 | } 715 | } 716 | } 717 | } catch (_0x414b44) { 718 | _0x3f8b20 = ![]; 719 | } 720 | } 721 | _0x3dc44b = _0x3f8b20; 722 | } 723 | } 724 | return _0x3e6dad[_0x2f47db] = !!_0x3dc44b; 725 | } 726 | if (!_0x3e6dad(_0x4eeb0f['VOOKO'])) { 727 | var _0x4aa5fb = _0x4eeb0f['RWync'], _0x31a69f = _0x4eeb0f['aIjHw'], _0x3042d1 = _0x4eeb0f['PepER'], _0x52a29e = _0x4eeb0f['kPRbR'], _0x1fea6e = '[object\x20Array]', _0x3a5355 = _0x4eeb0f['xylhM']; 728 | var _0x3c75d8 = _0x4eeb0f['wLDEJ'](_0x3e6dad, _0x4eeb0f['xcBtf']); 729 | if (!_0x54bf6f) { 730 | var _0x1653ea = _0x492af4['floor']; 731 | var _0x5e2102 = [ 732 | 0x0, 733 | 0x1f, 734 | 0x3b, 735 | 0x5a, 736 | 0x78, 737 | 0x97, 738 | 0xb5, 739 | 0xd4, 740 | 0xf3, 741 | 0x111, 742 | 0x130, 743 | 0x14e 744 | ]; 745 | var _0x230079 = function (_0xfd559d, _0x4e255b) { 746 | return _0x4eeb0f['xFIWq'](_0x4eeb0f['fwZed'](_0x4eeb0f['rkpeY'](_0x4eeb0f['chPIl'](_0x5e2102[_0x4e255b], _0x4eeb0f['BDoSI'](0x16d, _0x4eeb0f['fwZed'](_0xfd559d, 0x7b2))), _0x1653ea(_0x4eeb0f['gPwdD'](_0x4eeb0f['TYgBw'](_0x4eeb0f['fwZed'](_0xfd559d, 0x7b1), _0x4e255b = +(_0x4e255b > 0x1)), 0x4))), _0x4eeb0f['plTcp'](_0x1653ea, _0x4eeb0f['XKqTe'](_0x4eeb0f['fwZed'](_0xfd559d, 0x76d), _0x4e255b) / 0x64)), _0x1653ea(_0x4eeb0f['gPwdD'](_0x4eeb0f['ErziL'](_0x4eeb0f['fwZed'](_0xfd559d, 0x641), _0x4e255b), 0x190))); 747 | }; 748 | } 749 | if (!(_0x46d96e = _0x121b91['hasOwnProperty'])) { 750 | _0x46d96e = function (_0x3cdd9a) { 751 | var _0x3f677f = _0x3d7ea1['UuzbN']['split']('|'), _0x481fe5 = 0x0; 752 | while (!![]) { 753 | switch (_0x3f677f[_0x481fe5++]) { 754 | case '0': 755 | _0x10f738 = null; 756 | continue; 757 | case '1': 758 | return _0x46d96e['call'](this, _0x3cdd9a); 759 | case '2': 760 | var _0x3c6097 = { 761 | 'sFVwd': function (_0x3d6d49, _0x1eeea8) { 762 | return _0x3d7ea1['XEbIg'](_0x3d6d49, _0x1eeea8); 763 | } 764 | }; 765 | continue; 766 | case '3': 767 | if (_0x3d7ea1['JGXSV']((_0x10f738['__proto__'] = null, _0x10f738['__proto__'] = { 'toString': 0x1 }, _0x10f738)['toString'], _0x55d5eb)) { 768 | _0x46d96e = function (_0x3571f6) { 769 | var _0x261dfc = this['__proto__'], _0x57f75c = _0x3c6097['sFVwd'](_0x3571f6, (this['__proto__'] = null, this)); 770 | this['__proto__'] = _0x261dfc; 771 | return _0x57f75c; 772 | }; 773 | } else { 774 | _0xa260c6 = _0x10f738['constructor']; 775 | _0x46d96e = function (_0x1312f5) { 776 | var _0x1193d6 = (this['constructor'] || _0xa260c6)['prototype']; 777 | return _0x3d7ea1['BHbjT'](_0x1312f5, this) && !(_0x3d7ea1['fbeCR'](_0x1312f5, _0x1193d6) && this[_0x1312f5] === _0x1193d6[_0x1312f5]); 778 | }; 779 | } 780 | continue; 781 | case '4': 782 | var _0x10f738 = {}, _0xa260c6; 783 | continue; 784 | } 785 | break; 786 | } 787 | }; 788 | } 789 | _0x5c9475 = function (_0x12e9fd, _0x2f5e3f) { 790 | var _0x22a744 = { 791 | 'nlrtS': function (_0x167d3e, _0x374673) { 792 | return _0x4eeb0f['JgnXM'](_0x167d3e, _0x374673); 793 | }, 794 | 'snmcS': function (_0x177293, _0x13ffd6) { 795 | return _0x4eeb0f['AIzDb'](_0x177293, _0x13ffd6); 796 | }, 797 | 'dgeBG': _0x4eeb0f['LmWUQ'], 798 | 'mFJuK': function (_0x40239f, _0x3fa283) { 799 | return _0x4eeb0f['plTcp'](_0x40239f, _0x3fa283); 800 | } 801 | }; 802 | var _0x15b0ae = 0x0, _0x517f87, _0x4af2db, _0x493437; 803 | (_0x517f87 = function () { 804 | this['valueOf'] = 0x0; 805 | })['prototype']['valueOf'] = 0x0; 806 | _0x4af2db = new _0x517f87(); 807 | for (_0x493437 in _0x4af2db) { 808 | if (_0x46d96e['call'](_0x4af2db, _0x493437)) { 809 | _0x15b0ae++; 810 | } 811 | } 812 | _0x517f87 = _0x4af2db = null; 813 | if (!_0x15b0ae) { 814 | _0x4af2db = [ 815 | _0x4eeb0f['fscyL'], 816 | _0x4eeb0f['dfGtJ'], 817 | _0x4eeb0f['UHAjC'], 818 | _0x4eeb0f['KQGHw'], 819 | _0x4eeb0f['TNYBY'], 820 | _0x4eeb0f['Wtstk'], 821 | _0x4eeb0f['ESmaq'] 822 | ]; 823 | _0x5c9475 = function (_0x5a4fa2, _0x52b1bd) { 824 | var _0x92c377 = _0x22a744['nlrtS'](_0x55d5eb['call'](_0x5a4fa2), _0x4aa5fb), _0x493437, _0x2c6ad3; 825 | var _0x23c93f = !_0x92c377 && _0x22a744['snmcS'](typeof _0x5a4fa2['constructor'], _0x22a744['dgeBG']) && _0x43469f[typeof _0x5a4fa2['hasOwnProperty']] && _0x5a4fa2['hasOwnProperty'] || _0x46d96e; 826 | for (_0x493437 in _0x5a4fa2) { 827 | if (!(_0x92c377 && _0x22a744['nlrtS'](_0x493437, 'prototype')) && _0x23c93f['call'](_0x5a4fa2, _0x493437)) { 828 | _0x22a744['mFJuK'](_0x52b1bd, _0x493437); 829 | } 830 | } 831 | for (_0x2c6ad3 = _0x4af2db['length']; _0x493437 = _0x4af2db[--_0x2c6ad3]; _0x23c93f['call'](_0x5a4fa2, _0x493437) && _0x22a744['mFJuK'](_0x52b1bd, _0x493437)); 832 | }; 833 | } else if (_0x4eeb0f['QNVqF'](_0x15b0ae, 0x2)) { 834 | _0x5c9475 = function (_0x1227b2, _0x3450fb) { 835 | var _0x4af2db = {}, _0x2d8577 = _0x55d5eb['call'](_0x1227b2) == _0x4aa5fb, _0x493437; 836 | for (_0x493437 in _0x1227b2) { 837 | if (!(_0x2d8577 && _0x493437 == _0x3d7ea1['UTFTS']) && !_0x46d96e['call'](_0x4af2db, _0x493437) && (_0x4af2db[_0x493437] = 0x1) && _0x46d96e['call'](_0x1227b2, _0x493437)) { 838 | _0x3d7ea1['gOatN'](_0x3450fb, _0x493437); 839 | } 840 | } 841 | }; 842 | } else { 843 | _0x5c9475 = function (_0xa17f5d, _0x444493) { 844 | var _0x58e7fe = _0x3d7ea1['ainGk'](_0x55d5eb['call'](_0xa17f5d), _0x4aa5fb), _0x493437, _0x390c81; 845 | for (_0x493437 in _0xa17f5d) { 846 | if (!(_0x58e7fe && _0x493437 == 'prototype') && _0x46d96e['call'](_0xa17f5d, _0x493437) && !(_0x390c81 = _0x3d7ea1['xCNPL'](_0x493437, _0x3d7ea1['Xxmyg']))) { 847 | _0x444493(_0x493437); 848 | } 849 | } 850 | if (_0x390c81 || _0x46d96e['call'](_0xa17f5d, _0x493437 = _0x3d7ea1['Xxmyg'])) { 851 | _0x444493(_0x493437); 852 | } 853 | }; 854 | } 855 | return _0x4eeb0f['TfHiU'](_0x5c9475, _0x12e9fd, _0x2f5e3f); 856 | }; 857 | if (!_0x3e6dad(_0x4eeb0f['ZZKEe'])) { 858 | var _0x91925e = { 859 | 92: '\x5c\x5c', 860 | 34: '\x5c\x22', 861 | 8: '\x5cb', 862 | 12: '\x5cf', 863 | 10: '\x5cn', 864 | 13: '\x5cr', 865 | 9: '\x5ct' 866 | }; 867 | var _0x2c7624 = _0x4eeb0f['EfALB']; 868 | var _0x21935f = function (_0x2d49b5, _0x1e0107) { 869 | return _0x3d7ea1['DqXff'](_0x2c7624, _0x3d7ea1['RYJix'](_0x1e0107, 0x0))['slice'](-_0x2d49b5); 870 | }; 871 | var _0x20c105 = '\x5cu00'; 872 | var _0x2f4e97 = function (_0xda75a2) { 873 | var _0x2a3634 = '\x22', _0x34d1c7 = 0x0, _0x5452a7 = _0xda75a2['length'], _0x3fb45e = !_0x3c75d8 || _0x4eeb0f['yjocL'](_0x5452a7, 0xa); 874 | var _0x1121df = _0x3fb45e && (_0x3c75d8 ? _0xda75a2['split']('') : _0xda75a2); 875 | for (; _0x4eeb0f['NxdrI'](_0x34d1c7, _0x5452a7); _0x34d1c7++) { 876 | var _0x228ddd = _0xda75a2['charCodeAt'](_0x34d1c7); 877 | switch (_0x228ddd) { 878 | case 0x8: 879 | case 0x9: 880 | case 0xa: 881 | case 0xc: 882 | case 0xd: 883 | case 0x22: 884 | case 0x5c: 885 | _0x2a3634 += _0x91925e[_0x228ddd]; 886 | break; 887 | default: 888 | if (_0x4eeb0f['NxdrI'](_0x228ddd, 0x20)) { 889 | _0x2a3634 += _0x20c105 + _0x4eeb0f['BKgTu'](_0x21935f, 0x2, _0x228ddd['toString'](0x10)); 890 | break; 891 | } 892 | _0x2a3634 += _0x3fb45e ? _0x1121df[_0x34d1c7] : _0xda75a2['charAt'](_0x34d1c7); 893 | } 894 | } 895 | return _0x2a3634 + '\x22'; 896 | }; 897 | var _0x522266 = function (_0x4cd2b8, _0x561f2d, _0x16134d, _0x10fe92, _0x886ca7, _0x12aa13, _0x867a4f) { 898 | var _0x423b62 = _0x3d7ea1['UcISs']['split']('|'), _0x156a75 = 0x0; 899 | while (!![]) { 900 | switch (_0x423b62[_0x156a75++]) { 901 | case '0': 902 | try { 903 | _0x15a99a = _0x561f2d[_0x4cd2b8]; 904 | } catch (_0x2ff19c) { 905 | } 906 | continue; 907 | case '1': 908 | if (_0x3d7ea1['xCNPL'](_0x15a99a, null)) { 909 | return _0x3d7ea1['jcELh']; 910 | } 911 | continue; 912 | case '2': 913 | if (_0x3d7ea1['ainGk'](_0x4f4e22, _0x3a5355)) { 914 | return _0x3d7ea1['zNXPZ']('', _0x15a99a); 915 | } else if (_0x4f4e22 == _0x3042d1) { 916 | return _0x3d7ea1['NayAA'](_0x15a99a, _0x3d7ea1['GWrML'](-0x1, 0x0)) && _0x3d7ea1['kkdxN'](_0x15a99a, 0x1 / 0x0) ? _0x3d7ea1['zNXPZ']('', _0x15a99a) : _0x3d7ea1['jcELh']; 917 | } else if (_0x3d7ea1['ukxRU'](_0x4f4e22, _0x52a29e)) { 918 | return _0x3d7ea1['lvJGW'](_0x2f4e97, '' + _0x15a99a); 919 | } 920 | continue; 921 | case '3': 922 | _0x4f4e22 = _0x55d5eb['call'](_0x15a99a); 923 | continue; 924 | case '4': 925 | if (_0x3d7ea1['wUSAL'](typeof _0x15a99a, _0x3d7ea1['mIlCL'])) { 926 | var _0x52cce1 = '2|4|6|5|7|3|1|0'['split']('|'), _0x282865 = 0x0; 927 | while (!![]) { 928 | switch (_0x52cce1[_0x282865++]) { 929 | case '0': 930 | return _0x28f59e; 931 | case '1': 932 | _0x867a4f['pop'](); 933 | continue; 934 | case '2': 935 | for (_0x25badd = _0x867a4f['length']; _0x25badd--;) { 936 | if (_0x867a4f[_0x25badd] === _0x15a99a) { 937 | throw _0x3d7ea1['DPdRl'](_0x3438ee); 938 | } 939 | } 940 | continue; 941 | case '3': 942 | if (_0x3d7ea1['ZkaZr'](_0x4f4e22, _0x1fea6e)) { 943 | for (_0x5022b6 = 0x0, _0x25badd = _0x15a99a['length']; _0x3d7ea1['kkdxN'](_0x5022b6, _0x25badd); _0x5022b6++) { 944 | _0x1c8389 = _0x3d7ea1['zjICl'](_0x522266, _0x5022b6, _0x15a99a, _0x16134d, _0x10fe92, _0x886ca7, _0x12aa13, _0x867a4f); 945 | _0x1fc7eb['push'](_0x1c8389 === _0x56a5b8 ? _0x3d7ea1['jcELh'] : _0x1c8389); 946 | } 947 | _0x28f59e = _0x1fc7eb['length'] ? _0x886ca7 ? _0x3d7ea1['amsyw'](_0x3d7ea1['amsyw'](_0x3d7ea1['amsyw'](_0x3d7ea1['amsyw']('[\x0a', _0x12aa13), _0x1fc7eb['join'](_0x3d7ea1['amsyw'](',\x0a', _0x12aa13))), '\x0a') + _0x1e4f18, ']') : _0x3d7ea1['amsyw'](_0x3d7ea1['amsyw']('[', _0x1fc7eb['join'](',')), ']') : '[]'; 948 | } else { 949 | _0x3d7ea1['ulHNw'](_0x5c9475, _0x3d7ea1['TUocI'](_0x10fe92, _0x15a99a), function (_0x52bec2) { 950 | var _0xb0ddd7 = _0x3d7ea1['ubXcW'](_0x522266, _0x52bec2, _0x15a99a, _0x16134d, _0x10fe92, _0x886ca7, _0x12aa13, _0x867a4f); 951 | if (_0x3d7ea1['fgefx'](_0xb0ddd7, _0x56a5b8)) { 952 | _0x1fc7eb['push'](_0x3d7ea1['DqXff'](_0x3d7ea1['aGnYu'](_0x3d7ea1['xFXRi'](_0x3d7ea1['fDleW'](_0x2f4e97, _0x52bec2), ':'), _0x886ca7 ? '\x20' : ''), _0xb0ddd7)); 953 | } 954 | }); 955 | _0x28f59e = _0x1fc7eb['length'] ? _0x886ca7 ? _0x3d7ea1['amsyw'](_0x3d7ea1['gwrcF'](_0x3d7ea1['wbayg']('{\x0a' + _0x12aa13, _0x1fc7eb['join'](',\x0a' + _0x12aa13)) + '\x0a', _0x1e4f18), '}') : _0x3d7ea1['wbayg'](_0x3d7ea1['wbayg']('{', _0x1fc7eb['join'](',')), '}') : '{}'; 956 | } 957 | continue; 958 | case '4': 959 | _0x867a4f['push'](_0x15a99a); 960 | continue; 961 | case '5': 962 | _0x1e4f18 = _0x12aa13; 963 | continue; 964 | case '6': 965 | _0x1fc7eb = []; 966 | continue; 967 | case '7': 968 | _0x12aa13 += _0x886ca7; 969 | continue; 970 | } 971 | break; 972 | } 973 | } 974 | continue; 975 | case '5': 976 | var _0x15a99a, _0x4f4e22, _0x2d3b65, _0x398d84, _0x4ad09f, _0xc9e4b4, _0x27354b, _0x56c7da, _0x1a675f, _0x2da4b0, _0x1fc7eb, _0x1c8389, _0x5022b6, _0x25badd, _0x1e4f18, _0x28f59e; 977 | continue; 978 | case '6': 979 | if (_0x16134d) { 980 | _0x15a99a = _0x16134d['call'](_0x561f2d, _0x4cd2b8, _0x15a99a); 981 | } 982 | continue; 983 | case '7': 984 | if (_0x3d7ea1['ZkaZr'](typeof _0x15a99a, _0x3d7ea1['mIlCL']) && _0x15a99a) { 985 | _0x4f4e22 = _0x55d5eb['call'](_0x15a99a); 986 | if (_0x3d7ea1['ZkaZr'](_0x4f4e22, _0x31a69f) && !_0x46d96e['call'](_0x15a99a, _0x3d7ea1['VDQrq'])) { 987 | if (_0x3d7ea1['iSncQ'](_0x15a99a, -0x1 / 0x0) && _0x3d7ea1['kkdxN'](_0x15a99a, 0x1 / 0x0)) { 988 | if (_0x230079) { 989 | var _0x4230a7 = '1|0|6|7|8|2|3|5|4'['split']('|'), _0x2ce2b3 = 0x0; 990 | while (!![]) { 991 | switch (_0x4230a7[_0x2ce2b3++]) { 992 | case '0': 993 | for (_0x2d3b65 = _0x3d7ea1['mHXkh'](_0x3d7ea1['wbayg'](_0x3d7ea1['lvJGW'](_0x1653ea, _0x3d7ea1['GWrML'](_0x4ad09f, 365.2425)), 0x7b2), 0x1); _0x3d7ea1['yoOdO'](_0x3d7ea1['ulHNw'](_0x230079, _0x3d7ea1['wbayg'](_0x2d3b65, 0x1), 0x0), _0x4ad09f); _0x2d3b65++); 994 | continue; 995 | case '1': 996 | _0x4ad09f = _0x3d7ea1['IGblR'](_0x1653ea, _0x3d7ea1['GWrML'](_0x15a99a, 0x5265c00)); 997 | continue; 998 | case '2': 999 | _0x27354b = _0x3d7ea1['vRQcl'](_0x3d7ea1['IGblR'](_0x1653ea, _0xc9e4b4 / 0x36ee80), 0x18); 1000 | continue; 1001 | case '3': 1002 | _0x56c7da = _0x3d7ea1['vRQcl'](_0x3d7ea1['IGblR'](_0x1653ea, _0xc9e4b4 / 0xea60), 0x3c); 1003 | continue; 1004 | case '4': 1005 | _0x2da4b0 = _0xc9e4b4 % 0x3e8; 1006 | continue; 1007 | case '5': 1008 | _0x1a675f = _0x1653ea(_0xc9e4b4 / 0x3e8) % 0x3c; 1009 | continue; 1010 | case '6': 1011 | for (_0x398d84 = _0x3d7ea1['MvVwR'](_0x1653ea, _0x3d7ea1['GWrML'](_0x3d7ea1['mHXkh'](_0x4ad09f, _0x3d7ea1['ulHNw'](_0x230079, _0x2d3b65, 0x0)), 30.42)); _0x3d7ea1['ulHNw'](_0x230079, _0x2d3b65, _0x398d84 + 0x1) <= _0x4ad09f; _0x398d84++); 1012 | continue; 1013 | case '7': 1014 | _0x4ad09f = _0x3d7ea1['mHXkh'](_0x3d7ea1['wbayg'](0x1, _0x4ad09f), _0x230079(_0x2d3b65, _0x398d84)); 1015 | continue; 1016 | case '8': 1017 | _0xc9e4b4 = _0x3d7ea1['vRQcl'](_0x3d7ea1['wbayg'](_0x15a99a % 0x5265c00, 0x5265c00), 0x5265c00); 1018 | continue; 1019 | } 1020 | break; 1021 | } 1022 | } else { 1023 | var _0x4c57b6 = _0x3d7ea1['KRHnN']['split']('|'), _0x47a145 = 0x0; 1024 | while (!![]) { 1025 | switch (_0x4c57b6[_0x47a145++]) { 1026 | case '0': 1027 | _0x4ad09f = _0x15a99a['getUTCDate'](); 1028 | continue; 1029 | case '1': 1030 | _0x2d3b65 = _0x15a99a['getUTCFullYear'](); 1031 | continue; 1032 | case '2': 1033 | _0x56c7da = _0x15a99a['getUTCMinutes'](); 1034 | continue; 1035 | case '3': 1036 | _0x1a675f = _0x15a99a['getUTCSeconds'](); 1037 | continue; 1038 | case '4': 1039 | _0x27354b = _0x15a99a['getUTCHours'](); 1040 | continue; 1041 | case '5': 1042 | _0x398d84 = _0x15a99a['getUTCMonth'](); 1043 | continue; 1044 | case '6': 1045 | _0x2da4b0 = _0x15a99a['getUTCMilliseconds'](); 1046 | continue; 1047 | } 1048 | break; 1049 | } 1050 | } 1051 | _0x15a99a = _0x3d7ea1['wbayg'](_0x3d7ea1['gfRMW'](_0x3d7ea1['mxxsu'](_0x3d7ea1['qbBAu'](_0x3d7ea1['AMtEs'](_0x3d7ea1['nFwDL'](_0x3d7ea1['MtPiI'](_0x3d7ea1['MtPiI'](_0x3d7ea1['MtPiI'](_0x3d7ea1['MtPiI'](_0x3d7ea1['MtPiI'](_0x3d7ea1['yoOdO'](_0x2d3b65, 0x0) || _0x3d7ea1['wGUIG'](_0x2d3b65, 0x2710) ? _0x3d7ea1['ycFHY'](_0x3d7ea1['LrSAD'](_0x2d3b65, 0x0) ? '-' : '+', _0x3d7ea1['ulHNw'](_0x21935f, 0x6, _0x3d7ea1['LrSAD'](_0x2d3b65, 0x0) ? -_0x2d3b65 : _0x2d3b65)) : _0x3d7ea1['bHmZN'](_0x21935f, 0x4, _0x2d3b65), '-'), _0x21935f(0x2, _0x3d7ea1['ycFHY'](_0x398d84, 0x1))), '-'), _0x3d7ea1['Yducx'](_0x21935f, 0x2, _0x4ad09f)), 'T'), _0x3d7ea1['Yducx'](_0x21935f, 0x2, _0x27354b)), ':') + _0x21935f(0x2, _0x56c7da) + ':', _0x3d7ea1['Gyxyy'](_0x21935f, 0x2, _0x1a675f)), '.'), _0x3d7ea1['NZBmi'](_0x21935f, 0x3, _0x2da4b0)), 'Z'); 1052 | } else { 1053 | _0x15a99a = null; 1054 | } 1055 | } else if (_0x3d7ea1['ZkaZr'](typeof _0x15a99a['toJSON'], _0x3d7ea1['wOqLR']) && (_0x4f4e22 != _0x3042d1 && _0x4f4e22 != _0x52a29e && _0x3d7ea1['DImZI'](_0x4f4e22, _0x1fea6e) || _0x46d96e['call'](_0x15a99a, _0x3d7ea1['VDQrq']))) { 1056 | _0x15a99a = _0x15a99a['toJSON'](_0x4cd2b8); 1057 | } 1058 | } 1059 | continue; 1060 | } 1061 | break; 1062 | } 1063 | }; 1064 | _0x2daf34['stringify'] = function (_0x5cbd8a, _0x4b6797, _0xc26480) { 1065 | var _0x5a6683, _0x73bc0, _0x25aff4, _0xfdaaab; 1066 | if (_0x43469f[typeof _0x4b6797] && _0x4b6797) { 1067 | if ((_0xfdaaab = _0x55d5eb['call'](_0x4b6797)) == _0x4aa5fb) { 1068 | _0x73bc0 = _0x4b6797; 1069 | } else if (_0x4eeb0f['KfeMM'](_0xfdaaab, _0x1fea6e)) { 1070 | _0x25aff4 = {}; 1071 | for (var _0x33602b = 0x0, _0x586b37 = _0x4b6797['length'], _0x26990c; _0x4eeb0f['NxdrI'](_0x33602b, _0x586b37); _0x26990c = _0x4b6797[_0x33602b++], (_0xfdaaab = _0x55d5eb['call'](_0x26990c), _0x4eeb0f['TaOdZ'](_0xfdaaab, _0x52a29e) || _0x4eeb0f['CCFFm'](_0xfdaaab, _0x3042d1)) && (_0x25aff4[_0x26990c] = 0x1)); 1072 | } 1073 | } 1074 | if (_0xc26480) { 1075 | if ((_0xfdaaab = _0x55d5eb['call'](_0xc26480)) == _0x3042d1) { 1076 | if (_0x4eeb0f['BZxYf'](_0xc26480 -= _0x4eeb0f['eZvbe'](_0xc26480, 0x1), 0x0)) { 1077 | for (_0x5a6683 = '', _0x4eeb0f['BZxYf'](_0xc26480, 0xa) && (_0xc26480 = 0xa); _0x5a6683['length'] < _0xc26480; _0x5a6683 += '\x20'); 1078 | } 1079 | } else if (_0xfdaaab == _0x52a29e) { 1080 | _0x5a6683 = _0x4eeb0f['oQeNp'](_0xc26480['length'], 0xa) ? _0xc26480 : _0xc26480['slice'](0x0, 0xa); 1081 | } 1082 | } 1083 | return _0x522266('', (_0x26990c = {}, _0x26990c[''] = _0x5cbd8a, _0x26990c), _0x73bc0, _0x25aff4, _0x5a6683, '', []); 1084 | }; 1085 | } 1086 | if (!_0x4eeb0f['vLwaj'](_0x3e6dad, _0x4eeb0f['BHQSn'])) { 1087 | var _0x55226c = _0x3285fb['fromCharCode']; 1088 | var _0x536086 = { 1089 | 92: '\x5c', 1090 | 34: '\x22', 1091 | 47: '/', 1092 | 98: '', 1093 | 116: '\x09', 1094 | 110: '\x0a', 1095 | 102: '\x0c', 1096 | 114: '\x0d' 1097 | }; 1098 | var _0x540928, _0x4078be; 1099 | var _0x5be3f3 = function () { 1100 | _0x540928 = _0x4078be = null; 1101 | throw _0x551b05(); 1102 | }; 1103 | var _0x582927 = function () { 1104 | var _0x1e41f5 = _0x4078be, _0x28b97c = _0x1e41f5['length'], _0x3c8f95, _0x441121, _0x246a2d, _0x324f02, _0x5cff40; 1105 | while (_0x3d7ea1['tDivX'](_0x540928, _0x28b97c)) { 1106 | _0x5cff40 = _0x1e41f5['charCodeAt'](_0x540928); 1107 | switch (_0x5cff40) { 1108 | case 0x9: 1109 | case 0xa: 1110 | case 0xd: 1111 | case 0x20: 1112 | _0x540928++; 1113 | break; 1114 | case 0x7b: 1115 | case 0x7d: 1116 | case 0x5b: 1117 | case 0x5d: 1118 | case 0x3a: 1119 | case 0x2c: 1120 | _0x3c8f95 = _0x3c75d8 ? _0x1e41f5['charAt'](_0x540928) : _0x1e41f5[_0x540928]; 1121 | _0x540928++; 1122 | return _0x3c8f95; 1123 | case 0x22: 1124 | for (_0x3c8f95 = '@', _0x540928++; _0x3d7ea1['tDivX'](_0x540928, _0x28b97c);) { 1125 | _0x5cff40 = _0x1e41f5['charCodeAt'](_0x540928); 1126 | if (_0x3d7ea1['tDivX'](_0x5cff40, 0x20)) { 1127 | _0x3d7ea1['TfJdW'](_0x5be3f3); 1128 | } else if (_0x3d7ea1['ZkaZr'](_0x5cff40, 0x5c)) { 1129 | _0x5cff40 = _0x1e41f5['charCodeAt'](++_0x540928); 1130 | switch (_0x5cff40) { 1131 | case 0x5c: 1132 | case 0x22: 1133 | case 0x2f: 1134 | case 0x62: 1135 | case 0x74: 1136 | case 0x6e: 1137 | case 0x66: 1138 | case 0x72: 1139 | _0x3c8f95 += _0x536086[_0x5cff40]; 1140 | _0x540928++; 1141 | break; 1142 | case 0x75: 1143 | _0x441121 = ++_0x540928; 1144 | for (_0x246a2d = _0x540928 + 0x4; _0x3d7ea1['ecEKd'](_0x540928, _0x246a2d); _0x540928++) { 1145 | _0x5cff40 = _0x1e41f5['charCodeAt'](_0x540928); 1146 | if (!(_0x3d7ea1['kKGQe'](_0x5cff40, 0x30) && _0x5cff40 <= 0x39 || _0x5cff40 >= 0x61 && _0x3d7ea1['jnaam'](_0x5cff40, 0x66) || _0x3d7ea1['kKGQe'](_0x5cff40, 0x41) && _0x3d7ea1['eeohb'](_0x5cff40, 0x46))) { 1147 | _0x3d7ea1['GbaUR'](_0x5be3f3); 1148 | } 1149 | } 1150 | _0x3c8f95 += _0x3d7ea1['MvVwR'](_0x55226c, _0x3d7ea1['fDdJv']('0x', _0x1e41f5['slice'](_0x441121, _0x540928))); 1151 | break; 1152 | default: 1153 | _0x3d7ea1['AgHJY'](_0x5be3f3); 1154 | } 1155 | } else { 1156 | if (_0x3d7ea1['hMvJG'](_0x5cff40, 0x22)) { 1157 | break; 1158 | } 1159 | _0x5cff40 = _0x1e41f5['charCodeAt'](_0x540928); 1160 | _0x441121 = _0x540928; 1161 | while (_0x3d7ea1['RZeUQ'](_0x5cff40, 0x20) && _0x3d7ea1['endfM'](_0x5cff40, 0x5c) && _0x3d7ea1['ALniQ'](_0x5cff40, 0x22)) { 1162 | _0x5cff40 = _0x1e41f5['charCodeAt'](++_0x540928); 1163 | } 1164 | _0x3c8f95 += _0x1e41f5['slice'](_0x441121, _0x540928); 1165 | } 1166 | } 1167 | if (_0x3d7ea1['hMvJG'](_0x1e41f5['charCodeAt'](_0x540928), 0x22)) { 1168 | _0x540928++; 1169 | return _0x3c8f95; 1170 | } 1171 | _0x3d7ea1['AgHJY'](_0x5be3f3); 1172 | default: 1173 | _0x441121 = _0x540928; 1174 | if (_0x3d7ea1['VVeQe'](_0x5cff40, 0x2d)) { 1175 | _0x324f02 = !![]; 1176 | _0x5cff40 = _0x1e41f5['charCodeAt'](++_0x540928); 1177 | } 1178 | if (_0x3d7ea1['RZeUQ'](_0x5cff40, 0x30) && _0x3d7ea1['iRsDl'](_0x5cff40, 0x39)) { 1179 | if (_0x3d7ea1['VVeQe'](_0x5cff40, 0x30) && (_0x5cff40 = _0x1e41f5['charCodeAt'](_0x3d7ea1['fDdJv'](_0x540928, 0x1)), _0x3d7ea1['RZeUQ'](_0x5cff40, 0x30) && _0x3d7ea1['iRsDl'](_0x5cff40, 0x39))) { 1180 | _0x3d7ea1['AgHJY'](_0x5be3f3); 1181 | } 1182 | _0x324f02 = ![]; 1183 | for (; _0x3d7ea1['Xhsmz'](_0x540928, _0x28b97c) && (_0x5cff40 = _0x1e41f5['charCodeAt'](_0x540928), _0x3d7ea1['GYVlu'](_0x5cff40, 0x30) && _0x3d7ea1['iRsDl'](_0x5cff40, 0x39)); _0x540928++); 1184 | if (_0x3d7ea1['YydmY'](_0x1e41f5['charCodeAt'](_0x540928), 0x2e)) { 1185 | _0x246a2d = ++_0x540928; 1186 | for (; _0x3d7ea1['LMyTq'](_0x246a2d, _0x28b97c) && (_0x5cff40 = _0x1e41f5['charCodeAt'](_0x246a2d), _0x3d7ea1['GYVlu'](_0x5cff40, 0x30) && _0x3d7ea1['iRsDl'](_0x5cff40, 0x39)); _0x246a2d++); 1187 | if (_0x246a2d == _0x540928) { 1188 | _0x3d7ea1['AgHJY'](_0x5be3f3); 1189 | } 1190 | _0x540928 = _0x246a2d; 1191 | } 1192 | _0x5cff40 = _0x1e41f5['charCodeAt'](_0x540928); 1193 | if (_0x3d7ea1['yjsru'](_0x5cff40, 0x65) || _0x3d7ea1['yjsru'](_0x5cff40, 0x45)) { 1194 | var _0x114789 = _0x3d7ea1['egPym']['split']('|'), _0x234c16 = 0x0; 1195 | while (!![]) { 1196 | switch (_0x114789[_0x234c16++]) { 1197 | case '0': 1198 | _0x540928 = _0x246a2d; 1199 | continue; 1200 | case '1': 1201 | _0x5cff40 = _0x1e41f5['charCodeAt'](++_0x540928); 1202 | continue; 1203 | case '2': 1204 | for (_0x246a2d = _0x540928; _0x246a2d < _0x28b97c && (_0x5cff40 = _0x1e41f5['charCodeAt'](_0x246a2d), _0x3d7ea1['snzrN'](_0x5cff40, 0x30) && _0x3d7ea1['iRsDl'](_0x5cff40, 0x39)); _0x246a2d++); 1205 | continue; 1206 | case '3': 1207 | if (_0x3d7ea1['kFsxf'](_0x246a2d, _0x540928)) { 1208 | _0x5be3f3(); 1209 | } 1210 | continue; 1211 | case '4': 1212 | if (_0x3d7ea1['kFsxf'](_0x5cff40, 0x2b) || _0x3d7ea1['kFsxf'](_0x5cff40, 0x2d)) { 1213 | _0x540928++; 1214 | } 1215 | continue; 1216 | } 1217 | break; 1218 | } 1219 | } 1220 | return +_0x1e41f5['slice'](_0x441121, _0x540928); 1221 | } 1222 | if (_0x324f02) { 1223 | _0x5be3f3(); 1224 | } 1225 | if (_0x3d7ea1['kFsxf'](_0x1e41f5['slice'](_0x540928, _0x3d7ea1['fDdJv'](_0x540928, 0x4)), _0x3d7ea1['FqfZy'])) { 1226 | _0x540928 += 0x4; 1227 | return !![]; 1228 | } else if (_0x3d7ea1['hiNYj'](_0x1e41f5['slice'](_0x540928, _0x3d7ea1['ofOPe'](_0x540928, 0x5)), _0x3d7ea1['TikKY'])) { 1229 | _0x540928 += 0x5; 1230 | return ![]; 1231 | } else if (_0x1e41f5['slice'](_0x540928, _0x540928 + 0x4) == 'null') { 1232 | _0x540928 += 0x4; 1233 | return null; 1234 | } 1235 | _0x5be3f3(); 1236 | } 1237 | } 1238 | return '$'; 1239 | }; 1240 | var _0x47958b = function (_0x1b6a00) { 1241 | var _0x1b06ae, _0x59ac9e; 1242 | if (_0x3d7ea1['hiNYj'](_0x1b6a00, '$')) { 1243 | _0x3d7ea1['AgHJY'](_0x5be3f3); 1244 | } 1245 | if (_0x3d7ea1['rHYVa'](typeof _0x1b6a00, _0x3d7ea1['DYuUU'])) { 1246 | if (_0x3d7ea1['SBEes'](_0x3c75d8 ? _0x1b6a00['charAt'](0x0) : _0x1b6a00[0x0], '@')) { 1247 | return _0x1b6a00['slice'](0x1); 1248 | } 1249 | if (_0x3d7ea1['SBEes'](_0x1b6a00, '[')) { 1250 | _0x1b06ae = []; 1251 | for (;; _0x59ac9e || (_0x59ac9e = !![])) { 1252 | _0x1b6a00 = _0x3d7ea1['AgHJY'](_0x582927); 1253 | if (_0x3d7ea1['SBEes'](_0x1b6a00, ']')) { 1254 | break; 1255 | } 1256 | if (_0x59ac9e) { 1257 | if (_0x3d7ea1['lWlzb'](_0x1b6a00, ',')) { 1258 | _0x1b6a00 = _0x582927(); 1259 | if (_0x3d7ea1['lWlzb'](_0x1b6a00, ']')) { 1260 | _0x5be3f3(); 1261 | } 1262 | } else { 1263 | _0x5be3f3(); 1264 | } 1265 | } 1266 | if (_0x3d7ea1['mgBrM'](_0x1b6a00, ',')) { 1267 | _0x3d7ea1['wkCNu'](_0x5be3f3); 1268 | } 1269 | _0x1b06ae['push'](_0x3d7ea1['MvVwR'](_0x47958b, _0x1b6a00)); 1270 | } 1271 | return _0x1b06ae; 1272 | } else if (_0x3d7ea1['kMUuc'](_0x1b6a00, '{')) { 1273 | _0x1b06ae = {}; 1274 | for (;; _0x59ac9e || (_0x59ac9e = !![])) { 1275 | _0x1b6a00 = _0x3d7ea1['IBZcU'](_0x582927); 1276 | if (_0x3d7ea1['kMUuc'](_0x1b6a00, '}')) { 1277 | break; 1278 | } 1279 | if (_0x59ac9e) { 1280 | if (_0x3d7ea1['jWTZK'](_0x1b6a00, ',')) { 1281 | _0x1b6a00 = _0x3d7ea1['IBZcU'](_0x582927); 1282 | if (_0x3d7ea1['ZAJUh'](_0x1b6a00, '}')) { 1283 | _0x3d7ea1['IBZcU'](_0x5be3f3); 1284 | } 1285 | } else { 1286 | _0x5be3f3(); 1287 | } 1288 | } 1289 | if (_0x3d7ea1['KJQFG'](_0x1b6a00, ',') || _0x3d7ea1['nalzl'](typeof _0x1b6a00, 'string') || _0x3d7ea1['nalzl'](_0x3c75d8 ? _0x1b6a00['charAt'](0x0) : _0x1b6a00[0x0], '@') || _0x3d7ea1['PlXmJ'](_0x582927(), ':')) { 1290 | _0x3d7ea1['MIzBX'](_0x5be3f3); 1291 | } 1292 | _0x1b06ae[_0x1b6a00['slice'](0x1)] = _0x3d7ea1['MvVwR'](_0x47958b, _0x3d7ea1['FTxBu'](_0x582927)); 1293 | } 1294 | return _0x1b06ae; 1295 | } 1296 | _0x3d7ea1['XMlJo'](_0x5be3f3); 1297 | } 1298 | return _0x1b6a00; 1299 | }; 1300 | var _0x22639e = function (_0x41ee6f, _0x864acd, _0x14b4d5) { 1301 | var _0x4747d8 = _0x3d7ea1['qiKbz'](_0x47b56f, _0x41ee6f, _0x864acd, _0x14b4d5); 1302 | if (_0x3d7ea1['qUvwH'](_0x4747d8, _0x56a5b8)) { 1303 | delete _0x41ee6f[_0x864acd]; 1304 | } else { 1305 | _0x41ee6f[_0x864acd] = _0x4747d8; 1306 | } 1307 | }; 1308 | var _0x47b56f = function (_0x18209e, _0x174d9d, _0x1e5c78) { 1309 | var _0x3b1caa = { 1310 | 'SNIvG': function (_0x546439, _0x439519, _0xe46ca3, _0x3aba68) { 1311 | return _0x4eeb0f['oLgQL'](_0x546439, _0x439519, _0xe46ca3, _0x3aba68); 1312 | } 1313 | }; 1314 | var _0x4b8701 = _0x18209e[_0x174d9d], _0x178756; 1315 | if (typeof _0x4b8701 == 'object' && _0x4b8701) { 1316 | if (_0x4eeb0f['CCFFm'](_0x55d5eb['call'](_0x4b8701), _0x1fea6e)) { 1317 | for (_0x178756 = _0x4b8701['length']; _0x178756--;) { 1318 | _0x4eeb0f['AxejU'](_0x22639e, _0x4b8701, _0x178756, _0x1e5c78); 1319 | } 1320 | } else { 1321 | _0x4eeb0f['HCjrQ'](_0x5c9475, _0x4b8701, function (_0x3509bc) { 1322 | _0x3b1caa['SNIvG'](_0x22639e, _0x4b8701, _0x3509bc, _0x1e5c78); 1323 | }); 1324 | } 1325 | } 1326 | return _0x1e5c78['call'](_0x18209e, _0x174d9d, _0x4b8701); 1327 | }; 1328 | _0x2daf34['parse'] = function (_0x2cc0a0, _0x45ede4) { 1329 | var _0x6ee2e5 = _0x4eeb0f['GpSvB']['split']('|'), _0x5676ce = 0x0; 1330 | while (!![]) { 1331 | switch (_0x6ee2e5[_0x5676ce++]) { 1332 | case '0': 1333 | if (_0x4eeb0f['HaWuM'](_0x582927) != '$') { 1334 | _0x4eeb0f['hvjdO'](_0x5be3f3); 1335 | } 1336 | continue; 1337 | case '1': 1338 | var _0x55512e, _0x4c907e; 1339 | continue; 1340 | case '2': 1341 | _0x540928 = 0x0; 1342 | continue; 1343 | case '3': 1344 | _0x55512e = _0x47958b(_0x582927()); 1345 | continue; 1346 | case '4': 1347 | _0x4078be = _0x4eeb0f['ErziL']('', _0x2cc0a0); 1348 | continue; 1349 | case '5': 1350 | _0x540928 = _0x4078be = null; 1351 | continue; 1352 | case '6': 1353 | return _0x45ede4 && _0x4eeb0f['CCFFm'](_0x55d5eb['call'](_0x45ede4), _0x4aa5fb) ? _0x4eeb0f['AxejU'](_0x47b56f, (_0x4c907e = {}, _0x4c907e[''] = _0x55512e, _0x4c907e), '', _0x45ede4) : _0x55512e; 1354 | } 1355 | break; 1356 | } 1357 | }; 1358 | } 1359 | } 1360 | _0x2daf34['runInContext'] = _0x415768; 1361 | return _0x2daf34; 1362 | } 1363 | if (_0x4eeb0f['IvMhj'](_0x12373f, !_0x1cabc2)) { 1364 | _0x4eeb0f['BOzBt'](_0x415768, _0x211a8c, _0x12373f); 1365 | } else { 1366 | var _0x1e9f1c = _0x211a8c['JSON'], _0x3a0930 = _0x211a8c[_0x4eeb0f['ADXrQ']], _0x360de8 = ![]; 1367 | var _0x3a6406 = _0x4eeb0f['oNCQS'](_0x415768, _0x211a8c, _0x211a8c[_0x4eeb0f['ADXrQ']] = { 1368 | 'noConflict': function () { 1369 | if (!_0x360de8) { 1370 | _0x360de8 = !![]; 1371 | _0x211a8c['JSON'] = _0x1e9f1c; 1372 | _0x211a8c['JSON3'] = _0x3a0930; 1373 | _0x1e9f1c = _0x3a0930 = null; 1374 | } 1375 | return _0x3a6406; 1376 | } 1377 | }); 1378 | _0x211a8c['JSON'] = { 1379 | 'parse': _0x3a6406['parse'], 1380 | 'stringify': _0x3a6406['stringify'] 1381 | }; 1382 | } 1383 | if (_0x1cabc2) { 1384 | _0x4eeb0f['vLwaj'](define, function () { 1385 | return _0x3a6406; 1386 | }); 1387 | } 1388 | }['call'](this)); -------------------------------------------------------------------------------- /test-data/test-obf6.js: -------------------------------------------------------------------------------- 1 | function hi() { 2 | var _0x11ab40 = function () { 3 | var _0x5bfc62 = !![]; 4 | return function (_0x354e9b, _0x541114) { 5 | var _0x452f2a = _0x5bfc62 ? function () { 6 | if (_0x541114) { 7 | var _0x1c4cf9 = _0x541114['apply'](_0x354e9b, arguments); 8 | _0x541114 = null; 9 | return _0x1c4cf9; 10 | } 11 | } : function () { 12 | }; 13 | _0x5bfc62 = ![]; 14 | return _0x452f2a; 15 | }; 16 | }(); 17 | (function () { 18 | _0x11ab40(this, function () { 19 | var _0x14112d = new RegExp('function\x20*\x5c(\x20*\x5c)'); 20 | var _0x19beb8 = new RegExp('\x5c+\x5c+\x20*(?:_0x(?:[a-f0-9]){4,6}|(?:\x5cb|\x5cd)[a-z0-9]{1,4}(?:\x5cb|\x5cd))', 'i'); 21 | var _0x3bab19 = _0xedcf12('init'); 22 | if (!_0x14112d['test'](_0x3bab19 + 'chain') || !_0x19beb8['test'](_0x3bab19 + 'input')) { 23 | _0x3bab19('0'); 24 | } else { 25 | _0xedcf12(); 26 | } 27 | })(); 28 | }()); 29 | console['log']('Hello\x20World!'); 30 | } 31 | setInterval(function () { 32 | _0xedcf12(); 33 | }, 0xfa0); 34 | hi(); 35 | function _0xedcf12(_0x4698d9) { 36 | function _0x43da5f(_0x12d960) { 37 | if (typeof _0x12d960 === 'string') { 38 | return function (_0x53a4b6) { 39 | }['constructor']('while\x20(true)\x20{}')['apply']('counter'); 40 | } else { 41 | if (('' + _0x12d960 / _0x12d960)['length'] !== 0x1 || _0x12d960 % 0x14 === 0x0) { 42 | (function () { 43 | return !![]; 44 | }['constructor']('debu' + 'gger')['call']('action')); 45 | } else { 46 | (function () { 47 | return ![]; 48 | }['constructor']('debu' + 'gger')['apply']('stateObject')); 49 | } 50 | } 51 | _0x43da5f(++_0x12d960); 52 | } 53 | try { 54 | if (_0x4698d9) { 55 | return _0x43da5f; 56 | } else { 57 | _0x43da5f(0x0); 58 | } 59 | } catch (_0x1c4d11) { 60 | } 61 | } -------------------------------------------------------------------------------- /test-data/test-obf7.js: -------------------------------------------------------------------------------- 1 | while (!![]) { 2 | break; 3 | } 4 | 5 | if (![]) { 6 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ 5 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ 6 | "lib": [ "es2015" ], 7 | // "allowJs": true, /* Allow javascript files to be compiled. */ 8 | // "checkJs": true, /* Report errors in .js files. */ 9 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 10 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 11 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 12 | "sourceMap": true, /* Generates corresponding '.map' file. */ 13 | // "outFile": "./", /* Concatenate and emit output to single file. */ 14 | // "outDir": "./out", /* Redirect output structure to the directory. */ 15 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 16 | // "removeComments": true, /* Do not emit comments to output. */ 17 | // "noEmit": true, /* Do not emit outputs. */ 18 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 19 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 20 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 21 | 22 | /* Strict Type-Checking Options */ 23 | "strict": true, /* Enable all strict type-checking options. */ 24 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 25 | // "strictNullChecks": true, /* Enable strict null checks. */ 26 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 27 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 28 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 29 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 30 | 31 | /* Additional Checks */ 32 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 33 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 34 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 35 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 36 | 37 | /* Module Resolution Options */ 38 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 39 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 40 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 41 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 42 | // "typeRoots": [], /* List of folders to include type definitions from. */ 43 | // "types": [], /* Type declaration files to be included in compilation. */ 44 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 45 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 46 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 47 | 48 | /* Source Map Options */ 49 | // "sourceRoot": "./src", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 50 | // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ 51 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 52 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 53 | 54 | /* Experimental Options */ 55 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 56 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 57 | } 58 | } --------------------------------------------------------------------------------