Are you working with a proprietary
.swc? Does it have lots of bugs? Did the authors, in all their infinite wisdom, decide to hide those bugs in
private methods, so you stand no chance of being able to fix them? Well, friend, let me show you how to fix that.
Step 0: Uncompressing the
First make a backup copy of the library (just incase you botch something):
$ cp binary_library.swc binary_library_backup.swc
Then unzip the
swc file like you would any other
$ unzip binary_library.swc
This will extract, among other things, a
library.swf will probably be compressed, so you've also got to uncompress it. To do that, I like to use SWFTOOLS:
$ swfcombine -d library.swf -o uncompressed_library.swf
Step 1: Dumping the ABC
Now that you've got a nice uncompressed
swf, it's time to decompile it. To do this, you can use or my patched version of swfdump.
$ java -jar swfdump.jar -abc library.swf > library.abc
Step 2: Finding the multiname pool entry
Now pull up
library.abc in your favorite text editor and search for the method's name under the "MultiName Constant Pool Entries" heading. For example, if the method's name is "priv", you'll be looking for something like this:
6 MultiName Constant Pool Entries 07 01 04 private:priv <-- here 07 02 06 :void 07 02 09 :pub 07 02 01 :A 07 02 10 :Object
Note that the method may be prefixed with a namespace:
6 MultiName Constant Pool Entries ... 07 01 04 com.foo.ClassName:methodName
Technical details: The first of those three bytes refers to the entry kind. The second is a one-based index into the list of namespaces (which are listed under "Namespace Constant Pool Entries") and the third is a one-based index into the list of string constants ("String Constant Pool Entries"). For all the details, see section "4.3 Constant Pool", "4.4.3 Multiname" and "4.1 Primitive data types" (for the definition of u30 – making sure to read the paragraph witch mentions that it uses little-endian byte order) in AVM 2 Machine Overview.
Note: If you're dealing with a large
.swf, there may be four or even five bytes:
07 01 B9 03 :methodName
Don't worry – that's ok!
Make note of the bytes (in this case,
07 01 04) which prefix the method, then move on to step 3.
Step 3: Find a similar method
Next thing you've got to do is find a method of the same class which has a pubic (or protected) scope. In this case, we have a method called 'pub':
6 MultiName Constant Pool Entries 07 01 04 private:priv 07 02 06 :void 07 02 09 :pub <-- here
Make note here of the byte (
02): that tells the AVM which namespace the method belongs to.
Step 4: Hex edit the uncompressed library
Now, pull up your favorite hex editor and open up the
uncompressed_library.swf, which you created in step 0. Now, remember those bytes which prefix the method name? Search for them (and make sure you only find one instance of them – if there are multiple instances of them, expand the search to take into account the next few bytes (so, in this case,
07 01 04 07 02 06). Now, once you've found them, simply replace the second byte (in this case
01) with the second byte of the similar method:
07 01 04
is replaced with:
07 02 04
Step 5: Checking that you got it right
To check and make sure that you got it right, run the
swfutil again, then check the output:
$ java -jar swfdump.jar -abc uncompressed_library.swc
You should see your change reflected in the MultiName constant pool entries:
6 MultiName Constant Pool Entries 07 02 04 :priv 07 02 06 :void
Note that the method is no longer prefixed with 'private' (or whatever the original namespace was).
Now, if the utility crashes, or something else doesn't work, go back and try again – you'll get it eventually.
Step 6: Putting it all back together
You're almost done! All that's left to do is put everything back into the
uncompressed_library.swf over top of
$ cp library_uncompressed.swf library.swf
Or, optionally, you can re-compress it:
$ swfcombine -z -d library_uncompressed.swf -o library.swf
library.swf back into the
$ zip binary_library.swc library.swf
Finally try linking against it to see if everything worked!