webcrack

repository·master·Indexed 25 days ago

https://github.com/j4k0xb/webcrack

A reverse engineering tool for JavaScript designed to deobfuscate obfuscator.io code, unminify, transpile, and unpack Webpack or Browserify bundles. It can convert React.createElement calls back to JSX and transform legacy JavaScript syntax into modern features like optional chaining and nullish coalescing. Available as both a CLI tool and a library for Node.js 22 or 24, featuring a plugin system to hook into the processing pipeline.

Tokens
8.5K
Snippets
25
Records
65
Agent score
83%

What's inside webcrack

  1. Overview of webcrack capabilities

    master

    webcrack is a reverse engineering tool for JavaScript designed to restore code to a readable state. It provides the following capabilities:

    • Deobfuscation: Specifically targets obfuscator.io.
    • Unminification: Converts minified code back to a readable format.
    • Transpilation: Reverses transpiled code.
    • Unpacking: Unpacks webpack/browserify bundles.

    The tool focuses on performance, safety (respecting variable references and scope), and auto-detection of code patterns without requiring manual configuration.

  2. Unpack Webpack and Browserify bundles

    master

    webcrack can unpack webpack and browserify bundles into separate, readable files.

    Webpack Unpacking Behavior:

    • __webpack_require__(id) calls are rewritten to standard require('./relative/path.js') calls.
    • Modules may be converted to ESM (ECMAScript Modules).
    • Limitation: Multiple chunks are not currently supported.

    Browserify Unpacking Behavior:

    • webcrack builds a dependency tree based on numerical module IDs and relative dependency paths (e.g., { './foo': 1 }).
    • It resolves these paths to reconstruct the original file structure as closely as possible.
    • If the original root directory (like src) is missing from the bundle, webcrack uses placeholder directory names like tmp0/tmp1 to maintain the hierarchy.
  3. Transpile modern JavaScript syntax

    master
    Use webcrack to convert transpiled, legacy-style JavaScript syntax back into modern, readable JavaScript. This includes converting complex conditional checks and manual argument handling back into native language features like default parameters, optional chaining, and nullish coalescing.
  4. Deobfuscate code from javascript-obfuscator

    master

    webcrack provides deobfuscation capabilities for code that has been processed by javascript-obfuscator (obfuscator.io). It can reverse various obfuscation techniques including:

    String Array Transformations

    • Rotate
    • Shuffle
    • Index Shift
    • Calls Transform
    • Variable/Function Wrapper Type
    • None/Base64/RC4 Encoding
    • Split Strings
    • Unicode Escape Sequence

    Other Transformations

    • Compact
    • Simplify
    • Numbers To Expressions
    • Control Flow Flattening
    • Dead Code Injection
    • Transform Object Keys

    Protections

    • Disable Console Output
    • Self Defending
    • Debug Protection
    • Domain Lock
  5. webcrack Requirements and Node.js compatibility

    master

    webcrack requires Node.js 22 or 24.

    Important: webcrack depends on isolated-vm. It is highly recommended to avoid using odd-numbered Node.js releases (e.g., Node.js 23, 25) because they frequently break ABI/API compatibility with V8, which may cause issues with isolated-vm.

  6. Convert React.createElement calls back to JSX

    master

    webcrack can perform the inverse operation of standard build tools like Babel or TypeScript. Instead of converting JSX to React.createElement calls, it converts existing React.createElement calls back into readable JSX syntax.

    Limitation: This feature currently only works for the React UMD build and does not work when React is bundled.

    // Input: React.createElement calls
    React.createElement(
      'div',
      null,
      React.createElement('span', null, 'Hello ', name),
    );
    
    // Output: JSX syntax
    <div>
      <span>Hello {name}</span>
    </div>
  7. Use the webcrack playground

    master

    The webcrack playground allows you to deobfuscate code directly in your browser without installation. The processing happens entirely client-side, so your code is not sent to a server.

    Keyboard Shortcuts

    • F1: Open the command palette
    • Alt+Enter: Run webcrack on the current code
    • Shift+Enter: Evaluate and replace selected code as a value (e.g., [[3+4]][0] becomes [7])
    • Ctrl+Shift+Enter: Evaluate and replace selected code raw (e.g., 'x' + ' = \'val\'' becomes x = 'val' instead of a string)
    • Ctrl+S: Download the code in the active tab as a .js file
  8. Extend webcrack with plugins

    master

    Webcrack's pipeline consists of six stages: Parse, Prepare, Deobfuscate, Transpile/Unminify, JSX/Unpack, and Generate. You can hook into these stages using the plugins option.

    Supported Plugin Stages:

    • afterParse
    • afterPrepare
    • afterDeobfuscate
    • afterUnminify
    • afterUnpack

    Plugin API: Plugins follow a pattern similar to Babel plugins. The plugin function receives an object containing utility libraries:

    • parse (babel-parser)
    • types (babel-types)
    • traverse (babel-traverse)
    • template (babel-template)
    • matchers (codemod/matchers)

    Writing a Plugin: Plugins can implement pre(), visitor, and post() methods.

    function myPlugin({ types: t }) {
      return {
        pre() {
          console.log('Running before traversal');
        },
        visitor: {
          NumericLiteral(path) {
            path.replaceWith(t.stringLiteral('x'));
          },
        },
        post() {
          console.log('Running after traversal');
        },
      };
    }
    
    const result = await webcrack('1 + 1', {
      plugins: {
        afterParse: [myPlugin],
      },
    });

    Using Babel Plugins: Most Babel plugins are compatible if they only use the supported API.

    import removeConsole from 'babel-plugin-transform-remove-console';
    
    const result = await webcrack('consol.log(a), b()', {
      plugins: {
        afterUnminify: [removeConsole],
      },
    });
    import { webcrack } from 'webcrack';
    
    function myPlugin({ types: t }) {
      return {
        pre() {
          console.log('Running before traversal');
        },
        visitor: {
          NumericLiteral(path) {
            console.log('Found a number:', path.node.value);
            path.replaceWith(t.stringLiteral('x'));
          },
        },
        post() {
          console.log('Running after traversal');
        },
      };
    }
    
    const result = await webcrack('1 + 1', {
      plugins: {
        afterParse: [myPlugin],
      },
    });
    console.log(result.code); // '"xx"'