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

#11 Zero jumps in finally blocks
Date created:
Type: bug
Visibility: Everybody
Assigned to:
State: closed Help

Hi all. Yesterday i found another error with decompiling as3. In some cases compiler puts "jump 0" instructions (inside body of lookupswitch) in finally block implementation. Asdec does not recognize this and decompiled code looks broken. Here is the example code. private function test1(param1:String):String{ var str:String=param1; try { return str; } catch(e:Error) { trace("error is :"+e.message); } finally { return str; } } Decompiled code private function test1(param1:String) : String { var param1:String; var str:String; param1=param1; str=param1; try { return str; } catch(e:Error) { trace("error is :"+e.message); } finally { return _loc5_; } } P-code of finally block looks like this ... ofs0071:getscopeobject 1 getslot 2 coerce_a setlocal 5 pushbyte 2 jump ofs007e ofs007e:label pop ofs0080:label getlocal 5 kill 5 returnvalue lookupswitch ofs0094 2 ofs0022 ofs0066 ofs0080 ofs0094:kill 5 ... When asdec examines the code it just passes jump 0 (jump ofs007e ofs007e:label ) instruction and hence expression tree differs from original; I made some fixes in AVM2Code.java. They're working for me. Don't know if that's right way, but it can be useful AVM2Code.java: .... AVM2Instruction jmpIns = code.get(adr2pos(fixAddrAfterDebugLine(body.exceptions[e].end))); if (jmpIns.definition instanceof JumpIns) { int finStart = adr2pos(fixAddrAfterDebugLine(body.exceptions[e].end) + jmpIns.getBytes().length + jmpIns.operands[0]); finallyJumps.add(finStart); if (unknownJumps.contains(finStart)) { unknownJumps.remove((Integer) finStart); } for (int f = finStart; f <= end; f++) { //change 1. inside finally block there can be zero jump instructions //remember them if (code.get(f).definition instanceof JumpIns){ int jumpPos = adr2pos(code.get(f).getOffsets().get(0)); finallyJumps.add(jumpPos); if (unknownJumps.contains(jumpPos)) { unknownJumps.remove((Integer) jumpPos); } } //end of change 1. if (code.get(f).definition instanceof LookupSwitchIns) { AVM2Instruction swins = code.get(f); if (swins.operands.length >= 3) { if (swins.operands[0] == swins.getBytes().length) { if (adr2pos(pos2adr(f) + swins.operands[2]) < finStart) { finallyCommands = toSource(isStatic, classIndex, localRegs, stack, scopeStack, abc, constants, method_info, body, finStart, f - 1).output; returnPos = f + 1; break; } } } } } break; } .... AVM2Instruction ins = code.get(ip); //Ify s vice podminkama if (ins.definition instanceof JumpIns) { //change 2 sometimes zero jumps are needed //original code: /*if (ins.operands[0] == 0) { ip++; addr = pos2adr(ip); } else if (ins.operands[0] > 0) { int secondAddr = addr + ins.getBytes().length; int jumpAddr = secondAddr + ins.operands[0]; int jumpPos = adr2pos(jumpAddr);// */ int secondAddr = addr + ins.getBytes().length; int jumpAddr = secondAddr + ins.operands[0]; int jumpPos = adr2pos(jumpAddr); if (ins.operands[0] == 0 && !finallyJumps.contains(jumpPos)) { ip++; addr = pos2adr(ip); } else if (ins.operands[0] > 0 || finallyJumps.contains(jumpPos)) { //end of change 2 if (finallyJumps.contains(jumpPos)) { if (code.get(ip + 1).definition instanceof LabelIns) { if (code.get(ip + 2).definition instanceof PopIns) { if (code.get(ip + 3).definition instanceof LabelIns) { .....
Hi, sorry for answering too late. I made some changes to the code and now Asdec version 1.0.0 is available. The finally block problem should be fixed.
State: →closed
Title: Zero jumps in finally blocks→Zero jumps in finally blocks
Type: →bug
Visibility: →Everybody