From 7d722fcdcd0d36e6b700c983264bd98219ac45c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sun, 19 Nov 2023 02:01:05 +0100 Subject: [PATCH] missing classes --- .../decompiler/flash/abc/ScriptPack.java | 126 +++++++++++++++--- .../flash/helpers/hilight/Highlighting.java | 87 ++++++++++-- 2 files changed, 179 insertions(+), 34 deletions(-) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java index 0c665b0af..98cfba4d2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java @@ -16,15 +16,22 @@ */ package com.jpexs.decompiler.flash.abc; +import com.jpexs.decompiler.flash.IdentifiersDeobfuscation; import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; import com.jpexs.decompiler.flash.abc.avm2.ConvertException; +import com.jpexs.decompiler.flash.abc.avm2.OffsetUpdater; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions; +import com.jpexs.decompiler.flash.abc.avm2.instructions.IfTypeIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.debug.DebugFileIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.debug.DebugIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.debug.DebugLineIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.LookupSwitchIns; import com.jpexs.decompiler.flash.abc.avm2.model.GlobalAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.parser.script.AbcIndexing; +import com.jpexs.decompiler.flash.abc.types.ABCException; import com.jpexs.decompiler.flash.abc.types.ConvertData; import com.jpexs.decompiler.flash.abc.types.MethodBody; import com.jpexs.decompiler.flash.abc.types.Multiname; @@ -370,6 +377,15 @@ public class ScriptPack extends AS3ClassTreeItem { abc.script_info.get(scriptIndex).setModified(false); } + private class Label { + public long addr; + + public Label(long addr) { + this.addr = addr; + } + + } + /** * Injects debugfile, debugline instructions into the code. * @@ -382,7 +398,7 @@ public class ScriptPack extends AS3ClassTreeItem { Map> bodyLineToPos = new HashMap<>(); Map> bodyToRegToName = new HashMap<>(); Map> bodyToRegToLine = new HashMap<>(); - + Set lonelyBody = new HashSet<>(); try { HighlightedText decompiled = SWF.getCached(this); @@ -391,6 +407,10 @@ public class ScriptPack extends AS3ClassTreeItem { txt = txt.replace("\r", ""); for (int i = 0; i < txt.length(); i++) { + /*if ((i % 1000) == 0) { + int percent = i * 100 / txt.length(); + System.err.println("" + i + "/" + txt.length() + " (" + percent + "%)"); + }*/ blk: while (true) { Highlighting sh = Highlighting.searchPos(decompiled.getSpecialHighlights(), i); @@ -407,7 +427,7 @@ public class ScriptPack extends AS3ClassTreeItem { if (method == null) { break blk; } - Highlighting instr = Highlighting.searchPos(decompiled.getInstructionHighlights(), i); //h + Highlighting instr = Highlighting.searchPos(decompiled.getInstructionHighlights(), i); //h /*if (instr == null) { continue; }*/ @@ -434,7 +454,7 @@ public class ScriptPack extends AS3ClassTreeItem { if (instrOffset == -1) { lonelyBody.add(bodyIndex); break blk; - } + } try { pos = abc.bodies.get(bodyIndex).getCode().adr2pos(instrOffset); } catch (ConvertException cex) { @@ -450,7 +470,7 @@ public class ScriptPack extends AS3ClassTreeItem { } //int origPos = bodyLineToPos.get(bodyIndex).containsKey(line) ? bodyLineToPos.get(bodyIndex).get(line) : -1; - bodyToPosToLine.get(bodyIndex).put(pos, line); + bodyToPosToLine.get(bodyIndex).put(pos, line); bodyLineToPos.get(bodyIndex).put(line, pos); } else { lonelyBody.add(bodyIndex); @@ -483,8 +503,14 @@ public class ScriptPack extends AS3ClassTreeItem { //String filepath = path.toString().replace('.', '/') + ".as"; String pkg = path.packageStr.toString(); String cls = path.className; - String filename = new File(directoryPath, path.packageStr.toFilePath()) + ";" + pkg.replace(".", File.separator) + ";" + cls + ".as"; - + String filename = new File(directoryPath, path.packageStr.toFilePath()).getPath().replace(";", "{{semicolon}}") + + ";" + + pkg.replace(".", File.separator).replace(";", "{{semicolon}}") + + ";" + + cls.replace(";", "{{semicolon}}") + + ".as"; + filename = filename.replaceAll("\\{(invalid_utf8=[0-9]+)\\}", "[$1]"); + //Remove debug info from lonely bodies for (int bodyIndex : lonelyBody) { if (!bodyToPosToLine.keySet().contains(bodyIndex)) { @@ -537,33 +563,91 @@ public class ScriptPack extends AS3ClassTreeItem { Collections.sort(pos); Collections.reverse(pos); Set addedLines = new HashSet<>(); - loopi: - for (int i : pos) { + Set importantOffsets = b.getCode().getImportantOffsets(b, true); + List code2 = new ArrayList<>(); + Map origPosToNewPos = new HashMap<>(); + for (int i = 0; i < code.size(); i++) { + long adr = b.getCode().pos2adr(i); + if (importantOffsets.contains(adr)) { + code2.add(new Label(adr)); + } + origPosToNewPos.put(i, code2.size()); + if (delIns.contains(code.get(i))) { + continue; + } + code2.add(code.get(i)); + } + for (int i : pos) { int line = bodyToPosToLine.get(bodyIndex).get(i); if (addedLines.contains(line)) { continue; } addedLines.add(line); logger.log(Level.FINE, "Script {0}: Insert debugline({1}) at pos {2} to body {3}", new Object[]{path, line, i, bodyIndex}); - b.insertInstruction(i + dpos, new AVM2Instruction(0, AVM2Instructions.DebugLine, new int[]{line})); + code2.add(origPosToNewPos.get(i + dpos), new AVM2Instruction(0, AVM2Instructions.DebugLine, new int[]{line})); } - //remove old debug instructions - for (int i = 0; i < code.size(); i++) { - AVM2Instruction ins = code.get(i); - for (AVM2Instruction d : delIns) { - if (ins == d) { - b.removeInstruction(i); - i--; - break; + long adr = 0; + Map mapOffsets = new HashMap<>(); + for (int i = 0; i < code2.size(); i++) { + Object obj = code2.get(i); + if (obj instanceof AVM2Instruction) { + AVM2Instruction ins = (AVM2Instruction) obj; + adr += ins.getBytesLength(); + } + if (obj instanceof Label) { + Label lab = (Label) obj; + mapOffsets.put(lab.addr, adr); + } + } + code.clear(); + + adr = 0; + for (int i = 0; i < code2.size(); i++) { + Object obj = code2.get(i); + if (obj instanceof AVM2Instruction) { + AVM2Instruction ins = (AVM2Instruction) obj; + long targetAddr; + long changedAddr; + int changedOperand; + if (ins.definition instanceof IfTypeIns) { + targetAddr = ins.getTargetAddress(); + changedAddr = mapOffsets.get(targetAddr); + changedOperand = (int) (changedAddr - adr - 4); + ins.operands[0] = changedOperand; } + if (ins.definition instanceof LookupSwitchIns) { + targetAddr = ins.getAddress() + ins.operands[0]; + changedAddr = mapOffsets.get(targetAddr); + changedOperand = (int) (changedAddr - adr); + ins.operands[0] = changedOperand; + for (int k = 2; k < ins.operands.length; k++) { + targetAddr = ins.getAddress() + ins.operands[k]; + changedAddr = mapOffsets.get(targetAddr); + changedOperand = (int) (changedAddr - adr); + ins.operands[k] = changedOperand; + } + } + ins.setAddress(adr); + adr += ins.getBytesLength(); + code.add(ins); } } - + for (ABCException ex : b.exceptions) { + long lstart = ex.start; + long ltarget = ex.target; + long lend = ex.end; + lstart = mapOffsets.get(lstart); + ltarget = mapOffsets.get(ltarget); + lend = mapOffsets.get(lend); + ex.start = (int) lstart; + ex.target = (int) ltarget; + ex.end = (int) lend; + } b.setModified(); } - - ((Tag) abc.parentTag).setModified(true); - } + + ((Tag) abc.parentTag).setModified(true); + } public void injectPCodeDebugInfo(int abcIndex) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/hilight/Highlighting.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/hilight/Highlighting.java index 12df7023e..69652a15e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/hilight/Highlighting.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/hilight/Highlighting.java @@ -19,7 +19,10 @@ package com.jpexs.decompiler.flash.helpers.hilight; import com.jpexs.decompiler.flash.configuration.Configuration; import java.io.Serializable; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; /** * Provides methods for highlighting positions of instructions in the text. @@ -48,7 +51,7 @@ public class Highlighting implements Serializable { return properties; } - public static Highlighting search(List list, HighlightData properties, long from, long to) { + public static Highlighting search(HighlightingList list, HighlightData properties, long from, long to) { Highlighting ret = null; looph: for (Highlighting h : list) { @@ -82,11 +85,41 @@ public class Highlighting implements Serializable { return null; } - public static Highlighting searchPos(List list, long pos) { + public static Highlighting searchPos(HighlightingList list, long pos) { return searchPos(list, pos, -1, -1); } + + public static Highlighting searchPos(HighlightingList list, long pos, long from, long to) { + return searchPosNew(list, pos, from, to); + } - public static Highlighting searchPos(List list, long pos, long from, long to) { + public static Highlighting searchPosNew(HighlightingList list, long pos, long from, long to) { + Highlighting[] hmap = posToHighlightMap(list); + if (pos > -1) { + if (pos >= hmap.length) { + return null; + } + return hmap[(int) pos]; + } + if (from == -1) { + from = 0; + } + if (to == -1) { + to = hmap.length; + } + for (long i = from; i < to; i++) { + Highlighting h = hmap[(int) i]; + if (h != null) { + return h; + } + } + return null; + } + + + + /*public static Highlighting searchPosOld(HighlightingList list, long pos, long from, long to) { + Highlighting ret = null; looph: for (Highlighting h : list) { @@ -111,13 +144,41 @@ public class Highlighting implements Serializable { } return ret; + }*/ + + private static final Map listToPosMap = new WeakHashMap<>(); + + private static Highlighting[] posToHighlightMap(HighlightingList list) { + if (list.isEmpty()) { + return new Highlighting[0]; + } + if (listToPosMap.containsKey(list)) { + return listToPosMap.get(list); + } + Highlighting lastH = list.get(list.size() - 1); + int maxPos = lastH.startPos + Math.max(1, lastH.len); + Highlighting[] map = new Highlighting[maxPos]; + for (Highlighting h : list) { + for (int i = h.startPos; i < h.startPos + Math.max(1, h.len); i++) { + Highlighting oldH = map[i]; + if (oldH == null) { + map[i] = h; + continue; + } + if (h.len < oldH.len) { + map[i] = h; + } + } + } + listToPosMap.put(list, map); + return map; } - public static Highlighting searchOffset(List list, long offset) { + public static Highlighting searchOffset(HighlightingList list, long offset) { return searchOffset(list, offset, -1, -1); } - public static Highlighting searchOffset(List list, long offset, long from, long to) { + public static Highlighting searchOffset(HighlightingList list, long offset, long from, long to) { looph: for (Highlighting h : list) { if (from > -1) { @@ -140,11 +201,11 @@ public class Highlighting implements Serializable { return null; } - public static Highlighting searchIndex(List list, long index) { + public static Highlighting searchIndex(HighlightingList list, long index) { return searchIndex(list, index, -1, -1); } - public static Highlighting searchIndex(List list, long index, long from, long to) { + public static Highlighting searchIndex(HighlightingList list, long index, long from, long to) { looph: for (Highlighting h : list) { if (from > -1) { @@ -167,8 +228,8 @@ public class Highlighting implements Serializable { return null; } - public static List searchAllPos(List list, long pos) { - List ret = new ArrayList<>(); + public static HighlightingList searchAllPos(HighlightingList list, long pos) { + HighlightingList ret = new HighlightingList(); for (Highlighting h : list) { if (pos == -1 || (pos >= h.startPos && (pos < h.startPos + h.len))) { ret.add(h); @@ -178,8 +239,8 @@ public class Highlighting implements Serializable { return ret; } - public static List searchAllIndexes(List list, long index) { - List ret = new ArrayList<>(); + public static HighlightingList searchAllIndexes(HighlightingList list, long index) { + HighlightingList ret = new HighlightingList(); for (Highlighting h : list) { long i = h.getProperties().index; if (i == index) { @@ -190,8 +251,8 @@ public class Highlighting implements Serializable { return ret; } - public static List searchAllLocalNames(List list, String localName) { - List ret = new ArrayList<>(); + public static HighlightingList searchAllLocalNames(HighlightingList list, String localName) { + HighlightingList ret = new HighlightingList(); for (Highlighting h : list) { if (localName.equals(h.getProperties().localName)) { ret.add(h);