j4k0xb / webcrack

Deobfuscate obfuscator.io, unminify and unpack bundled javascript
https://webcrack.netlify.app
MIT License
870 stars 100 forks source link

feat: rename destructuring #63

Open j4k0xb opened 7 months ago

j4k0xb commented 7 months ago

closes #62

netlify[bot] commented 7 months ago

Deploy Preview for webcrack ready!

Name Link
Latest commit 271f21c8bac41582b58a0b4896aed11f4d2e9a30
Latest deploy log https://app.netlify.com/sites/webcrack/deploys/65d3de47ff1280000792e0af
Deploy Preview https://deploy-preview-63--webcrack.netlify.app
Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

milahu commented 7 months ago

testing this with a 3MB input file

rename should also affect imports, but this is also missing in wakaru

import {
  render as ak,
  html as aq,
  Component as az,
} from "/libs/preact/preact.js";

console.log(ak, aq, az);

some rebindings are preserved because the identifier has already been declared, regardless of scope

i guess an optimal solution would require dynamic analysis for example to ensure that Math == Math so that Math.sqrt == Math.sqrt so the first let { sqrt } = Math; can be reused and the following let { sqrt: _sqrtN } = Math; can be removed

let { sqrt } = Math;
let { sqrt: _sqrt } = Math;
let { sqrt: _sqrt2 } = Math;
let { sqrt: _sqrt3 } = Math;

works for y, fails on x, because x is declared globally

const x = "...";

let { x: _x2, y } = aD;
let { x: _x4, y } = DOMPoint.fromPoint(aP).matrixTransform(aN);
let { x: _x5, y } = DOMPoint.fromPoint(aV).matrixTransform(aT);
let { x: _x6, y } = Ha(...);
let { x: _x7, y } = Ha(...);

here it also fails on y, because y is declared locally

let { x: _x8, y } = aF.matrixTransform(aD);
let { x: _x9, y: _y } = aG.matrixTransform(aD);
j4k0xb commented 7 months ago

now also affects imports

i guess an optimal solution would require dynamic analysis for example to ensure that Math == Math

can maybe be done later/separately because its not related to the renaming and potentially unsafe I guess this was created by a bundler with scope hoisting (all modules are concatenated) like rollup/esbuild/swc

works for y, fails on x, because x is declared globally

hmm could be improved if it wont affect the performance too much it currently doesn't use x to avoid checking for shadowing:

const x = "...";
function f() {
  let { x: _x2, y } = aD;
  console.log(x);
}

here it also fails on y, because y is declared locally

expected

milahu commented 7 months ago

rename should also affect imports

similar situation with custom elements

webcrack should infer the class name from the element name

class aa extends HTMLElement {
  static #V = html`<div>foo</div>`;
  static #j = css`:host { display: block; }`;
  #Y;
  constructor() {
    super();
    this.#Y = this.attachShadow({  mode: "open" });
    this.#Y.adoptedStyleSheets = [aa.#j];
    this.#Y.append(document.importNode(aa.#V.content, true));
  }
}
customElements.define("x-foo", aa);
class XFoo extends HTMLElement {
  // ...
}
customElements.define("x-foo", XFoo);

maybe also add names to anonymous classes

customElements.define(
  "x-foo",
  class extends HTMLElement { /* ... */ }
);