From e9063e487b4320b96a3dc1017225823c55146dd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sat, 11 Mar 2023 22:50:30 +0100 Subject: [PATCH] Fixed AS3 - getouterscope instruction support --- CHANGELOG.md | 2 +- .../decompiler/flash/abc/AVM2LocalData.java | 3 ++ .../decompiler/flash/abc/ScriptPack.java | 9 +++- .../decompiler/flash/abc/avm2/AVM2Code.java | 21 +++++----- .../deobfuscation/AVM2DeobfuscatorGetSet.java | 2 + .../AVM2DeobfuscatorSimpleOld.java | 2 + .../flash/abc/avm2/graph/AVM2Graph.java | 23 +++++++---- .../flash/abc/avm2/graph/AVM2GraphSource.java | 8 +--- .../instructions/InstructionDefinition.java | 5 ++- .../construction/NewFunctionIns.java | 5 ++- .../localregs/GetLocalTypeIns.java | 11 +++-- .../instructions/other/GetOuterScopeIns.java | 20 +++++++++ .../instructions/other/GetScopeObjectIns.java | 2 +- .../avm2/instructions/stack/PopScopeIns.java | 2 +- .../avm2/instructions/stack/PushScopeIns.java | 2 +- .../avm2/instructions/stack/PushWithIns.java | 2 +- .../flash/abc/avm2/model/ClassAVM2Item.java | 15 +++++++ .../abc/avm2/model/NewFunctionAVM2Item.java | 2 +- .../flash/abc/avm2/model/ThisAVM2Item.java | 16 ++++++- .../flash/abc/types/traits/Trait.java | 9 ++-- .../flash/abc/types/traits/TraitClass.java | 36 ++++++++++++---- .../flash/abc/types/traits/TraitFunction.java | 4 +- .../types/traits/TraitMethodGetterSetter.java | 4 +- .../abc/types/traits/TraitSlotConst.java | 3 +- .../flash/abc/types/traits/Traits.java | 16 ++++--- .../exporters/script/DependencyParser.java | 28 +++++++++++++ .../script/PcodeGraphVizExporter.java | 2 +- .../as3decompile/ActionScript3ClassTest.java | 39 ++++++++++++++++++ .../testdata/getouterscope/getouterscope.swf | Bin 0 -> 1029 bytes .../flash/gui/abc/ASMSourceEditorPane.java | 2 +- 30 files changed, 227 insertions(+), 68 deletions(-) create mode 100644 libsrc/ffdec_lib/testdata/getouterscope/getouterscope.swf diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d4bf9924d..0dbb466858 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,7 @@ All notable changes to this project will be documented in this file. - AS3 p-code docs - deldescendants, negate_p operands - AS3 p-code - IGNORE_REST method flag incorrectly shown as EXPLICIT - [#1989] AS3 - Slow deobfuscation (AVM2DeobfuscatorSimpleOld) -- AS3 p-code - getouterscope instruction docs +- AS3 - getouterscope instruction support ### Changed - AS1/2/3 P-code - format Number values with EcmaScript toString function diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/AVM2LocalData.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/AVM2LocalData.java index 83a81bd823..8d403b46ee 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/AVM2LocalData.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/AVM2LocalData.java @@ -50,6 +50,8 @@ public class AVM2LocalData extends BaseLocalData { public HashMap localRegs; public ScopeStack scopeStack; + + public ScopeStack localScopeStack; public MethodBody methodBody; @@ -145,6 +147,7 @@ public AVM2LocalData(AVM2LocalData localData) { classIndex = localData.classIndex; localRegs = localData.localRegs; scopeStack = localData.scopeStack; + localScopeStack = localData.localScopeStack; methodBody = localData.methodBody; callStack = localData.callStack; abc = localData.abc; 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 3a2aa3fe55..c603377c54 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 @@ -23,6 +23,7 @@ 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.model.GlobalAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.parser.script.AbcIndexing; import com.jpexs.decompiler.flash.abc.types.ConvertData; import com.jpexs.decompiler.flash.abc.types.MethodBody; @@ -197,14 +198,18 @@ public void convert(AbcIndexing abcIndex, final NulWriter writer, final List(), parallel); + trait.convertPackaged(abcIndex, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList<>(), parallel, scopeStack); } else { - trait.convert(abcIndex, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList<>(), parallel); + trait.convert(abcIndex, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList<>(), parallel, scopeStack); } } } 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 0f89ffa3dc..431b480a83 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 @@ -1486,7 +1486,7 @@ public long getAddrThroughJumpAndDebugLine(long addr) throws ConvertException { return pos2adr(getIpThroughJumpAndDebugLine(adr2pos(addr, true))); } - public ConvertOutput toSourceOutput(Set switchParts, List callStack, AbcIndexing abcIndex, Map> setLocalPosToGetLocalPos, boolean thisHasDefaultToPrimitive, Reference lineStartItem, String path, GraphPart part, boolean processJumps, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, ABC abc, MethodBody body, int start, int end, HashMap localRegNames, HashMap localRegTypes, List fullyQualifiedNames, boolean[] visited, HashMap localRegAssigmentIps) throws ConvertException, InterruptedException { + public ConvertOutput toSourceOutput(Set switchParts, List callStack, AbcIndexing abcIndex, Map> setLocalPosToGetLocalPos, boolean thisHasDefaultToPrimitive, Reference lineStartItem, String path, GraphPart part, boolean processJumps, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, ScopeStack localScopeStack, ABC abc, MethodBody body, int start, int end, HashMap localRegNames, HashMap localRegTypes, List fullyQualifiedNames, boolean[] visited, HashMap localRegAssigmentIps) throws ConvertException, InterruptedException { boolean debugMode = DEBUG_MODE; if (debugMode) { System.err.println("OPEN SubSource:" + start + "-" + end + " " + code.get(start).toString() + " to " + code.get(end).toString()); @@ -1531,7 +1531,7 @@ public ConvertOutput toSourceOutput(Set switchParts, List } if (debugMode) { - System.err.println("translating ip " + ip + " ins " + ins.toString() + " stack:" + stack.toString() + " scopeStack:" + scopeStack.toString()); + System.err.println("translating ip " + ip + " ins " + ins.toString() + " stack:" + stack.toString() + " localScopeStack:" + localScopeStack.toString()); } if (ins.definition instanceof NewFunctionIns) { if (ip + 1 <= end) { @@ -1560,7 +1560,7 @@ public ConvertOutput toSourceOutput(Set switchParts, List do { AVM2Instruction insAfter = ip + 1 < code.size() ? code.get(ip + 1) : null; if (insAfter == null) { - ins.definition.translate(switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, this, thisHasDefaultToPrimitive); + ins.definition.translate(switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, localScopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, this, thisHasDefaultToPrimitive); ip++; break; } @@ -1582,14 +1582,14 @@ public ConvertOutput toSourceOutput(Set switchParts, List //stack.add("(" + stack.pop() + ")||"); isAnd = false; } else { - ins.definition.translate(switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, this, thisHasDefaultToPrimitive); + ins.definition.translate(switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, localScopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, this, thisHasDefaultToPrimitive); ip++; break; //throw new ConvertException("Unknown pattern after DUP:" + insComparsion.toString()); } } while (ins.definition instanceof DupIns); } else if ((ins.definition instanceof ReturnValueIns) || (ins.definition instanceof ReturnVoidIns) || (ins.definition instanceof ThrowIns)) { - ins.definition.translate(switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, this, thisHasDefaultToPrimitive); + ins.definition.translate(switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, localScopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, this, thisHasDefaultToPrimitive); //ip = end + 1; break; } else if (ins.definition instanceof NewFunctionIns) { @@ -1607,12 +1607,12 @@ public ConvertOutput toSourceOutput(Set switchParts, List } AVM2Instruction psco = code.get(ip + 1 + plus); if (psco.definition instanceof GetScopeObjectIns) { - if (psco.operands[0] == scopeStack.size() - 1) { + if (psco.operands[0] == localScopeStack.size() - 1) { if (code.get(ip + plus + 2).definition instanceof SwapIns) { if (code.get(ip + plus + 4).definition instanceof PopScopeIns) { if (code.get(ip + plus + 3).definition instanceof SetPropertyIns) { functionName = abc.constants.getMultiname(code.get(ip + plus + 3).operands[0]).getName(abc.constants, fullyQualifiedNames, true, true); - scopeStack.pop();// with + localScopeStack.pop();// with output.remove(output.size() - 1); // with ip = ip + plus + 4; // +1 below } @@ -1625,13 +1625,13 @@ public ConvertOutput toSourceOutput(Set switchParts, List } } // What to do when hasDup is false? - ins.definition.translate(switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, this, thisHasDefaultToPrimitive); + ins.definition.translate(switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, localScopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, this, thisHasDefaultToPrimitive); NewFunctionAVM2Item nft = (NewFunctionAVM2Item) stack.peek(); nft.functionName = functionName; ip++; } else { try { - ins.definition.translate(switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, this, thisHasDefaultToPrimitive); + ins.definition.translate(switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, localScopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, this, thisHasDefaultToPrimitive); } catch (RuntimeException re) { /*String last=""; int len=5; @@ -2059,11 +2059,10 @@ public List toGraphTargetItems(List callStack, AbcI localRegTypes.put(i + 1, AbcIndexing.multinameToType(abc.method_info.get(methodIndex).param_types[i], abc.constants)); } - ScopeStack prevScopeStack = (ScopeStack) scopeStack.clone(); try { list = AVM2Graph.translateViaGraph(null, callStack, abcIndex, path, this, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localRegNames, localRegTypes, fullyQualifiedNames, staticOperation, localRegAssigmentIps, thisHasDefaultToPrimitive); } catch (SecondPassException spe) { - list = AVM2Graph.translateViaGraph(spe.getData(), callStack, abcIndex, path, this, abc, body, isStatic, scriptIndex, classIndex, localRegs, prevScopeStack, localRegNames, localRegTypes, fullyQualifiedNames, staticOperation, localRegAssigmentIps, thisHasDefaultToPrimitive); + list = AVM2Graph.translateViaGraph(spe.getData(), callStack, abcIndex, path, this, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localRegNames, localRegTypes, fullyQualifiedNames, staticOperation, localRegAssigmentIps, thisHasDefaultToPrimitive); } if (initTraits != null) { loopi: diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorGetSet.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorGetSet.java index d43e1d2c9f..c201658b3c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorGetSet.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorGetSet.java @@ -87,6 +87,7 @@ protected boolean removeObfuscationGetSets(int classIndex, boolean isStatic, int } localData.scopeStack.clear(); + localData.localScopeStack.clear(); localData.localRegs.clear(); localData.localRegAssignmentIps.clear(); localData.localRegs.clear(); @@ -109,6 +110,7 @@ protected AVM2LocalData newLocalData(int scriptIndex, ABC abc, AVM2ConstantPool localData.localRegs = new HashMap<>(body.max_regs); localData.localRegAssignmentIps = new HashMap<>(); localData.scopeStack = new ScopeStack(true); + localData.localScopeStack = new ScopeStack(true); List callStack = new ArrayList<>(); callStack.add(body); localData.callStack = callStack; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimpleOld.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimpleOld.java index d7638f687a..b0e4bbef0c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimpleOld.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimpleOld.java @@ -179,6 +179,7 @@ protected boolean removeObfuscationIfs(int classIndex, boolean isStatic, int scr } localData.scopeStack.clear(); + localData.localScopeStack.clear(); localData.localRegs.clear(); localData.localRegAssignmentIps.clear(); localData.localRegs.clear(); @@ -202,6 +203,7 @@ protected AVM2LocalData newLocalData(int scriptIndex, ABC abc, AVM2ConstantPool localData.localRegs = new HashMap<>(body.max_regs); localData.localRegAssignmentIps = new HashMap<>(); localData.scopeStack = new ScopeStack(true); + localData.localScopeStack = new ScopeStack(true); List callStack = new ArrayList<>(); callStack.add(body); localData.callStack = callStack; 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 376ae42faf..ddb92e6709 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 @@ -161,8 +161,8 @@ private static List getExceptionEntries(MethodBody body) { return ret; } - public AVM2Graph(AbcIndexing abcIndex, AVM2Code code, ABC abc, MethodBody body, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, ScopeStack scopeStack, HashMap localRegNames, List fullyQualifiedNames, HashMap localRegAssigmentIps) { - super(new AVM2GraphSource(code, isStatic, scriptIndex, classIndex, localRegs, scopeStack, abc, body, localRegNames, fullyQualifiedNames, localRegAssigmentIps), getExceptionEntries(body)); + public AVM2Graph(AbcIndexing abcIndex, AVM2Code code, ABC abc, MethodBody body, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, ScopeStack scopeStack, ScopeStack localScopeStack, HashMap localRegNames, List fullyQualifiedNames, HashMap localRegAssigmentIps) { + super(new AVM2GraphSource(code, isStatic, scriptIndex, classIndex, localRegs, abc, body, localRegNames, fullyQualifiedNames, localRegAssigmentIps), getExceptionEntries(body)); this.avm2code = code; this.abc = abc; this.body = body; @@ -248,7 +248,8 @@ private void getIgnoredSwitches(AVM2LocalData localData, Set allParts TranslateStack finallyTryTargetStack = (TranslateStack) new TranslateStack("try_target"); AVM2LocalData localData2 = new AVM2LocalData(localData); - localData2.scopeStack = new ScopeStack(); + //localData2.scopeStack = new ScopeStack(); + localData2.localScopeStack = new ScopeStack(); List targetOutput; try { @@ -626,7 +627,8 @@ public Map> calculateLocalRegsUsage(List throw } public static List translateViaGraph(SecondPassData secondPassData, List callStack, AbcIndexing abcIndex, String path, AVM2Code code, ABC abc, MethodBody body, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, ScopeStack scopeStack, HashMap localRegNames, HashMap localRegTypes, List fullyQualifiedNames, int staticOperation, HashMap localRegAssigmentIps, boolean thisHasDefaultToPrimitive) throws InterruptedException { - AVM2Graph g = new AVM2Graph(abcIndex, code, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localRegNames, fullyQualifiedNames, localRegAssigmentIps); + ScopeStack localScopeStack = new ScopeStack(); + AVM2Graph g = new AVM2Graph(abcIndex, code, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localScopeStack, localRegNames, fullyQualifiedNames, localRegAssigmentIps); AVM2LocalData localData = new AVM2LocalData(); localData.secondPassData = secondPassData; @@ -635,6 +637,7 @@ public static List translateViaGraph(SecondPassData secondPassD localData.classIndex = classIndex; localData.localRegs = localRegs; localData.scopeStack = scopeStack; + localData.localScopeStack = localScopeStack; localData.methodBody = body; localData.callStack = callStack; localData.abc = abc; @@ -1063,7 +1066,8 @@ private boolean checkTry(List currentRet, List foundG st2.clear(); st2.add(new ExceptionAVM2Item(finallyException)); AVM2LocalData localData2 = new AVM2LocalData(localData); - localData2.scopeStack = new ScopeStack(); + //localData2.scopeStack = new ScopeStack(); + localData2.localScopeStack = new ScopeStack(); try { //We are assuming Finally target has only 1 part @@ -1181,7 +1185,8 @@ private boolean checkTry(List currentRet, List foundG } } AVM2LocalData localData2 = new AVM2LocalData(localData); - localData2.scopeStack = new ScopeStack(); + //localData2.scopeStack = new ScopeStack(); + localData2.localScopeStack = new ScopeStack(); List stopPart2 = new ArrayList<>(stopPart); List stopPartKind2 = new ArrayList<>(stopPartKind); @@ -1202,7 +1207,7 @@ private boolean checkTry(List currentRet, List foundG WithAVM2Item w = (WithAVM2Item) currentCatchCommands.get(0); if (w.scope instanceof LocalRegAVM2Item) { int regId = ((LocalRegAVM2Item) w.scope).regIndex; - for (GraphTargetItem item : localData.scopeStack) { + for (GraphTargetItem item : localData.localScopeStack) { if (item instanceof WithObjectAVM2Item) { WithObjectAVM2Item wo = (WithObjectAVM2Item) item; @@ -2381,8 +2386,8 @@ public AVM2LocalData prepareBranchLocalData(BaseLocalData localData) { AVM2LocalData aLocalData = (AVM2LocalData) localData; AVM2LocalData ret = new AVM2LocalData(aLocalData); ScopeStack copyScopeStack = new ScopeStack(); - copyScopeStack.addAll(ret.scopeStack); - ret.scopeStack = copyScopeStack; + copyScopeStack.addAll(ret.localScopeStack); + ret.localScopeStack = copyScopeStack; return ret; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphSource.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphSource.java index e424afaf0a..ac252e6e05 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphSource.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphSource.java @@ -53,8 +53,6 @@ public class AVM2GraphSource extends GraphSource { HashMap localRegs; - ScopeStack scopeStack; - ABC abc; MethodBody body; @@ -69,12 +67,11 @@ public AVM2Code getCode() { return code; } - public AVM2GraphSource(AVM2Code code, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, ScopeStack scopeStack, ABC abc, MethodBody body, HashMap localRegNames, List fullyQualifiedNames, HashMap localRegAssigmentIp) { + public AVM2GraphSource(AVM2Code code, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, ABC abc, MethodBody body, HashMap localRegNames, List fullyQualifiedNames, HashMap localRegAssigmentIp) { this.code = code; this.isStatic = isStatic; this.classIndex = classIndex; this.localRegs = localRegs; - this.scopeStack = scopeStack; this.abc = abc; this.body = body; this.localRegNames = localRegNames; @@ -115,9 +112,8 @@ public boolean isEmpty() { @Override public List translatePart(Graph graph, GraphPart part, BaseLocalData localData, TranslateStack stack, int start, int end, int staticOperation, String path) throws InterruptedException { List ret = new ArrayList<>(); - ScopeStack newstack = ((AVM2LocalData) localData).scopeStack; Reference lineStartItem = new Reference<>(localData.lineStartInstruction); - ConvertOutput co = code.toSourceOutput(localData.allSwitchParts, ((AVM2LocalData) localData).callStack, ((AVM2LocalData) localData).abcIndex, ((AVM2LocalData) localData).setLocalPosToGetLocalPos, ((AVM2LocalData) localData).thisHasDefaultToPrimitive, lineStartItem, path, part, false, isStatic, scriptIndex, classIndex, localRegs, stack, newstack, abc, body, start, end, localRegNames, ((AVM2LocalData) localData).localRegTypes, fullyQualifiedNames, new boolean[size()], localRegAssigmentIps); + ConvertOutput co = code.toSourceOutput(localData.allSwitchParts, ((AVM2LocalData) localData).callStack, ((AVM2LocalData) localData).abcIndex, ((AVM2LocalData) localData).setLocalPosToGetLocalPos, ((AVM2LocalData) localData).thisHasDefaultToPrimitive, lineStartItem, path, part, false, isStatic, scriptIndex, classIndex, localRegs, stack, ((AVM2LocalData) localData).scopeStack, ((AVM2LocalData) localData).localScopeStack, abc, body, start, end, localRegNames, ((AVM2LocalData) localData).localRegTypes, fullyQualifiedNames, new boolean[size()], localRegAssigmentIps); localData.lineStartInstruction = lineStartItem.getVal(); ret.addAll(co.output); return ret; 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 b5cbaa7b9f..0522d8b923 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 @@ -193,7 +193,7 @@ protected void illegalOpCode(LocalDataArea lda, AVM2Instruction ins) throws AVM2 public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List output, String path) throws InterruptedException { } - public void translate(Set switchParts, List callStack, AbcIndexing abcIndex, Map> setLocalPosToGetLocalPos, Reference lineStartItem, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2Instruction ins, List output, MethodBody body, ABC abc, HashMap localRegNames, HashMap localRegTypes, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, AVM2Code code, boolean thisHasDefaultToPrimitive) throws InterruptedException { + public void translate(Set switchParts, List callStack, AbcIndexing abcIndex, Map> setLocalPosToGetLocalPos, Reference lineStartItem, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, ScopeStack localScopeStack, AVM2Instruction ins, List output, MethodBody body, ABC abc, HashMap localRegNames, HashMap localRegTypes, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, AVM2Code code, boolean thisHasDefaultToPrimitive) throws InterruptedException { AVM2LocalData localData = new AVM2LocalData(); localData.allSwitchParts = switchParts; localData.isStatic = isStatic; @@ -202,6 +202,7 @@ public void translate(Set switchParts, List callStack, Ab localData.lineStartInstruction = lineStartItem.getVal(); localData.localRegs = localRegs; localData.scopeStack = scopeStack; + localData.localScopeStack = localScopeStack; localData.methodBody = body; localData.callStack = callStack; localData.abc = abc; @@ -365,7 +366,7 @@ private static Multiname searchSlotName(int slotIndex, AVM2LocalData localData, if (obj instanceof FindPropertyAVM2Item) { FindPropertyAVM2Item findProp = (FindPropertyAVM2Item) obj; - for (GraphTargetItem item : localData.scopeStack) { + for (GraphTargetItem item : localData.localScopeStack) { Multiname ret = searchSlotName(slotIndex, localData, item, ((FullMultinameAVM2Item) findProp.propertyName).multinameIndex, realObj); if (ret != null) { return ret; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewFunctionIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewFunctionIns.java index 95feb43faa..d139e73f72 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewFunctionIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewFunctionIns.java @@ -40,7 +40,10 @@ public NewFunctionIns() { @Override public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List output, String path) { int methodIndex = ins.operands[0]; - NewFunctionAVM2Item function = new NewFunctionAVM2Item(ins, localData.lineStartInstruction, "", path, false, localData.scriptIndex, localData.classIndex, localData.abc, methodIndex, (ScopeStack) localData.scopeStack.clone()); + ScopeStack newScopeStack = new ScopeStack(); + newScopeStack.addAll(localData.scopeStack); + newScopeStack.addAll(localData.localScopeStack); + NewFunctionAVM2Item function = new NewFunctionAVM2Item(ins, localData.lineStartInstruction, "", path, false, localData.scriptIndex, localData.classIndex, localData.abc, methodIndex, newScopeStack); stack.push(function); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalTypeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalTypeIns.java index bd2a190e02..c5682b8454 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalTypeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalTypeIns.java @@ -28,6 +28,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.DecrementAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.GlobalAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item; @@ -71,8 +72,12 @@ public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruc int regId = getRegisterId(ins); if (regId == 0) { - if ((localData.classIndex >= localData.getInstanceInfo().size()) || localData.classIndex < 0) { - stack.push(new ThisAVM2Item(ins, localData.lineStartInstruction, DottedChain.OBJECT /*?*/, false)); + if (localData.classIndex == -1) { + stack.push(new ThisAVM2Item(ins, localData.lineStartInstruction, DottedChain.parseNoSuffix("global"), false, false)); + return; + } + if ((localData.classIndex >= localData.getInstanceInfo().size())) { + stack.push(new ThisAVM2Item(ins, localData.lineStartInstruction, DottedChain.OBJECT /*?*/, false, false)); return; } if (localData.isStatic) { @@ -81,7 +86,7 @@ public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruc List ts = localData.getInstanceInfo().get(localData.classIndex).instance_traits.traits; boolean isBasicObject = localData.thisHasDefaultToPrimitive; Multiname m = localData.getInstanceInfo().get(localData.classIndex).getName(localData.getConstants()); - stack.push(new ThisAVM2Item(ins, localData.lineStartInstruction, m.getNameWithNamespace(localData.getConstants(), true), isBasicObject)); + stack.push(new ThisAVM2Item(ins, localData.lineStartInstruction, m.getNameWithNamespace(localData.getConstants(), true), isBasicObject, false)); } return; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetOuterScopeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetOuterScopeIns.java index a26d9d3bd4..08aabae485 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetOuterScopeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetOuterScopeIns.java @@ -17,9 +17,16 @@ package com.jpexs.decompiler.flash.abc.avm2.instructions.other; import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.AVM2LocalData; import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.GlobalAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ThisAVM2Item; +import com.jpexs.decompiler.graph.DottedChain; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.List; /** * @@ -31,6 +38,19 @@ public GetOuterScopeIns() { super(0x67, "getouterscope", new int[]{AVM2Code.DAT_SCOPE_INDEX}, false); } + @Override + public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List output, String path) { + int index = ins.operands[0]; + GraphTargetItem item = localData.scopeStack.get(index); + if (item instanceof ThisAVM2Item) { + if (((ThisAVM2Item)item).className.equals(DottedChain.parseNoSuffix("global"))) { + stack.push(new GlobalAVM2Item(null, null)); + return; + } + } + stack.push(item); + } + @Override public int getStackPopCount(AVM2Instruction ins, ABC abc) { return 0; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetScopeObjectIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetScopeObjectIns.java index 6c8c21aca8..ff3f250e09 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetScopeObjectIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetScopeObjectIns.java @@ -38,7 +38,7 @@ public GetScopeObjectIns() { @Override public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List output, String path) { int index = ins.operands[0]; - stack.push(localData.scopeStack.get(index)); + stack.push(localData.localScopeStack.get(index)); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PopScopeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PopScopeIns.java index 1295f3545c..805f242161 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PopScopeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PopScopeIns.java @@ -46,7 +46,7 @@ public boolean execute(LocalDataArea lda, AVM2ConstantPool constants, AVM2Instru @Override public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List output, String path) { - GraphTargetItem scope = localData.scopeStack.pop(); + GraphTargetItem scope = localData.localScopeStack.pop(); if (scope instanceof WithObjectAVM2Item) { scope = ((WithObjectAVM2Item) scope).scope; output.add(new WithEndAVM2Item(ins, localData.lineStartInstruction, scope)); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushScopeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushScopeIns.java index 450b6fb5a1..8abb5962a9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushScopeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushScopeIns.java @@ -65,7 +65,7 @@ public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruc } } - localData.scopeStack.push(top); + localData.localScopeStack.push(top); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushWithIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushWithIns.java index ab4530bf72..b052476421 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushWithIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushWithIns.java @@ -40,7 +40,7 @@ public PushWithIns() { public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List output, String path) { GraphTargetItem w = stack.pop(); WithObjectAVM2Item wot = new WithObjectAVM2Item(ins, localData.lineStartInstruction, w); - localData.scopeStack.push(wot); + localData.localScopeStack.push(wot); output.add(new WithAVM2Item(ins, localData.lineStartInstruction, w)); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ClassAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ClassAVM2Item.java index 47689735ba..0e7173a237 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ClassAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ClassAVM2Item.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.abc.avm2.model; +import com.jpexs.decompiler.flash.IdentifiersDeobfuscation; import com.jpexs.decompiler.flash.abc.types.Multiname; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.graph.DottedChain; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TypeItem; import com.jpexs.decompiler.graph.model.LocalData; @@ -29,14 +31,27 @@ public class ClassAVM2Item extends AVM2Item { public Multiname className; + + public DottedChain classNameAsStr; public ClassAVM2Item(Multiname className) { super(null, null, PRECEDENCE_PRIMARY); this.className = className; } + + public ClassAVM2Item(DottedChain className) { + super(null, null, PRECEDENCE_PRIMARY); + this.classNameAsStr = className; + } @Override public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) { + if (classNameAsStr != null) { + if (localData.fullyQualifiedNames != null && localData.fullyQualifiedNames.contains(classNameAsStr)) { + return writer.append(classNameAsStr.toPrintableString(true)); + } + return writer.append(IdentifiersDeobfuscation.printIdentifier(true, classNameAsStr.getLast())); + } return writer.append(className.getName(localData.constantsAvm2, localData.fullyQualifiedNames, false, true)); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/NewFunctionAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/NewFunctionAVM2Item.java index 71621e882c..04e75bd3b6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/NewFunctionAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/NewFunctionAVM2Item.java @@ -92,7 +92,7 @@ public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) thr if (body != null) { List callStack = new ArrayList<>(localData.callStack); callStack.add(body); - body.convert(callStack, localData.abcIndex, new ConvertData(), path + "/inner", ScriptExportMode.AS, isStatic, methodIndex, scriptIndex, classIndex, abc, null, new ScopeStack(), 0, new NulWriter(), localData.fullyQualifiedNames, null, false, new HashSet<>(localData.seenMethods)); + body.convert(callStack, localData.abcIndex, new ConvertData(), path + "/inner", ScriptExportMode.AS, isStatic, methodIndex, scriptIndex, classIndex, abc, null, scopeStack, 0, new NulWriter(), localData.fullyQualifiedNames, null, false, new HashSet<>(localData.seenMethods)); body.toString(callStack, localData.abcIndex, path + "/inner", ScriptExportMode.AS, abc, null, writer, localData.fullyQualifiedNames, new HashSet<>(localData.seenMethods)); } writer.endBlock(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ThisAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ThisAVM2Item.java index 64836b9c14..eb7448ac21 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ThisAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ThisAVM2Item.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.flash.abc.avm2.model; +import com.jpexs.decompiler.flash.IdentifiersDeobfuscation; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions; @@ -41,12 +42,15 @@ public class ThisAVM2Item extends AVM2Item { public DottedChain className; public boolean basicObject; + + public boolean showClassName; - public ThisAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, DottedChain className, boolean basicObject) { + public ThisAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, DottedChain className, boolean basicObject, boolean showClassName) { super(instruction, lineStartIns, PRECEDENCE_PRIMARY); this.className = className; this.basicObject = basicObject; - getSrcData().localName = "this"; + this.showClassName = showClassName; + getSrcData().localName = "this"; } public boolean isBasicObject() { @@ -84,6 +88,14 @@ public String toString() { @Override public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) { + if (showClassName) { + if (className != null) { + if (localData.fullyQualifiedNames != null && localData.fullyQualifiedNames.contains(className)) { + return writer.append(className.toPrintableString(true)).append(".this"); + } + return writer.append(IdentifiersDeobfuscation.printIdentifier(true, className.getLast())).append(".this"); + } + } return writer.append("this"); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java index b5339ae73f..45db33cd70 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java @@ -38,6 +38,7 @@ import com.jpexs.decompiler.flash.search.MethodId; import com.jpexs.decompiler.flash.tags.ABCContainerTag; import com.jpexs.decompiler.graph.DottedChain; +import com.jpexs.decompiler.graph.ScopeStack; import com.jpexs.helpers.Helper; import java.io.Serializable; import java.util.AbstractMap.SimpleEntry; @@ -391,7 +392,7 @@ public GraphTextWriter toString(AbcIndexing abcIndex, Trait parent, ConvertData return writer; } - public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException { } public abstract GraphTextWriter convertTraitHeader(ABC abc, GraphTextWriter writer); @@ -486,11 +487,11 @@ public GraphTextWriter toStringPackaged(AbcIndexing abcIndex, Trait parent, Conv return writer; } - public void convertPackaged(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + public void convertPackaged(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException { Namespace ns = abc.constants.getMultiname(name_index).getNamespace(abc.constants); if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) { String nsname = ns.getName(abc.constants).toPrintableString(true); - convert(abcIndex, parent, convertData, path + nsname, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); + convert(abcIndex, parent, convertData, path + nsname, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel, scopeStack); } } @@ -500,7 +501,7 @@ public GraphTextWriter toStringHeader(Trait parent, ConvertData convertData, Str } public void convertHeader(Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { - convert(null, parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); + convert(null, parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel, new ScopeStack()); } public final Multiname getName(ABC abc) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java index 3d531a7db0..9b1a6e4007 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java @@ -18,9 +18,11 @@ import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.avm2.model.CallPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ClassAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.GetLexAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.GlobalAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.ThisAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.parser.script.AbcIndexing; @@ -214,7 +216,7 @@ public GraphTextWriter toString(AbcIndexing abcIndex, Trait parent, ConvertData } @Override - public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException { fullyQualifiedNames = new ArrayList<>(); @@ -234,8 +236,8 @@ public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, } } else { convertData.thisHasDefaultToPrimitive = true; - } - + } + ScopeStack newScopeStack = (ScopeStack)scopeStack.clone(); //class initializer int bodyIndex = abc.findBodyIndex(classInfo.cinit_index); if (bodyIndex != -1) { @@ -243,11 +245,27 @@ public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, List ts = new ArrayList<>(); ts.add(classInfo.static_traits); List callStack = new ArrayList<>(); - callStack.add(abc.bodies.get(bodyIndex)); - abc.bodies.get(bodyIndex).convert(callStack, abcIndex, convertData, path +/*packageName +*/ "/" + instanceInfoName + ".staticinitializer", exportMode, true, classInfo.cinit_index, scriptIndex, class_info, abc, this, new ScopeStack(), GraphTextWriter.TRAIT_CLASS_INITIALIZER, writer, fullyQualifiedNames, ts, true, new HashSet<>()); + callStack.add(abc.bodies.get(bodyIndex)); + + if (!abc.instance_info.get(class_info).isInterface()) { + AbcIndexing.ClassIndex cls = abcIndex.findClass(AbcIndexing.multinameToType(abc.instance_info.get(class_info).name_index, abc.constants), abc, scriptIndex); + List clsList = new ArrayList<>(); + cls = cls.parent; + while(cls != null) { + clsList.add(0, cls); + cls = cls.parent; + } + for (AbcIndexing.ClassIndex cls2: clsList) { + newScopeStack.push(new ClassAVM2Item(cls2.abc.instance_info.get(cls2.index).getName(cls2.abc.constants).getNameWithNamespace(cls2.abc.constants, true))); + } + } + + abc.bodies.get(bodyIndex).convert(callStack, abcIndex, convertData, path +/*packageName +*/ "/" + instanceInfoName + ".staticinitializer", exportMode, true, classInfo.cinit_index, scriptIndex, class_info, abc, this, newScopeStack, GraphTextWriter.TRAIT_CLASS_INITIALIZER, writer, fullyQualifiedNames, ts, true, new HashSet<>()); + + newScopeStack.push(new ClassAVM2Item(abc.instance_info.get(class_info).getName(abc.constants))); classInitializerIsEmpty = !writer.getMark(); - } - + } + //constructor - instance initializer if (!instanceInfo.isInterface()) { bodyIndex = abc.findBodyIndex(instanceInfo.iinit_index); @@ -312,9 +330,9 @@ public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, } //static variables,constants & methods - classInfo.static_traits.convert(abcIndex, this, convertData, path +/*packageName +*/ "/" + instanceInfoName, abc, true, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel); + classInfo.static_traits.convert(abcIndex, this, convertData, path +/*packageName +*/ "/" + instanceInfoName, abc, true, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel, newScopeStack); - instanceInfo.instance_traits.convert(abcIndex, this, convertData, path +/*packageName +*/ "/" + instanceInfoName, abc, false, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel); + instanceInfo.instance_traits.convert(abcIndex, this, convertData, path +/*packageName +*/ "/" + instanceInfoName, abc, false, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel, newScopeStack); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitFunction.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitFunction.java index 66f880fc21..9b694b19ba 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitFunction.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitFunction.java @@ -103,7 +103,7 @@ public GraphTextWriter toString(AbcIndexing abcIndex, Trait parent, ConvertData } @Override - public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException { fullyQualifiedNames = new ArrayList<>(); writeImports(abcIndex, scriptIndex, classIndex, false, abc, writer, getPackage(abc), fullyQualifiedNames); writer.startMethod(method_info); @@ -112,7 +112,7 @@ public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, if (bodyIndex != -1) { List callStack = new ArrayList<>(); callStack.add(abc.bodies.get(bodyIndex)); - abc.bodies.get(bodyIndex).convert(callStack, abcIndex, convertData, path + "." + abc.constants.getMultiname(name_index).getName(abc.constants, fullyQualifiedNames, false, true), exportMode, isStatic, method_info, scriptIndex, classIndex, abc, this, new ScopeStack(), 0, writer, fullyQualifiedNames, null, true, new HashSet<>()); + abc.bodies.get(bodyIndex).convert(callStack, abcIndex, convertData, path + "." + abc.constants.getMultiname(name_index).getName(abc.constants, fullyQualifiedNames, false, true), exportMode, isStatic, method_info, scriptIndex, classIndex, abc, this, scopeStack, 0, writer, fullyQualifiedNames, null, true, new HashSet<>()); } writer.endMethod(); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitMethodGetterSetter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitMethodGetterSetter.java index 0bf7646b2d..4e9ce2a843 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitMethodGetterSetter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitMethodGetterSetter.java @@ -108,7 +108,7 @@ public GraphTextWriter toStringHeader(Trait parent, ConvertData convertData, Str } @Override - public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException { if (classIndex < 0) { writeImports(abcIndex, scriptIndex, classIndex, isStatic, abc, writer, getPackage(abc), fullyQualifiedNames); } @@ -121,7 +121,7 @@ public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, if (bodyIndex != -1) { List callStack = new ArrayList<>(); callStack.add(abc.bodies.get(bodyIndex)); - abc.bodies.get(bodyIndex).convert(callStack, abcIndex, convertData, path, exportMode, isStatic, method_info, scriptIndex, classIndex, abc, this, new ScopeStack(), 0, writer, fullyQualifiedNames, null, true, new HashSet<>()); + abc.bodies.get(bodyIndex).convert(callStack, abcIndex, convertData, path, exportMode, isStatic, method_info, scriptIndex, classIndex, abc, this, scopeStack, 0, writer, fullyQualifiedNames, null, true, new HashSet<>()); } } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java index cf913f8557..2df3581b4e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java @@ -37,6 +37,7 @@ import com.jpexs.decompiler.flash.search.MethodId; import com.jpexs.decompiler.graph.DottedChain; import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; import com.jpexs.decompiler.graph.model.LocalData; import com.jpexs.helpers.Helper; import java.util.ArrayList; @@ -193,7 +194,7 @@ public GraphTextWriter toString(AbcIndexing abcIndex, Trait parent, ConvertData } @Override - public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException { getNameStr(writer, abc, fullyQualifiedNames); if (hasValueStr(abc, convertData)) { getValueStr(abcIndex,exportMode, parent, convertData, writer, abc, fullyQualifiedNames); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Traits.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Traits.java index e7fae60edc..dd78b00368 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Traits.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Traits.java @@ -32,6 +32,7 @@ import com.jpexs.decompiler.flash.search.MethodId; import com.jpexs.decompiler.graph.DottedChain; import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -133,8 +134,10 @@ private class TraitConvertTask implements Callable { ConvertData convertData; AbcIndexing abcIndex; + + ScopeStack scopeStack; - public TraitConvertTask(AbcIndexing abcIndex, Trait trait, Trait parent, ConvertData convertData, boolean makePackages, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, int traitIndex, boolean parallel) { + public TraitConvertTask(AbcIndexing abcIndex, Trait trait, Trait parent, ConvertData convertData, boolean makePackages, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, int traitIndex, boolean parallel, ScopeStack scopeStack) { this.trait = trait; this.parent = parent; this.convertData = convertData; @@ -150,14 +153,15 @@ public TraitConvertTask(AbcIndexing abcIndex, Trait trait, Trait parent, Convert this.traitIndex = traitIndex; this.parallel = parallel; this.abcIndex = abcIndex; + this.scopeStack = scopeStack; } @Override public Void call() throws InterruptedException { if (makePackages) { - trait.convertPackaged(abcIndex, parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); + trait.convertPackaged(abcIndex, parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel, scopeStack); } else { - trait.convert(abcIndex, parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); + trait.convert(abcIndex, parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel, scopeStack); } return null; } @@ -248,10 +252,10 @@ public GraphTextWriter toString(AbcIndexing abcIndex, Class[] traitTypes, Trait return writer; } - public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, boolean makePackages, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, boolean makePackages, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException { if (!parallel || traits.size() < 2) { for (int t = 0; t < traits.size(); t++) { - TraitConvertTask task = new TraitConvertTask(abcIndex, traits.get(t), parent, convertData, makePackages, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, t, parallel); + TraitConvertTask task = new TraitConvertTask(abcIndex, traits.get(t), parent, convertData, makePackages, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, t, parallel, scopeStack); task.call(); } } else { @@ -261,7 +265,7 @@ public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, futureResults = new ArrayList<>(); for (int t = 0; t < traits.size(); t++) { // each convert task needs a separate NulWriter, because they are executed parallel - TraitConvertTask task = new TraitConvertTask(abcIndex, traits.get(t), parent, convertData, makePackages, path, abc, isStatic, exportMode, scriptIndex, classIndex, new NulWriter(), fullyQualifiedNames, t, parallel); + TraitConvertTask task = new TraitConvertTask(abcIndex, traits.get(t), parent, convertData, makePackages, path, abc, isStatic, exportMode, scriptIndex, classIndex, new NulWriter(), fullyQualifiedNames, t, parallel, scopeStack); Future future = executor.submit(task); futureResults.add(future); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/DependencyParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/DependencyParser.java index f917446c04..98a56be2b0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/DependencyParser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/DependencyParser.java @@ -26,12 +26,14 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetLexIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetOuterScopeIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetPropertyIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetSuperIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetPropertyIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetSuperIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.types.AsTypeIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceIns; +import com.jpexs.decompiler.flash.abc.avm2.model.ClassAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.InitVectorAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.parser.script.AbcIndexing; import com.jpexs.decompiler.flash.abc.types.ABCException; @@ -42,6 +44,8 @@ import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.graph.DottedChain; +import com.jpexs.decompiler.graph.TypeItem; +import java.util.ArrayList; import java.util.List; public class DependencyParser { @@ -153,6 +157,30 @@ public static void parseDependenciesFromMethodInfo(AbcIndexing abcIndex, Trait t } } } + if (classIndex > -1 && ins.definition instanceof GetOuterScopeIns) { + if (ins.operands[0] > 0) { //first is global + DottedChain type = abc.instance_info.get(classIndex).getName(abc.constants).getNameWithNamespace(abc.constants, true); + AbcIndexing.ClassIndex cls = abcIndex.findClass(new TypeItem(type), abc, scriptIndex); + List clsList = new ArrayList<>(); + cls = cls.parent; + while(cls != null) { + clsList.add(0, cls); + cls = cls.parent; + } + if (ins.operands[0] < 1 + clsList.size()) { + AbcIndexing.ClassIndex cls2 = clsList.get(ins.operands[0] - 1); + DottedChain nimport = cls2.abc.instance_info.get(cls2.index).getName(cls2.abc.constants).getNameWithNamespace(cls2.abc.constants, true); + Dependency depExp = new Dependency(nimport, DependencyType.EXPRESSION); + if (!dependencies.contains(depExp)) { + dependencies.add(depExp); + } + } + } + + /*for (AbcIndexing.ClassIndex cls2: clsList) { + newScopeStack.push(new ClassAVM2Item(cls2.abc.instance_info.get(cls2.index).getName(cls2.abc.constants).getNameWithNamespace(cls2.abc.constants, true))); + } */ + } for (int k = 0; k < ins.definition.operands.length; k++) { if (ins.definition.operands[k] == AVM2Code.DAT_MULTINAME_INDEX) { int m = ins.operands[k]; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/PcodeGraphVizExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/PcodeGraphVizExporter.java index d642c2caca..7c244632cd 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/PcodeGraphVizExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/PcodeGraphVizExporter.java @@ -86,7 +86,7 @@ public void exportAs12(ASMSource src, GraphTextWriter writer) throws Interrupted } public void exportAs3(AbcIndexing abcIndex, ABC abc, MethodBody body, GraphTextWriter writer) throws InterruptedException { - AVM2Graph gr = new AVM2Graph(abcIndex, body.getCode(), abc, body, false, -1, -1, new HashMap<>(), new ScopeStack(), new HashMap<>(), new ArrayList<>(), new HashMap<>()); // body.getCode().visitCode(body)); + AVM2Graph gr = new AVM2Graph(abcIndex, body.getCode(), abc, body, false, -1, -1, new HashMap<>(), new ScopeStack(), new ScopeStack(), new HashMap<>(), new ArrayList<>(), new HashMap<>()); // body.getCode().visitCode(body)); export(gr, writer); } diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassTest.java index 8d10ec26a7..1d1dda64ba 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassTest.java @@ -44,6 +44,7 @@ public class ActionScript3ClassTest extends ActionScript3DecompileTestBase { public void init() throws IOException, InterruptedException { addSwf("standard", "testdata/as3_new/bin/as3_new.flex.swf"); addSwf("assembled", "testdata/as3_assembled/bin/as3_assembled.swf"); + addSwf("getouterscope", "testdata/getouterscope/getouterscope.swf"); } private void decompileScriptPack(String swfId, String path, String expectedResult) { @@ -491,4 +492,42 @@ public void testModifiers() { + " }\n" + "}"); } + + @Test + public void testGetOuterScope() { + decompileScriptPack("getouterscope", "mypkg.MainClass", "package mypkg\n" + + "{\n" + + " import flash.display.DisplayObject;\n" + + " import flash.display.DisplayObjectContainer;\n" + + " import flash.display.InteractiveObject;\n" + + " import flash.display.MovieClip;\n" + + " import flash.display.Sprite;\n" + + " import flash.events.EventDispatcher;\n" + + " import flash.text.TextField;\n" + + " \n" + + " public class MainClass extends MovieClip\n" + + " {\n" + + " \n" + + " \n" + + " private var myTextBox:TextField;\n" + + " \n" + + " public function MainClass()\n" + + " {\n" + + " super();\n" + + " this.myTextBox = new TextField();\n" + + " this.myTextBox.text = \"\";\n" + + " this.myTextBox.width = 1024;\n" + + " this.myTextBox.height = 1024;\n" + + " this.myTextBox.multiline = true;\n" + + " addChild(this.myTextBox);\n" + + " this.test();\n" + + " }\n" + + " \n" + + " internal function test() : void\n" + + " {\n" + + " this.myTextBox.text = \"scopes:\\n\" + global + \"\\n\" + Object + \"\\n\" + EventDispatcher + \"\\n\" + DisplayObject + \"\\n\" + InteractiveObject + \"\\n\" + DisplayObjectContainer + \"\\n\" + Sprite + \"\\n\" + MovieClip + \"\\n\" + MainClass + \"\\n\";\n" + + " }\n" + + " }\n" + + "}"); + } } diff --git a/libsrc/ffdec_lib/testdata/getouterscope/getouterscope.swf b/libsrc/ffdec_lib/testdata/getouterscope/getouterscope.swf new file mode 100644 index 0000000000000000000000000000000000000000..eda924edf440f1c560573fe64f9c2389396a02b8 GIT binary patch literal 1029 zcmV+g1p50!S5ptk2LJ$goTXG-bJ|82T_MB*wqrYXh zJGLMCk|}Fxfo*gfX)*BB{uKX{{007zyAl^Wv71TT9r1nIPv;zV&t5`M1OVIua3BC{ z_kh3uxwj($a1uEK{lea_vVL5_PH;^scHk*f94cxBDTxjT z>1ISQ3!0u7`oKPiJ&qq$D_c0 zH^DcgJV>lQQSO2Nbx3?>z22u6-1C$bI%XGS@M&~>H4BMyLE>N>*@VMiEjLWBr=R&T z!@f<PpQD>~Z4TQqB1n zY7eL@weyG$Dc`bBsG7C5(XBNNwOdm=rm8kNX5DHV4P+SIw$Vf@)h8s@Vp9K|GY>hy4BRbo@>uTCG^WYmweu4PnBt8G0!u}9REn)7%<^=93wb~tuDT|6uFf*VRqmxkLZ zPG92+-t3A@Sv!~(7YxRGg{0J_#C5Wa#4MZCqzQG{C^sT>IAR5F>@w<7pX9OQm?M4x zNRQFs-huOSCWgEQ9mEsK}ce~C=`n&p(K{111Nz~;iXvG%YOl$ zLm>k*St#b9l!v(@gd0%Ugu)gSoAS!3IKRvVp1;S% zw;Md4ZwT}A9N_fKKBvFobk6y52yS10bvqQ&m`S6U#%vm;H0II>)0j^phFnL?@FD#$ zM+EdYQGW~dpP~LX>hGZbF6xW?`3-!tXrl~=|G2lmoN2mQD(lSx-tgMrt-eZITAlWO literal 0 HcmV?d00001 diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java b/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java index 352a41873a..9f0042fd55 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java @@ -265,7 +265,7 @@ public void setMethod(String scriptPathName, int methodIndex, int bodyIndex, ABC public void graph() { try { - AVM2Graph gr = new AVM2Graph(null /*?*/, abc.bodies.get(bodyIndex).getCode(), abc, abc.bodies.get(bodyIndex), false, -1, -1, new HashMap<>(), new ScopeStack(), new HashMap<>(), new ArrayList<>(), new HashMap<>()); //, abc.bodies.get(bodyIndex).getCode().visitCode(abc.bodies.get(bodyIndex))); + AVM2Graph gr = new AVM2Graph(null /*?*/, abc.bodies.get(bodyIndex).getCode(), abc, abc.bodies.get(bodyIndex), false, -1, -1, new HashMap<>(), new ScopeStack(), new ScopeStack(), new HashMap<>(), new ArrayList<>(), new HashMap<>()); //, abc.bodies.get(bodyIndex).getCode().visitCode(abc.bodies.get(bodyIndex))); (new GraphDialog(getAbcPanel().getMainPanel().getMainFrame().getWindow(), gr, name)).setVisible(true); } catch (InterruptedException ex) { Logger.getLogger(ASMSourceEditorPane.class.getName()).log(Level.SEVERE, null, ex);