Skip to content

Commit

Permalink
fix evaluation of arrow functions with literal type nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzoferre committed Mar 30, 2024
1 parent 286ec2e commit 5cddd38
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 32 deletions.
2 changes: 0 additions & 2 deletions src/deobfuscator.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { transform } from "@babel/core";
import { changed, setChanged } from "./utils/util.js";
import removeDeadCode from "./techniques/statics/remove-dead-code.js";
import renameVariableSameScope from "./techniques/statics/rename-variable-same-scope.js";
import replaceFunctionExpressionWithFunctionDeclaration from "./techniques/statics/replace-function-expression-with-function-declaration.js";
import reconstructVariableDeclaration from "./techniques/statics/reconstruct-variable-declaration.js";
import constantPropagation from "./techniques/statics/constant-propagation.js";
import evaluate from "./techniques/statics/evaluate.js";
Expand All @@ -26,7 +25,6 @@ export default function deobfuscate(code, dynamic = false) {
plugins: [
removeDeadCode,
renameVariableSameScope,
replaceFunctionExpressionWithFunctionDeclaration,
reconstructVariableDeclaration,
constantPropagation,
evaluate,
Expand Down
29 changes: 18 additions & 11 deletions src/techniques/dynamics/evaluate-function.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,36 @@ import _generate from "@babel/generator";
const generate = _generate.default;
import vm from "vm";

const context = vm.createContext();
var functionName;

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

return {
name: "evaluate-function",
visitor: {
FunctionDeclaration(path) {
const { node } = path;
functionName = node.id.name;
const func = generate(node).code;
vm.runInContext(func, context);
FunctionDeclaration: {
enter(path) {
const { node } = path;
const func = generate(node).code;
vm.runInContext(func, context);
},
},
VariableDeclarator: {
enter(path) {
const { node } = path;
const { init } = node;
if (t.isArrowFunctionExpression(init)) {
vm.runInContext(generate(node).code, context);
}
},
},
CallExpression(path) {
const { node } = path;
const { callee } = node;
if (callee.name !== functionName) return;
if (!context.hasOwnProperty(callee.name)) return;
const args = node.arguments;
if (!args.every(arg => t.isLiteral(arg))) return;
const expressionCode = generate(node).code;
const value = vm.runInContext(expressionCode, context);
const value = vm.runInContext(generate(node).code, context);
if (value) {
path.replaceWith(t.valueToNode(value));
setChanged(true);
Expand Down
32 changes: 31 additions & 1 deletion test/test-dynamic-techniques.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { test, describe } from "node:test";
import { test } from "node:test";
import assert from "node:assert/strict";

import deobfuscate from "../src/deobfuscator.js";
Expand All @@ -21,3 +21,33 @@ test("evaluation of functions with literal node type as inputs", () => {
`console.log(4);`
);
});

test("evaluation of arrow functions with literal node type as inputs and implicit return", () => {
assert.strictEqual(
removeNewLinesAndTabs(
deobfuscate(
`
let sum = (a,b) => a + b;
console.log(sum(2,2));
`,
true
)
),
`console.log(4);`
);
});

test("evaluation of arrow functions with literal node type as inputs", () => {
assert.strictEqual(
removeNewLinesAndTabs(
deobfuscate(
`
let sub = (a,b) => {return a - b;};
console.log(sub(4,2));
`,
true
)
),
`console.log(2);`
);
});
18 changes: 0 additions & 18 deletions test/test-static-techniques.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,6 @@ import deobfuscate from "../src/deobfuscator.js";

import { removeNewLinesAndTabs } from "../src/utils/util.js";

test("transform function expressions into function declarations", () => {
assert.strictEqual(
removeNewLinesAndTabs(
deobfuscate(
`
var sum = function(a, b) {
return a + b;
}
var a = 2;
console.log(sum(a, 2*a));
`,
false
)
),
`function sum(a, b) { return a + b; } console.log(sum(2, 4));`
);
});

test("reconstruct variable declarations", () => {
assert.strictEqual(
removeNewLinesAndTabs(
Expand Down

0 comments on commit 5cddd38

Please sign in to comment.