From 6602ecffa054e91e9779d31c53bca72b47df7499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Mon, 16 Jan 2023 10:11:00 +0100 Subject: [PATCH] Fixed #1938 "Open loaded during play" Loader injection for Multiname types --- CHANGELOG.md | 3 +- .../flash/gui/debugger/DebuggerTools.java | 89 ++++++++++++++----- 2 files changed, 70 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81fa7d920..84bfd2927 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,7 +40,8 @@ All notable changes to this project will be documented in this file. - [#1938] AS3 - shortening + 1 to increment - [#1938] AS3 - implicit coercion of operations - [#1938] AS3 - initproperty compound operators, increment/decrement - +- [#1938] "Open loaded during play" Loader injection for Multiname types + ## [18.3.2] - 2023-01-10 ### Removed - [#1935], [#1913] Retaining shape exact position(bounds) in SVG export/import diff --git a/src/com/jpexs/decompiler/flash/gui/debugger/DebuggerTools.java b/src/com/jpexs/decompiler/flash/gui/debugger/DebuggerTools.java index b54e790d7..b4d232875 100644 --- a/src/com/jpexs/decompiler/flash/gui/debugger/DebuggerTools.java +++ b/src/com/jpexs/decompiler/flash/gui/debugger/DebuggerTools.java @@ -29,6 +29,7 @@ import com.jpexs.decompiler.flash.tags.FileAttributesTag; import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.helpers.Helper; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Random; import java.util.logging.Level; @@ -90,33 +91,79 @@ public class DebuggerTools { if (hasDebugger(swf)) { ScriptPack dsp = getDebuggerScriptPack(swf); String debuggerPkg = dsp.getClassPath().packageStr.toRawString(); + List displayTypes = Arrays.asList("Loader"); + List utilsTypes = Arrays.asList( + "getDefinitionByName", + "getQualifiedClassName", + "getQualifiedSuperclassName", + "describeType" + ); + for (ABCContainerTag ct : swf.getAbcList()) { ABC a = ct.getABC(); if (dsp.abc == a) { //do not replace Loader in debugger itself continue; } + int debuggerNs = a.constants.getNamespaceId(Namespace.KIND_PACKAGE, debuggerPkg, 0, true); for (int i = 1; i < a.constants.getMultinameCount(); i++) { Multiname m = a.constants.getMultiname(i); - if ("flash.display.Loader".equals(m.getNameWithNamespace(a.constants, true).toRawString())) { - m.namespace_index = a.constants.getNamespaceId(Namespace.KIND_PACKAGE, debuggerPkg, 0, true); - m.name_index = a.constants.getStringId("DebugLoader", true); - ((Tag) ct).setModified(true); - } else if ("flash.utils.getDefinitionByName".equals(m.getNameWithNamespace(a.constants, true).toRawString())) { - m.namespace_index = a.constants.getNamespaceId(Namespace.KIND_PACKAGE, debuggerPkg, 0, true); - m.name_index = a.constants.getStringId("debugGetDefinitionByName", true); - ((Tag) ct).setModified(true); - } else if ("flash.utils.getQualifiedClassName".equals(m.getNameWithNamespace(a.constants, true).toRawString())) { - m.namespace_index = a.constants.getNamespaceId(Namespace.KIND_PACKAGE, debuggerPkg, 0, true); - m.name_index = a.constants.getStringId("debugGetQualifiedClassName", true); - ((Tag) ct).setModified(true); - } else if ("flash.utils.getQualifiedSuperclassName".equals(m.getNameWithNamespace(a.constants, true).toRawString())) { - m.namespace_index = a.constants.getNamespaceId(Namespace.KIND_PACKAGE, debuggerPkg, 0, true); - m.name_index = a.constants.getStringId("debugGetQualifiedSuperclassName", true); - ((Tag) ct).setModified(true); - } else if ("flash.utils.describeType".equals(m.getNameWithNamespace(a.constants, true).toRawString())) { - m.namespace_index = a.constants.getNamespaceId(Namespace.KIND_PACKAGE, debuggerPkg, 0, true); - m.name_index = a.constants.getStringId("debugDescribeType", true); - ((Tag) ct).setModified(true); + String rawNsName = m.getNameWithNamespace(a.constants, true).toRawString(); + if (m.kind == Multiname.MULTINAME) { + String simpleName = m.getName(a.constants, new ArrayList<>(), true, false); + String nsToSearch; + if (displayTypes.contains(simpleName)) { + nsToSearch = "flash.display"; + } else if (utilsTypes.contains(simpleName)) { + nsToSearch = "flash.utils"; + } else { + continue; + } + + int nsFoundId = -1; + for (int ns : a.constants.getNamespaceSet(m.namespace_set_index).namespaces) { + String nsString = a.constants.namespaceToString(ns); + if (nsString != null) { + if (nsString.equals(nsToSearch)) { + nsFoundId = ns; + break; + } + } + } + if (nsFoundId > -1) { + m.kind = Multiname.QNAME; + m.namespace_index = nsFoundId; + m.namespace_set_index = 0; + rawNsName = m.getNameWithNamespace(a.constants, true).toRawString(); + } + } + if (null != rawNsName) { + switch (rawNsName) { + case "flash.display.Loader": + m.namespace_index = debuggerNs; + m.name_index = a.constants.getStringId("DebugLoader", true); + ((Tag) ct).setModified(true); + break; + case "flash.utils.getDefinitionByName": + m.namespace_index = debuggerNs; + m.name_index = a.constants.getStringId("debugGetDefinitionByName", true); + ((Tag) ct).setModified(true); + break; + case "flash.utils.getQualifiedClassName": + m.namespace_index = debuggerNs; + m.name_index = a.constants.getStringId("debugGetQualifiedClassName", true); + ((Tag) ct).setModified(true); + break; + case "flash.utils.getQualifiedSuperclassName": + m.namespace_index = debuggerNs; + m.name_index = a.constants.getStringId("debugGetQualifiedSuperclassName", true); + ((Tag) ct).setModified(true); + break; + case "flash.utils.describeType": + m.namespace_index = debuggerNs; + m.name_index = a.constants.getStringId("debugDescribeType", true); + ((Tag) ct).setModified(true); + break; + } } } } @@ -204,7 +251,7 @@ public class DebuggerTools { } } //Add to target SWF - ((Tag) ds).setSwf(swf); + ((Tag) ds).setSwf(swf); swf.addTagBefore((Tag) ds, (Tag) firstAbc); swf.getAbcList().add(swf.getAbcList().indexOf(firstAbc), ds); ((Tag) ds).setModified(true);