UNPKG

js-confuser

Version:

JavaScript Obfuscation Tool.

100 lines (84 loc) 2.96 kB
import { NodePath } from "@babel/traverse"; import { PluginArg, PluginObject } from "./plugin"; import * as t from "@babel/types"; import { ok } from "assert"; import { Order } from "../order"; import { NodeSymbol, SKIP } from "../constants"; import Template from "../templates/template"; import { append } from "../utils/ast-utils"; export default ({ Plugin }: PluginArg): PluginObject => { const me = Plugin(Order.AstScrambler, { changeData: { expressions: 0, }, }); var callExprName: string; return { visitor: { "Block|SwitchCase": { exit(_path) { const path = _path as NodePath<t.Block | t.SwitchCase>; const isProgram = path.isProgram(); let containerKey: string; if (path.isSwitchCase()) { containerKey = "consequent"; } else if (path.isBlock()) { containerKey = "body"; } var container: t.Statement[] = path.node[containerKey]; var newContainer: t.Statement[] = []; ok(Array.isArray(container)); var expressions: t.Expression[] = []; const flushExpressions = () => { if (!expressions.length) return; // Not enough expressions to require a call expression if (expressions.length === 1) { newContainer.push(t.expressionStatement(expressions[0])); expressions = []; return; } if (!callExprName) { callExprName = me.getPlaceholder() + "_ast"; } me.changeData.expressions += expressions.length; newContainer.push( t.expressionStatement( t.callExpression(t.identifier(callExprName), expressions) ) ); expressions = []; }; for (var statement of container) { if ( // Preserve last expression at the top level (isProgram ? statement !== container.at(-1) : true) && t.isExpressionStatement(statement) && !(statement as NodeSymbol)[SKIP] ) { if (t.isSequenceExpression(statement.expression)) { expressions.push(...statement.expression.expressions); } else { expressions.push(statement.expression); } } else { flushExpressions(); newContainer.push(statement); } } flushExpressions(); path.node[containerKey] = newContainer; if (path.isProgram()) { if (callExprName) { var functionDeclaration = new Template(` function ${callExprName}(){ ${callExprName} = function(){}; } `).single(); append(path, functionDeclaration); } } }, }, }, }; };