From 8b2075feebfb90a465a24c2af35762cacdee20bc Mon Sep 17 00:00:00 2001 From: Ben Baryo <60312583+BenBaryoPX@users.noreply.github.com> Date: Sun, 14 Jan 2024 10:47:57 +0200 Subject: [PATCH] Small Fixes (#109) * Refactor redundant code into a single statement (modules/safe/unwrapFunctionShells) * Fix issue where cycle changes counter did not reset between cycles (modules/utils/runLoop) * Fix logger line not printing (restringer.js) * Add version logging (restringer.js) * Replace Node.js v16 with Node.js v20 (.github/workflows/node.js.yml) --- .github/workflows/node.js.yml | 2 +- src/modules/safe/unwrapFunctionShells.js | 3 +-- src/modules/utils/runLoop.js | 3 ++- src/restringer.js | 3 ++- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index bca41a5..ec47948 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: - node-version: [16.x, 18.x] + node-version: [18.x, 20.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: diff --git a/src/modules/safe/unwrapFunctionShells.js b/src/modules/safe/unwrapFunctionShells.js index 5a4830d..3be9d32 100644 --- a/src/modules/safe/unwrapFunctionShells.js +++ b/src/modules/safe/unwrapFunctionShells.js @@ -15,8 +15,7 @@ function unwrapFunctionShells(arb, candidateFilter = () => true) { for (let i = 0; i < arb.ast.length; i++) { const n = arb.ast[i]; if (['FunctionDeclaration', 'FunctionExpression'].includes(n.type) && - n.body?.body?.length === 1 && - n.body.body[0].type === 'ReturnStatement' && + n.body?.body?.[0]?.type === 'ReturnStatement' && (n.body.body[0].argument?.callee?.property?.name || n.body.body[0].argument?.callee?.property?.value) === 'apply' && n.body.body[0].argument.arguments?.length === 2 && n.body.body[0].argument.callee.object.type === 'FunctionExpression' && diff --git a/src/modules/utils/runLoop.js b/src/modules/utils/runLoop.js index 77fc4da..ab6d79b 100644 --- a/src/modules/utils/runLoop.js +++ b/src/modules/utils/runLoop.js @@ -23,9 +23,9 @@ function hasGlobalMaxIterationBeenReached() { function runLoop(script, funcs, maxIterations = defaultMaxIterations) { let scriptSnapshot = ''; let currentIteration = 0; + let changesCounter = 0; try { let scriptHash = generateHash(script); - let changesCounter = 0; let arborist = new Arborist(script, logger.log); while (arborist.ast?.length && scriptSnapshot !== script && currentIteration < maxIterations && !hasGlobalMaxIterationBeenReached()) { const cycleStartTime = Date.now(); @@ -60,6 +60,7 @@ function runLoop(script, funcs, maxIterations = defaultMaxIterations) { ++globalIterationsCounter; logger.log(`[+] ==> Cycle ${globalIterationsCounter} completed in ${(Date.now() - cycleStartTime) / 1000} seconds` + ` with ${changesCounter ? changesCounter : 'no'} changes (${arborist.ast?.length || '???'} nodes)`); + changesCounter = 0; } if (changesCounter) script = arborist.script; } catch (e) { diff --git a/src/restringer.js b/src/restringer.js index dea150f..2562e01 100755 --- a/src/restringer.js +++ b/src/restringer.js @@ -156,11 +156,12 @@ if (require.main === module) { const fs = require('node:fs'); let content = fs.readFileSync(args.inputFilename, 'utf-8'); const startTime = Date.now(); - logger.log(`[!] Deobfuscating ${args.inputFilename}...\n`); const restringer = new REstringer(content); if (args.quiet) restringer.logger.setLogLevel(logger.logLevels.NONE); else if (args.verbose) restringer.logger.setLogLevel(logger.logLevels.DEBUG); + logger.log(`[!] REstringer v${REstringer.__version__}`); + logger.log(`[!] Deobfuscating ${args.inputFilename}...`); if (args.maxIterations) { setGlobalMaxIterations(args.maxIterations); restringer.logger.log(`[!] Running at most ${args.maxIterations} iterations`);