js-confuser
Version:
JavaScript Obfuscation Tool.
83 lines (70 loc) • 2.15 kB
text/typescript
import { PluginArg, PluginObject } from "./plugin";
import * as t from "@babel/types";
import { getRandomInteger } from "../utils/random-utils";
import Template from "../templates/template";
import { Order } from "../order";
import { isStaticValue } from "../utils/static-utils";
import { PREDICTABLE } from "../constants";
import { numericLiteral } from "../utils/node";
import { prependProgram } from "../utils/ast-utils";
export default ({ Plugin }: PluginArg): PluginObject => {
const me = Plugin(Order.Shuffle, {
changeData: {
arrays: 0,
},
});
let fnName: string | null = null;
return {
visitor: {
ArrayExpression: {
exit(path) {
if (path.node.elements.length <= 3) {
return;
}
var illegalElement = path.node.elements.find(
(element) => !isStaticValue(element)
);
if (illegalElement) return;
if (!me.computeProbabilityMap(me.options.shuffle)) {
return;
}
// Create un-shuffling function
if (!fnName) {
fnName = me.getPlaceholder() + "_shuffle";
prependProgram(
path,
new Template(
`
function ${fnName}(arr, shift) {
for (var i = 0; i < shift; i++) {
arr["push"](arr["shift"]());
}
return arr;
}
`
)
.addSymbols(PREDICTABLE)
.single<t.FunctionDeclaration>()
);
}
var shift = getRandomInteger(
1,
Math.min(30, path.node.elements.length * 6)
);
var shiftedElements = [...path.node.elements];
for (var i = 0; i < shift; i++) {
shiftedElements.unshift(shiftedElements.pop());
}
path.replaceWith(
t.callExpression(t.identifier(fnName), [
t.arrayExpression(shiftedElements),
numericLiteral(shift),
])
);
path.skip();
me.changeData.arrays++;
},
},
},
};
};