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`);