JavaScript Deobfuscator reloaded

A few weeks ago I released JavaScript Deobfuscator 2.0 — finally something that works with current Firefox versions again. Why did it take me a year to fix this compatibility issue? Well, it really wasn’t that simple. After considering all the possibilities I decided that rewriting it from scratch was the only possibility, and that was hard to accomplish in my spare time.

Before I continue with the technical details, allow me to introduce JavaScript Deobfuscator in its new reincarnation: it now adds a panel to Firefox Developer Tools. Instead of messing with filters your view is limited to the current tab automatically. Both compiled and executed scripts go into the same list, with some text indicating whether we’ve seen the script being compiled or executed or both. Starting with Firefox 39 even code running in Web Workers will be displayed. And JavaScript Deobfuscator will beautify the code instead of relying on the JavaScript engine to do so.

JavaScript Deobfuscator screenshot

The downside is that only Firefox is supported now — other applications simply don’t have Developer Tools to integrate with. Also, debugging add-ons or the browser itself isn’t possible—— Developer Tools run in a separate process for that, no add-ons installed there. Finally, the search functionality is absolutely rudimentary right now, that’s something I hope to improve eventually.

Now to the technical details. The reason for this overhaul is the new debugging interface which replaced the one JavaScript Deobfuscator was using. The old debugging interface was conceptually different, it was designed as a single hook to collect all data. The new one on the other hand collects data about individual compartments and it’s up to you to figure out which ones you need. After a few unsuccessful attempts to continue collecting all data in JavaScript Deobfuscator I realized that it made a lot more sense to look at individual tabs.

Using the new debugging API turned out to be tricky to say the least. Did I link to MDN above? Sorry about that, I should have linked to the SpiderMonkey source code. It’s very similar to the MDN documentation but the later is outdated. And even if you look at the SpiderMonkey source, much of the documentation is merely wishful thinking, listing features that were never implemented.

A new UI concept had to be developed as well, and the only good option for per-tab debugging would be integrating into the Firefox Developer Tools. That’s where the fun really started. I tried to make sense of the documentation, studied the source code, figured out that ToolDefinition.build() is supposed to return a promise. Then I looked at what TargetType is and how existing tools work with it — this was the point where I realized that there are so many implementation details involved that an extension cannot possibly do it. So I gave up.

When I came back a few months later things improved, slightly. Somebody wrote an Add-on SDK module to create new Developer Tools panels. While I didn’t use that module directly, it showed nicely which parts of the API are contractual and which ones are merely implementation details. It also showed that things aren’t too bad if you limit yourself to a single target type — a local tab. Handling remote connections to browser and add-ons is more complicated, but as I mentioned above extensions cannot do that anyway.

Now that article stops at the point where you “merely” need to use the remote debugging protocol to communicate with the built-in debugging actor. Well, maybe it is really simple but I couldn’t figure out how to do this — and whether that protocol is something I can rely on. See, the built-in tools will certainly be adjusted when the debugging actor or/and the protocol change. My extension on the other hand will be broken, and I’ll need to invest time into figuring out what changed and how my code needs to be adjusted while staying compatible with older Firefox versions.

So JavaScript Deobfuscator uses the debugging interface directly, without relying on the debugging actor of the Developer Tools. And it beautifies JavaScript code using its own copy of a library rather than relying on code used by Developer Tools — JavaScript beautification in Developer Tools is currently an implementation detail that extensions cannot rely on. JavaScript Deobfuscator also duplicates the styles of the two Developer Tools themes to make sure it looks similar to the existing panels — just using the styles from Developer Tools would have likely caused a disaster after only a few Firefox releases. Not that the built-in styles are really defined in a generic way, there is really lots of inconsistencies there and each panel is styled somewhat differently.

These are only some examples, there is more code duplication. Developer Tools aren’t currently built to allow extensions to reuse their code. Still, I’m fairly happy with the result, and I hope that the largest chunk (JavaScript beautification) will go away eventually. From the usability point of view the new version is a huge leap forward, getting there could have been easier however.

Comments

  • Neil Rashbrook

    I guess to debug add-ons you could use manual remote debugging like you would for Thunderbird or SeaMonkey?

    Wladimir Palant

    Sure. It’s merely impossible to integrate with Developer Tools, but one could always replicate their functionality in own code.