From 5d13387f7b2744ca33360fc215a5316b1ee6cc8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Tue, 20 Dec 2022 17:17:10 +0100 Subject: [PATCH] Fixed AS3 direct editation and decompiler share same AbcIndex --- CHANGELOG.md | 1 + .../abc/avm2/parser/script/AbcIndexing.java | 50 ++++++++----------- .../parser/script/ActionScript3Parser.java | 17 +++---- .../importers/FFDecAs3ScriptReplacer.java | 2 +- .../flash/ActionScript3DeobfuscatorTest.java | 2 +- .../console/CommandLineArgumentParser.java | 2 +- .../flash/gui/tagtree/TagTreeContextMenu.java | 2 +- 7 files changed, 33 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71c34e29a..65f37bc50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file. - [#1904] AS1/2 Simplify expressions breaks registers, functions - [#1904] AS1/2 Throw is an ExitItem to properly handle continues vs ifs - AS3 direct editation - protected property resolving +- AS3 direct editation and decompiler share same AbcIndex ### Changed - Warning before switching deobfuscation is now optional diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java index 3b7289572..220de7778 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java @@ -142,7 +142,7 @@ public final class AbcIndexing { public String getPropNsString() { return propNsString; - } + } /** * Creates key to property. @@ -178,7 +178,7 @@ public final class AbcIndexing { } } } - + public PropertyDef(String propName, GraphTargetItem parent, String propNsString) { this.propName = propName; this.parent = parent; @@ -316,11 +316,11 @@ public final class AbcIndexing { this.objType = objType; } } - + private static class ClassDef { public GraphTargetItem type; - public DottedChain pkg; - + public DottedChain pkg; + public ClassDef(GraphTargetItem type, ABC abc, Integer scriptIndex) { this.type = type; if (scriptIndex != null) { @@ -358,9 +358,7 @@ public final class AbcIndexing { } return Objects.equals(this.pkg, other.pkg); } - - - + } public static class ClassIndex { @@ -370,7 +368,7 @@ public final class AbcIndexing { public ABC abc; public ClassIndex parent; - + public Integer scriptIndex; @Override @@ -417,7 +415,7 @@ public final class AbcIndexing { return false; } return Objects.equals(this.scriptIndex, other.scriptIndex); - } + } } private final Map classes = new HashMap<>(); @@ -430,23 +428,23 @@ public final class AbcIndexing { private final Map classNsProperties = new HashMap<>(); - private final Map scriptProperties = new HashMap<>(); - + private final Map scriptProperties = new HashMap<>(); + public ClassIndex findClass(GraphTargetItem cls, ABC abc, Integer scriptIndex) { ClassDef keyWithScriptIndex = new ClassDef(cls, abc, scriptIndex); if (classes.containsKey(keyWithScriptIndex)) { return classes.get(keyWithScriptIndex); } - + ClassDef keyWithNoScriptIndex = new ClassDef(cls, abc, null); if (classes.containsKey(keyWithNoScriptIndex)) { return classes.get(keyWithNoScriptIndex); } - + if (parent == null) { return null; } - return parent.findClass(cls, abc, scriptIndex); + return parent.findClass(cls, abc, scriptIndex); } public void findPropertyTypeOrCallType(ABC abc, GraphTargetItem cls, String propName, int ns, boolean findStatic, boolean findInstance, boolean findProtected, Reference type, Reference callType) { @@ -459,8 +457,7 @@ public final class AbcIndexing { callType.setVal(traitIndex.callReturnType); } } - - + public GraphTargetItem findPropertyType(ABC abc, GraphTargetItem cls, String propName, int ns, boolean findStatic, boolean findInstance, boolean findProtected) { TraitIndex traitIndex = findProperty(new PropertyDef(propName, cls, abc, ns), findStatic, findInstance, findProtected); if (traitIndex == null) { @@ -529,7 +526,7 @@ public final class AbcIndexing { } } System.out.println("-----------"); -*/ + */ //search all static first if (findStatic && classProperties.containsKey(prop)) { if (!classProperties.containsKey(prop)) { @@ -562,7 +559,7 @@ public final class AbcIndexing { AbcIndexing.ClassIndex ci = findClass(prop.parent, prop.abc, null); if (ci != null && ci.parent != null && (prop.abc == null || prop.propNsIndex == 0)) { AbcIndexing.ClassIndex ciParent = ci.parent; - DottedChain parentClass = ciParent.abc.instance_info.get(ciParent.index).getName(ciParent.abc.constants).getNameWithNamespace(ciParent.abc.constants, true); + DottedChain parentClass = ciParent.abc.instance_info.get(ciParent.index).getName(ciParent.abc.constants).getNameWithNamespace(ciParent.abc.constants, true); TraitIndex pti = findProperty(new PropertyDef(prop.propName, new TypeItem(parentClass), prop.getPropNsString()), findStatic, findInstance, findProtected); if (pti != null) { return pti; @@ -618,7 +615,7 @@ public final class AbcIndexing { return new ApplyTypeAVM2Item(null, null, obj, params); } else { if (m.namespace_index != 0 && m.getNamespace(constants).kind == Namespace.KIND_PRIVATE) { - return new TypeItem(m.getName(constants, new ArrayList<>(), true, true), "ns:"+m.namespace_index); + return new TypeItem(m.getName(constants, new ArrayList<>(), true, true), "ns:" + m.namespace_index); } return new TypeItem(m.getNameWithNamespace(constants, true)); } @@ -626,7 +623,7 @@ public final class AbcIndexing { public static GraphTargetItem multinameToType(int m_index, AVM2ConstantPool constants) { return multinameToType(new HashSet<>(), m_index, constants); - } + } private static GraphTargetItem getTraitCallReturnType(ABC abc, Trait t) { if (t instanceof TraitSlotConst) { @@ -766,16 +763,13 @@ public final class AbcIndexing { return; } List addedClasses = new ArrayList<>(); - - for (int i = 0; i < abc.instance_info.size(); i++) { - - } - for (int i = 0; i < abc.script_info.size(); i++) { + + for (int i = 0; i < abc.script_info.size(); i++) { indexTraits(abc, 0, abc.script_info.get(i).traits, null, scriptProperties); - for (int t = 0; t < abc.script_info.get(i).traits.traits.size(); t++) { + for (int t = 0; t < abc.script_info.get(i).traits.traits.size(); t++) { Trait tr = abc.script_info.get(i).traits.traits.get(t); if (tr instanceof TraitClass) { - TraitClass tc = (TraitClass)tr; + TraitClass tc = (TraitClass) tr; InstanceInfo ii = abc.instance_info.get(tc.class_info); if (ii.deleted) { continue; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java index be25a688f..f17bcbefa 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java @@ -2605,21 +2605,16 @@ public class ActionScript3Parser { addScriptFromTree(allOpenedNamespaces, traits, classPos); } - public ActionScript3Parser(ABC abc, List otherAbcs, boolean air) throws IOException, InterruptedException { + public ActionScript3Parser(AbcIndexing abcIndex) throws IOException, InterruptedException { SWF.initPlayer(); - abcIndex = new AbcIndexing(air ? SWF.getAirGlobalAbcIndex() : SWF.getPlayerGlobalAbcIndex()); - for (ABC a : otherAbcs) { - abcIndex.addAbc(a); - } - - abcIndex.addAbc(abc); + this.abcIndex = abcIndex; } - public static void compile(String src, ABC abc, List otherABCs, String fileName, int classPos, int scriptIndex, boolean air) throws AVM2ParseException, IOException, InterruptedException, CompilationException { + public static void compile(String src, ABC abc, AbcIndexing abcIndex, String fileName, int classPos, int scriptIndex, boolean air) throws AVM2ParseException, IOException, InterruptedException, CompilationException { //List parABCs = new ArrayList<>(); SWF.initPlayer(); - ActionScript3Parser parser = new ActionScript3Parser(abc, otherABCs, air); + ActionScript3Parser parser = new ActionScript3Parser(abcIndex); boolean success = false; ABC originalAbc = ((ABCContainerTag) ((Tag) abc.parentTag).cloneTag()).getABC(); try { @@ -2640,12 +2635,12 @@ public class ActionScript3Parser { } } - public static void compile(SWF swf, String src, String dst, int classPos, int scriptIndex, boolean air) { + public static void compile(SWF swf, String src, String dst, int classPos, int scriptIndex) { System.err.println("WARNING: AS3 compiler is not finished yet. This is only used for debuggging!"); try { SWF.initPlayer(); ABC abc = new ABC(null); - ActionScript3Parser parser = new ActionScript3Parser(abc, new ArrayList<>(), air); + ActionScript3Parser parser = new ActionScript3Parser(swf.getAbcIndex()); parser.addScript(new String(Helper.readFile(src), Utf8Helper.charset), src, classPos, scriptIndex); try ( OutputStream fos = new BufferedOutputStream(new FileOutputStream(new File(dst)))) { abc.saveToStream(fos); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/FFDecAs3ScriptReplacer.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/FFDecAs3ScriptReplacer.java index f1c1becc0..c7c899cf8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/FFDecAs3ScriptReplacer.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/FFDecAs3ScriptReplacer.java @@ -71,7 +71,7 @@ public class FFDecAs3ScriptReplacer implements As3ScriptReplacerInterface { otherAbcs.remove(abc); abc.script_info.get(oldIndex).delete(abc, true); - ActionScript3Parser.compile(text, abc, otherAbcs, scriptName, newClassIndex, oldIndex, air); + ActionScript3Parser.compile(text, abc, swf.getAbcIndex(), scriptName, newClassIndex, oldIndex, air); if (pack.isSimple) { // Move newly added script to its position abc.script_info.set(oldIndex, abc.script_info.get(newIndex)); diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3DeobfuscatorTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3DeobfuscatorTest.java index 208e54fb6..47895953a 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3DeobfuscatorTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3DeobfuscatorTest.java @@ -127,7 +127,7 @@ public class ActionScript3DeobfuscatorTest extends ActionScriptTestBase { public void setABC(ABC abc) { } }); - ActionScript3Parser par = new ActionScript3Parser(abc, new ArrayList<>(), false); + ActionScript3Parser par = new ActionScript3Parser(swf.getAbcIndex()); HighlightedTextWriter writer = new HighlightedTextWriter(new CodeFormatting(), false); par.addScript(str, "Test.as", 0, 0); diff --git a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java index c98b3a75b..2b5d6681f 100644 --- a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java +++ b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java @@ -988,7 +988,7 @@ public class CommandLineArgumentParser { } else if (command.equals("importscript")) { parseImportScript(args, charset, air); } else if (command.equals("as3compiler")) { - ActionScript3Parser.compile(null /*?*/, args.pop(), args.pop(), 0, 0, air); + ActionScript3Parser.compile(null /*?*/, args.pop(), args.pop(), 0, 0); } else if (nextParam.equals("--debugtool")) { parseDebugTool(args, charset); } else if (nextParam.equals("--compareresources")) { diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java index 0111ff429..72a70395d 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java @@ -1864,7 +1864,7 @@ public class TagTreeContextMenu extends JPopupMenu { } } try { - ActionScript3Parser parser = new ActionScript3Parser(doAbc.getABC(), abcs, false); + ActionScript3Parser parser = new ActionScript3Parser(swf.getAbcIndex()); DottedChain dc = new DottedChain(pkgParts); String script = "package " + dc.toPrintableString(true) + " {"