j4k0xb / webcrack

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

Multiple bundles #107

Open Mardoxx opened 2 months ago

Mardoxx commented 2 months ago

It would be cool of this could support multiple bundles.

I was trying to re an app earlier and it was packed into separate bundles, had to do them one after another and sort of hack it all back together.

Amazing project, I hope to contribute one day.

Mardoxx commented 2 months ago

Unpack multi-chunk bundles

Already on your todo list!

0xdevalias commented 2 months ago

If it's not obfuscated (eg. just minimised), you may have some luck with wakaru in the meantime. I think it handles multi-chunk bundles from memory:

sharky98 commented 1 month ago

If it's not obfuscated (eg. just minimised), you may have some luck with wakaru in the meantime. I think it handles multi-chunk bundles from memory:

* https://github.com/pionxzh/wakaru

Funny thing, I came here linked by them because they doesn't do obfuscated code, but I have a webpack bundle (and maybe multiple bundle, still reverse engineering the code) split in multiple chunks & files (I think it's a Next framework).

For now I do webcrack on all files, keeping the generated module and passing them to wakaru. It's something.

Anyhow, in my case I have a _buildManifest.js file that seems to detail the relationship between the pages, common chunks, and pages entrypoint. Maybe it could be used (if it's available in more than just Next)

I removed the hash and shortened the VERY long list of mangled variables that are used to point to a chunks.

self.__BUILD_MANIFEST = function (s, c, [...]) {
  return {
    __rewrites: {
      beforeFiles: [],
      afterFiles: [],
      fallback: []
    },
    "/": [s, t, [...], "static/chunks/pages/index-[hash].js"],
    "/404": [s, e, c, "static/chunks/pages/404-[hash].js"],
    "/_error": ["static/chunks/pages/_error-[hash].js"],
    sortedPages: ["/", "/404", "/_app", "/_error", [...]]
  };
}("static/chunks/8621-[hash].js", "static/chunks/6579-[hash].js", [...]);
if (self.__BUILD_MANIFEST_CB) {
  self.__BUILD_MANIFEST_CB();
}
pionxzh commented 1 month ago

The manifest from Next is very useful to guess the complete filename. But I think it would be hard to support this feature since we won't be able to restore the folder or filename, all we get is a module id.

One possible solution is matching the dependencies.

"routes/status": {
            "id": "routes/status",
            "parentId": "root",
            "path": "status",
            "hasAction": false,
            "hasLoader": false,
            "hasClientAction": false,
            "hasClientLoader": false,
            "hasErrorBoundary": false,
            "module": "/assets/m8vsowdoh2jxozsr.js",
            "imports": ["/assets/dckfpppmklfb86fh.js", "/assets/f8f8l0d0j83ubfpm.js", "/assets/j36pxwjzprolzjey.js"],
            "css": ["/assets/root-e9fk4trk.css"]
        },

So, like this one, we can see that it depends on dckfpppmklfb86fh, f8f8l0d0j83ubfpm, and j36pxwjzprolzjey. We can do an analysis to match what file also depends on these chunks to restore the filename. But this can be relatively complex.

0xdevalias commented 1 month ago

Anyhow, in my case I have a _buildManifest.js file that seems to detail the relationship between the pages, common chunks, and pages entrypoint. Maybe it could be used (if it's available in more than just Next)

@sharky98 While not directly relevant to your main issue here, you might find benefit in some scripts I wrote for another project to extract the full list of chunks/etc from the _buildManifest.js + webpack.js:

It's also worth noting that in newer versions of Next.js, the buildManifest is no longer present in the same way, and we need to take a different approach, parsing/extracting information from the React Server Components streaming wire format:


The manifest from Next is very useful to guess the complete filename. But I think it would be hard to support this feature since we won't be able to restore the folder or filename, all we get is a module id.

@pionxzh While guessing the filename/folder structure would definitely be a nice 'feature add'; I think the main request here wasn't even going that deeply, and is just about being able to pass in multiple chunks/code files and have them all handled together properly as 'one bundle of code'.