From bffc5d4ff0792ed29538e7d527f6a163af2c2c96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sun, 21 Feb 2021 17:59:38 +0100 Subject: [PATCH] Fixed: AS3 decompilation: try..catch..finally suborder when debugline info not present --- CHANGELOG.md | 1 + .../flash/abc/avm2/graph/AVM2Graph.java | 40 +++++++++++++++---- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a8d0289c..f82a8feca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ All notable changes to this project will be documented in this file. - Ribbon stealing focus when pressing Alt (for example in editors) - Focused byte barely visible in hex view - AS3 P-code editation - only first try offset was saved when multiple try with same label +- AS3 decompilation: try..catch..finally suborder when debugline info not present ### Changed - #1565, #1407, #1350 On BinaryData SWF save, parent SWF is saved diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java index 9206b3ccf..ee933a082 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java @@ -816,19 +816,25 @@ public class AVM2Graph extends Graph { if (!previouslyCatchedExceptionIds.contains(e)) { if (addr == fixedExStart) { //avm2code.getAddrThroughJumpAndDebugLine(fixedExStart)) { ABCException ex = body.exceptions[e]; - if (ex.isFinally()) { - finnalysIndicesToBe.add(e); + if (fixedExEnd >= maxEndAddr) { + finnalysIndicesToBe.add(e); + } } else { - long endAddr = avm2code.getAddrThroughJumpAndDebugLine(fixedExEnd); + long endAddr = fixedExEnd; if (endAddr > maxEndAddr) { catchedExceptionIds.clear(); - maxEndAddr = avm2code.getAddrThroughJumpAndDebugLine(fixedExEnd); - /*endIp = avm2code.adr2pos(maxEndAddr); - realEndIp = avm2code.adr2pos(fixedExEnd);*/ + maxEndAddr = fixedExEnd; catchedExceptionIds.add(e); + //filter finallys that have lower endAddr - they do not belong to these catches + for (int k = 0; k < finnalysIndicesToBe.size(); k++) { + if (body.exceptions[finnalysIndicesToBe.get(k)].end < endAddr) { + finnalysIndicesToBe.remove(k); + k--; + } + } } else if (endAddr == maxEndAddr) { catchedExceptionIds.add(e); } @@ -849,11 +855,24 @@ public class AVM2Graph extends Graph { outSideExceptionPart = searchFirstPartOutSideTryCatch(localData, body.exceptions[catchedExceptionIds.get(0)], loops, allParts); } + if (!finnalysIndicesToBe.isEmpty()) { + long maxEnd = 0; + int maxF = -1; + for (int f : finnalysIndicesToBe) { + long fixedExEnd = avm2code.pos2adr(avm2code.adr2pos(body.exceptions[f].end, true)); + if (fixedExEnd > maxEnd) { + maxEnd = fixedExEnd; + maxF = f; + } + } + finnalysIndicesToBe.clear(); + finnalysIndicesToBe.add(maxF); + } + for (int e : finnalysIndicesToBe) { ABCException finallyExceptionToBe = body.exceptions[e]; if (catchedExceptionIds.isEmpty() || outSideExceptionPart == null) { - //there's no exception, finally only - finallyIndex.setVal(e); + //there's no exception, finally only break; } GraphPart outSideExceptionNonEmptyPart = nearestNonEmptyPart(outSideExceptionPart); @@ -883,6 +902,11 @@ public class AVM2Graph extends Graph { } } } + + if (finallyIndex.getVal() == -1 && !finnalysIndicesToBe.isEmpty()) { + catchedExceptionIds.clear(); + finallyIndex.setVal(finnalysIndicesToBe.get(0)); + } } private boolean checkTry(List currentRet, List foundGotos, Map> partCodes, Map partCodePos, Set visited, AVM2LocalData localData, GraphPart part, List stopPart, List loops, List throwStates, Set allParts, TranslateStack stack, int staticOperation, String path, int recursionLevel) throws InterruptedException {