PerimeterX/restringer

Refactor `deobfuscate` Method for Easier Customization and Module Replacement

lanvent opened this issue · 2 comments

Description:

Hello, I've been using your excellent JavaScript deobfuscation library one day and found it to be extremely useful. While the deobfuscate method is comprehensive, it performs several steps like determineObfuscationType and _loopSafeAndUnsafeDeobfuscationMethods which essentially determine which processors and modules to use. However, this design doesn't easily allow for the replacement or augmentation of specific modules.
For example, if I want to add a filter to resolveLocalCalls, I have to override the function and include a lot of boilerplate code, such as:

restringer._unsafeDeobfuscationMethods= () => {
  return [
    // ... other modules
    (n) => resolveLocalCalls(n, n => !(n.callee?.name?.includes('rand')|| n.callee?.name?.includes('Rand'))),
    // ... other modules
  ];
}

This makes it hard to replace or customize specific processors or deobfuscation methods.

Suggestion:

If the exported class could allow configuring all the methods used in the deobfuscate function during its construction, users could easily replace or extend specific modules or processors.

Example:
class REstringer {
  constructor() {
    this.determineObfuscationType(); // determine default processors.
    this.unsafeDeobfuscationMethods = [/* default methods */];
    // ...
  }
}
...
// my code
const restringer = new REstringer(code);
let index = restringer.unsafeDeobfuscationMethods.indexOf(resolveLocalCalls);
if (index !== -1) {
  restringer._preprocessors.splice(index, 1, (n) => resolveLocalCalls(n, n => !(n.callee?.name?.includes('rand') || n.callee?.name?.includes('Rand'))));
}
// customize processors or modules needed
restringer.deobfuscate();

This way, we can maintain the benefits of the existing class architecture while enabling users to make minimal necessary modifications.

If you agree with this proposal but don't have the time to implement it, I'd be happy to contribute a PR. Thank you for considering this improvement.

#93 externalizes the deob methods as requested. There's a usage example in the README.md file.
I added a disable option for the obfuscation type detection, meaning the pre and post processors won't run if turned off.
I hope this solves this issue

Thank you for your latest commit! It looks like it will fulfill my need. Great work!