From ecce73def8ec5caca85e9f5c0dddd3616c724fa2 Mon Sep 17 00:00:00 2001 From: lorenzoferre Date: Wed, 25 Oct 2023 10:49:45 +0200 Subject: [PATCH 1/3] retrive results returned by functions --- src/deobfuscator.js | 2 ++ src/techniques/evaluate-function.js | 33 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 src/techniques/evaluate-function.js diff --git a/src/deobfuscator.js b/src/deobfuscator.js index c50b8b1..dad5ca3 100644 --- a/src/deobfuscator.js +++ b/src/deobfuscator.js @@ -14,6 +14,7 @@ import replaceNullToUndefined from "./techniques/replace-null-to-undefined.js"; import evaluateConditionStatement from "./techniques/evaluate-condition-statement.js"; import controlFlowUnflattening from "./techniques/control-flow-unflattening.js"; import removeEmptyStatement from "./techniques/remove-empty-statement.js"; +import evaluateFunction from "./techniques/evaluate-function.js"; export default function deobfuscate(code) { do { @@ -34,6 +35,7 @@ export default function deobfuscate(code) { evaluateConditionStatement, controlFlowUnflattening, removeEmptyStatement, + evaluateFunction, ], comments: false, compact: false, diff --git a/src/techniques/evaluate-function.js b/src/techniques/evaluate-function.js new file mode 100644 index 0000000..86a4402 --- /dev/null +++ b/src/techniques/evaluate-function.js @@ -0,0 +1,33 @@ +import { setChanged } from "../utils/util.js"; +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; + + return { + name: "evaluate-function", + visitor: { + FunctionDeclaration(path) { + const { node } = path; + functionName = node.id.name; + const func = generate(node).code; + vm.runInContext(func, context); + }, + CallExpression(path) { + const { node } = path; + const { callee } = node; + if (callee.name === functionName) { + const expressionCode = generate(node).code; + const value = vm.runInContext(expressionCode, context); + path.replaceWith(t.valueToNode(value)); + setChanged(true); + } + }, + }, + }; +} From 0e00c306c3c663d4da9e20a2f082de161c1b1dd7 Mon Sep 17 00:00:00 2001 From: lorenzoferre Date: Tue, 28 Nov 2023 23:44:00 +0100 Subject: [PATCH 2/3] fix bracket to dot test --- test/test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test.js b/test/test.js index ff804bf..a22e9f6 100644 --- a/test/test.js +++ b/test/test.js @@ -13,7 +13,6 @@ test("hex to value", () => { test("bracket to dot", () => { assert.strictEqual(deobfuscate(`console["log"]("a")`), `console.log("a");`); - assert.strictEqual(deobfuscate(`console.log(o["a"]);`), `console.log(o.a);`); }); test("remove empty statement", () => { From 6bb4e2771ed4bc46efa845f82e8a0539a8bf0af4 Mon Sep 17 00:00:00 2001 From: lorenzoferre Date: Tue, 28 Nov 2023 23:44:39 +0100 Subject: [PATCH 3/3] fix evaluation of functions --- src/techniques/evaluate-function.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/techniques/evaluate-function.js b/src/techniques/evaluate-function.js index 86a4402..6b168d3 100644 --- a/src/techniques/evaluate-function.js +++ b/src/techniques/evaluate-function.js @@ -21,9 +21,12 @@ export default function (babel) { CallExpression(path) { const { node } = path; const { callee } = node; - if (callee.name === functionName) { - const expressionCode = generate(node).code; - const value = vm.runInContext(expressionCode, context); + if (callee.name !== functionName) return; + const args = node.arguments; + if (!args.every(arg => t.isLiteral(arg))) return; + const expressionCode = generate(node).code; + const value = vm.runInContext(expressionCode, context); + if (value) { path.replaceWith(t.valueToNode(value)); setChanged(true); }