JSXBIN, the Binary ExtendScript Script File format, is a proprietary format created by Adobe to help script developers keep their work safe and as “opaque” as possible to foreign eyes. I will not discuss here the motivation behind such encryption, and even less its technical aspects. We are not authorized to share sensible information on this subject. Furthermore, we shouldn't even attempt to use reverse engineering techniques in order to crack JSXBIN files or study how they work.

However, the state of affairs is that JSXBIN is not a robust shield at all. Various algorithms and tools have emerged that can partially or entirely decode a JSXBIN file into its original ExtendScript code. That's obviously a critical issue to anyone who releases scripted products, including me and many of my colleagues in the community. (Once again I do not want to argue. Each of us has his/her own reasons to either share or protect what s/he has designed.)

Cracking the Code to Improve It

So we are caught in a dilemma: not to investigate the encryption algorithm while accepting that others can decipher our files!

At that point I took the option that seems the most pragmatic to me, whatever its legal issue. I implemented a JS script, JsxBlind, that uses what is known about the JSXBIN format to generate a deeper obfuscation of an existing JSXBIN file. This way, you can take a binary script (originated from ESTK), then run JsxBlind on it, then publicly release the re-encoded version. The process is as follows:

Global process of re-encoding a JSXBIN (through JsxBlind) from the original source code.

The file finally generated by JsxBlind, MyScript_blind.jsxbin, is nothing but a new JSXBIN having exactly the same size—and the same functionalities!—than the one natively encoded by ESTK. So you'll ask me the question, “how could the latter be more secure than the former, since it can be cracked the same way by those pesky JSXBIN hackers?” Well, you are perfectly right, nothing prevents the blind version from being deciphered.

But, just for my argument, let's assume we have at our disposal such a decoder and let's compare the result of applying it to the original JSXBIN on one hand, and to the final JSXBIN on the other hand:

The original (left panel) and the final (right panel) JSXBIN as revealed by the same decoder.

As you may notice there is no difference in the code structure. However, in the obfuscated version (right panel) the original identifiers—that is, variables, constants, parameters, and function names—have been replaced by random Unicode characters remaining fully valid in terms of JavaScript syntax but making the program quite unreadable.

This process is based on two facts. First, using some well designed algorithm we can scramble the identifier table of a JSXBIN while preserving its size and its code structure. Secondly, most identifiers of a JavaScript program are arbitrary in the sense that they do not determine how the script operates.

Limitations and Usage

As most of my free scripts JsxBlind is an experimental utility without warranty of any kind. I particularly emphasize this point, as no technical precision can be revealed, and no support (or additional feature) can be provided. I also point out—and you have to trust me on this, sorry!—that I have no way to reverse the operations performed by JsxBlind, since substituted characters are randomly generated. Needless to say that it is your entire responsibility to keep safe the original code of your scripts. Do not expect that a blinded file could be easily translated back into a clear code. Do not expect, either, that nobody can do it! Our goal is just to make this extremely tedious.

Now, if you look more closely at the example shown above, you notice that object members (method and property names) are unchanged. Indeed, these are not arbitrary identifiers in JavaScript. Therefore, this part of your code cannot be obfuscated, leading to keep clear many logical and/or semantic elements in the puzzled version. By contrast, function names are usually free to camouflage, except in special cases where the code relies on Function.name property checking. In such situation, you need to tell JsxBlind that you want to leave unchanged function names. (A prompt box is displayed for that purpose when the script starts up.)

Here are the steps:

1. Run JsxBlindRun.jsx from your host application (all tests have been done in InDesign—not sure other hosts would be OK.)

Select the JSXBIN file you want to re-encode.

2. As requested, select the target JSXBIN file on your hard disk.

3. Answer the question in the prompt box:

Do you want to scramble function names too?

4. Let the script parse the whole structure. (This could take some time, depending on the file size.)

JsxBlind is working…

5. If nothing goes wrong, the resulting file is generated with the suffix _blind.jsxbin at the location of the source:

Get the result.

6. Finally, do not forget to check that the blind version works as the original before you release the product! If this were not the case, I couldn't do anything else for you ;-)