Skip to content

Commit

Permalink
evaluation of update expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzoferre committed Mar 30, 2024
1 parent 7ae6b44 commit 3c829f1
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 14 deletions.
2 changes: 2 additions & 0 deletions src/deobfuscator.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import evaluateConditionStatement from "./techniques/statics/evaluate-condition-
import controlFlowUnflattening from "./techniques/statics/control-flow-unflattening.js";
import removeEmptyStatement from "./techniques/statics/remove-empty-statement.js";
import evaluateFunction from "./techniques/dynamics/evaluate-function.js";
import evaluateUpdateExpression from "./techniques/dynamics/evaluate-update-expression.js";

export default function deobfuscate(code, dynamic = false) {
do {
Expand All @@ -40,6 +41,7 @@ export default function deobfuscate(code, dynamic = false) {
controlFlowUnflattening,
removeEmptyStatement,
dynamic ? evaluateFunction : null,
dynamic ? evaluateUpdateExpression : null,
].filter(Boolean),
comments: false,
compact: false,
Expand Down
54 changes: 40 additions & 14 deletions src/techniques/dynamics/evaluate-update-expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,53 @@ import _generate from "@babel/generator";
const generate = _generate.default;
import vm from "vm";

const context = vm.createContext();

export default function (babel) {
const { types: t } = babel;
const context = vm.createContext();
let scopeUid;

return {
name: "evaluate-update-expression",
visitor: {
VariableDeclaration(path) {
const { node } = path;
const declaration = generate(node).code;
vm.runInContext(declaration, context);
VariableDeclarator: {
enter(path) {
const { node } = path;
const { scope } = path;
scopeUid = scope.uid;
const declaration = generate(node).code;
vm.runInContext(declaration, context);
},
},
ExpressionStatement: {
enter(path) {
const { node } = path;
const { scope } = path;
if (scopeUid !== scope.uid) return;
const { expression } = node;
if (t.isUpdateExpression(expression) || t.isAssignmentExpression(expression)) {
const expressionCode = generate(node).code;
const value = vm.runInContext(expressionCode, context);
if (value) {
path.remove();
setChanged(true);
}
}
},
},
ExpressionStatement(path) {
const { node } = path;
const { expression } = node;
if (t.isUpdateExpression(expression) || t.isAssignmentExpression(expression)) {
const expressionCode = generate(node).code;
vm.runInContext(expressionCode, context);
console.log(context);
}
Identifier: {
enter(path) {
const { node } = path;
const { scope } = path;
if (scopeUid !== scope.uid) return;
const { parent } = path;
if (t.isUpdateExpression(parent) || t.isAssignmentExpression(parent)) return;
const parentFather = path.parentPath.parent;
if (!t.isExpressionStatement(parentFather)) return;
if (context.hasOwnProperty(node.name)) {
path.replaceWith(t.valueToNode(context[node.name]));
setChanged(true);
}
},
},
},
};
Expand Down
39 changes: 39 additions & 0 deletions test/test-dynamic-techniques.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,42 @@ test("evaluation of arrow functions with literal node type as inputs", () => {
`console.log(2);`
);
});

test("evaluation of update expressions", () => {
assert.strictEqual(
removeNewLinesAndTabs(
deobfuscate(
`
let a = 5;
a++;
a *= 2;
a--;
console.log(a);
`,
true
)
),
`console.log(11);`
);
});

test("evaluation of update expressions in different scopes", () => {
assert.strictEqual(
removeNewLinesAndTabs(
deobfuscate(
`
let func = (a) => {
a++;
a *= 2;
a--;
return a;
}
let a = 5;
console.log(func(a));
`,
true
)
),
`console.log(11);`
);
});

0 comments on commit 3c829f1

Please sign in to comment.