diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java index 4036cbc0d..90d8a4f59 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java @@ -282,6 +282,7 @@ import com.jpexs.decompiler.graph.ScopeStack; import com.jpexs.decompiler.graph.TranslateException; import com.jpexs.decompiler.graph.TranslateStack; import com.jpexs.decompiler.graph.TypeItem; +import com.jpexs.decompiler.graph.model.ExitItem; import com.jpexs.decompiler.graph.model.LocalData; import com.jpexs.decompiler.graph.model.ScriptEndItem; import com.jpexs.helpers.Helper; @@ -297,6 +298,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; +import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; @@ -675,6 +677,7 @@ public class AVM2Code implements Cloneable { public AVM2Code(ABCInputStream ais) throws IOException { Map codeMap = new TreeMap<>(); + Map endOffsets = new HashMap<>(); DumpInfo diParent = ais.dumpInfo; List addresses = new ArrayList<>(); long startPos = ais.getPosition(); @@ -738,6 +741,11 @@ public class AVM2Code implements Cloneable { } codeMap.put(startOffset, new AVM2Instruction(startOffset, instr, actualOperands)); ais.endDumpLevel(instr.instructionCode); + long endOffset = ais.getPosition(); + endOffsets.put(startOffset, endOffset); + if (instr.isExitInstruction()) { //do not continue if there is return/throw instruction + break; + } } else { ais.endDumpLevel(); break; // Unknown instructions are ignored (Some of the obfuscators add unknown instructions) @@ -750,6 +758,18 @@ public class AVM2Code implements Cloneable { } } + //If there are gaps between instructions, fill them with Nops, so the jump offsets are correct + List starts = new ArrayList<>(new TreeSet<>(codeMap.keySet())); + for (int s = 0; s < starts.size() - 1/*last does not have next endoffset instruction*/; s++) { + long curEnd = endOffsets.get(starts.get(s)); + if (!codeMap.containsKey(curEnd)) { + long nextStart = starts.get(s + 1); + for (long off = curEnd; off < nextStart; off++) { + codeMap.put(off, new AVM2Instruction(off, new NopIns(), new int[]{})); + } + } + } + code.addAll(codeMap.values()); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/InstructionDefinition.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/InstructionDefinition.java index 1310055d0..74909950a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/InstructionDefinition.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/InstructionDefinition.java @@ -169,4 +169,8 @@ public class InstructionDefinition implements Serializable { } return true; } + + public boolean isExitInstruction() { + return false; + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ReturnValueIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ReturnValueIns.java index fc2a94268..ae6ebcf08 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ReturnValueIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ReturnValueIns.java @@ -45,4 +45,10 @@ public class ReturnValueIns extends InstructionDefinition { public int getStackDelta(AVM2Instruction ins, ABC abc) { return -1; } + + @Override + public boolean isExitInstruction() { + return true; + } + } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ReturnVoidIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ReturnVoidIns.java index da8e060f9..f514e2f5c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ReturnVoidIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ReturnVoidIns.java @@ -40,4 +40,9 @@ public class ReturnVoidIns extends InstructionDefinition { public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { output.add(new ReturnVoidAVM2Item(ins)); } + + @Override + public boolean isExitInstruction() { + return true; + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ThrowIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ThrowIns.java index 57e35154d..75fd7d460 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ThrowIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/ThrowIns.java @@ -45,4 +45,9 @@ public class ThrowIns extends InstructionDefinition { public int getStackDelta(AVM2Instruction ins, ABC abc) { return -1; } + + @Override + public boolean isExitInstruction() { + return true; + } }