JPEXS Free Flash Decompiler Issue Tracker

If you are looking for the decompiler itself, visit https://github.com/jindrapetrik/jpexs-decompiler

NEW : We have got a new blog where we post some interesting SWF internals info.

List of issuesList of issues

#786 Decompiler errors
Date created:
Type: bug
Visibility: Everybody
Assigned to:
Labels: AS1/2
State: closed Help

In issue #774, honfika pointed me that this decompiler messages are errors that JPEXS could fix. So... I'm here creating a new issue with extra info: Decompiling "ATG_-_Reconstruction.v1709.swf" with FFdec v4.0.5 nightly 372 gives errors on stderr: Feb 01, 2015 11:47:58 PM com.jpexs.decompiler.flash.action.ActionGraphSource adr2pos SEVERE: Address loc12518 not found Feb 01, 2015 11:47:58 PM com.jpexs.decompiler.flash.action.swf4.ActionIf getBranches SEVERE: Invalid IF jump to ofs12518 Feb 01, 2015 11:47:58 PM com.jpexs.decompiler.flash.action.ActionGraphSource adr2pos SEVERE: Address loc12518 not found Feb 01, 2015 11:47:58 PM com.jpexs.decompiler.flash.action.swf4.ActionIf getBranches SEVERE: Invalid IF jump to ofs12518 I have multiple version of these flash game, most of them give similar messages, I'm not sure if they could be useful, so I'm uploading you all error messages (see "ffdec_405n372_errors.zip"). You can get the SWF that generated those messages from here: http://tiny.cc/aitg-data/?p=swf| (didn't want to upload all of them, it's quite each swf is around 5mb)
user
sorry, I meant http://tiny.cc/aitg-data/?p=swf%2f for the location of the SWFs
developer
This problem is strange... are you sure that this is not a bug in your SWF file? For me it seems to be to a bug in your file. See the attached image. The ActionIf which is in the error message is at the position 0x4A4E67, it is in the beginning of a function, the container function is marked with yellow in the screenshot. The if wants to jump out of the function, about 15800 bytes before the DefineFunction, this is not valid as i know. I think the offset should be -15806 + 65536, so an overflow occurred in the compiler, because: 0x4A4E67 -15806 + 65536 + 5 (if action length) = 0x4B10AE, which is the position if the next action after this function. So here should be a return. The releated AS code is this: function death() { if(enemyID != 0) { // here is the invalid jump } if(_root.save.arenaZone == 50)... Was this swf compiled with the official Adobe Flash compiler? So I think this method is currently not working when you call this function when enemyID == 0.
Downloadatg.png (96 KiB)
user
Hi, I'm not the dev of this game, but I contacted the developer and he gladly provided some info: He is developing with Adobe Flash CS3. And he provided the code of that part (attached), it seems that the conditional is wrapping all the code of the function, so if enemyID == 0, the function does absolutely nothing.
developer
Could you ask him to call this method when enemyID == 0?.... I bet, that the call will fail. I prepared 2 similar swfs, it contains the following: var result = "equals"; if(1 != 2) { // here more than 32K unused code result = "notequals"; } return result; Pcode: Push "result" "equals" DefineLocal Push 1 2 Equals If equals // here more than 32k code Push "result" "notequals" SetVariable equals:Push "result" GetVariable Return and: var result = "equals"; if(1 != 1) { // here more than 32K unused code result = "notequals"; } return result; Pcode: Push "result" "equals" DefineLocal Push 1 1 Equals If equals // here more than 32k code Push "result" "notequals" SetVariable equals:Push "result" GetVariable Return The difference is only 1 byte, the 2nd value of the condition, you can compare the 2 swfs with any binary file compare tool. The first returns "notequals", here the if action is false, so it won't jump. The second will fail, it won't show "equals". It tries to jump forward 35569, but it can't, because the jump offset is an signed 16 bit value, so it is interpreted as jump back 29967 bytes, which does not exists, so it fails. I still belive that this is not an FFDec bug, and your SWF won't work when you call it when the enemyID is zero.
Downloadequals.swf (527 KiB)Downloadnotequals.swf (527 KiB)
user
Well, let me see if I got this correctly: Are you telling me this is some kind of bug with the SWF compilers that generate an invalid jump when the function body is really big (or something similar to this case)? And the generated binary crashes even the official SWF player?
user
Ok, I just reread the part of the "jump offset is asigned 16 bit value" part and it makes more sense now, the function is simply too big.
developer
Yes, I think this is a bug in the SWF compiler, the operand of the If action is too big, so overflow occurs. But if it is compiled with the official flash compiler, it is very interesting, i think this is a huge bug in the compiler. Flash player is not crashing, I think this is the same as when you throw an exception, so if the caller puts the call in a try catch, the exception can be catched. And if there is no try-catch, the exception will be shown in the debug window of the flash player (if you have a debug player)
user
There's one thing I don't understand tho. Just like you said, the addressing problem can be reproduced with the "equals" files. If I run notequals.swf it works, if I run equals.swf it crashes (I tried it both with Pepper Flash in Chrome and normal Flash in FF). But I see that FFdec can decompile both files, equals.swf and notequals.swf, correctly anyways. How is it possible? I thought this addressing problem was the reason why it couldn't get decompiled correctly (which would totally make sense). Anyways, I understand that there's some kind of weird file format problem/limit here, if you think you can't do anything to improve or fix it by any means, just close this issue.
developer
It is not decompiled correctly... you can see thet the "return result" is inside of the if branch...
developer
I can create a setting, which detects this problem, and fixes them by interpreting the offset as an unsigned int 16 when the current target is negative, and tries to jump out of the function. But in this case the decompiled code is tricky, it is not the same as the actual compiled code, so I not really want to do this. JPEXS: What do you think about it? I have another idea, I'll write about it later, because it needs some time to implement.
developer
Since this is not a real bug, I not really wanted to put this to the main application, so I created a plugin for FFDec to fix this problem. You should put this class file to a folder called "plugins" next to ffdec.jar, so for exmaple if your application is here: C:\FFDec\ffdec.exe C:\FFDec\ffdec.jar C:\FFDec\lib\ffdec_lib.jar Then the plugin should be here: C:\FFDec\plugins\AS3JumpOverflowFix.class FFDec automatically loads the classes (and theoretically the java source files, too, but it probably needs JDK), and uses them as a plugin. This plugin should implement the com.jpexs.decompiler.flash.helpers.SWFDecompilerListener interface. You can also find the source code of this file in the following location: https://github.com/jindrapetrik/jpexs-decompiler/blob/master/libsrc/plugins/src/AS3JumpOve rflowFix.java It is very simple, just a for loop which fixes the offsets if they seems wrong. You need the latest nightly version of FFDec to load the plugins. Currently this is the only plugin, the interface maybe will be changed in the future, but in this case i'll update your AS3JumpOverflowFix.class file. I hope you find this solution useful.
State: new→upgraded
user
Thanks for your time, the plugin seems to work fine. No more error messages and it's decompiling the file correctly.
developer
State: upgraded→closed
developer
From nightly 1404 (or stable after 8.0.1) you need this plugin.