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 issues#786 Decompiler errors
Author: kurzedmetal
Date created:
Type: bug
Visibility: Everybody
Assigned to:
Labels: AS1/2
State: closed
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)
ATG_-_Reconstruction.v1709.swf (2,679 KiB)ffdec_405n372_errors.zip (14 KiB)
sorry, I meant http://tiny.cc/aitg-data/?p=swf%2f for the location of the SWFs
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.
atg.png (96 KiB)
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.
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.
equals.swf (527 KiB)notequals.swf (527 KiB)
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?
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.
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)
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.
It is not decompiled correctly... you can see thet the "return result" is inside of the if
branch...
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.
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.
AS3JumpOverflowFix.class (3 KiB)
State: new→upgraded
Thanks for your time, the plugin seems to work fine.
No more error messages and it's decompiling the file correctly.
State: upgraded→closed