diff --git a/trunk/src/com/jpexs/decompiler/flash/SWF.java b/trunk/src/com/jpexs/decompiler/flash/SWF.java index a94e5622b..7e699f4f9 100644 --- a/trunk/src/com/jpexs/decompiler/flash/SWF.java +++ b/trunk/src/com/jpexs/decompiler/flash/SWF.java @@ -18,6 +18,8 @@ package com.jpexs.decompiler.flash; import SevenZip.Compression.LZMA.Encoder; import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.gui.TreeLeafScript; +import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.ActionGraphSource; import com.jpexs.decompiler.flash.action.swf4.ActionEquals; @@ -413,20 +415,16 @@ public class SWF { } for (int i = 0; i < abcTags.size(); i++) { ABC abc = abcTags.get(i).getABC(); - int scriptIndex = abc.findScriptByPath(className); - if (scriptIndex > -1) { + TreeLeafScript scr = abc.findScriptTraitByPath(className); + if (scr != null) { String cnt = ""; if (abc.script_info.length > 1) { cnt = "script " + (i + 1) + "/" + abc.script_info.length + " "; } - String path = abc.script_info[scriptIndex].getPath(abc); - String packageName = path.substring(0, path.lastIndexOf(".")); - if (packageName.equals("")) { - path = path.substring(1); - } - String exStr = "Exporting " + "tag " + (i + 1) + "/" + abcTags.size() + " " + cnt + path + " ..."; + Trait t = abc.script_info[scr.scriptIndex].traits.traits[scr.traitIndex]; + String exStr = "Exporting " + "tag " + (i + 1) + "/" + abcTags.size() + " " + cnt + t.getPath(abc) + " ..."; informListeners("export", exStr); - abc.script_info[scriptIndex].export(abc, abcTags, outdir, isPcode, scriptIndex); + t.export(outdir, abc, abcTags, isPcode, scr.scriptIndex, -1,false); return true; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/ABC.java b/trunk/src/com/jpexs/decompiler/flash/abc/ABC.java index f17f9a6b4..89a38a561 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/ABC.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/ABC.java @@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; import com.jpexs.decompiler.flash.abc.avm2.ConstantPool; import com.jpexs.decompiler.flash.abc.avm2.UnknownInstructionCode; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.gui.TreeLeafScript; import com.jpexs.decompiler.flash.abc.types.*; import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter; @@ -565,18 +566,16 @@ public class ABC { public void export(String directory, boolean pcode, List abcList, String abcStr) throws IOException { for (int i = 0; i < script_info.length; i++) { - String path = script_info[i].getPath(this); - String packageName = path.substring(0, path.lastIndexOf(".")); - if (packageName.equals("")) { - path = path.substring(1); - } + String cnt = ""; if (script_info.length > 1) { cnt = "script " + (i + 1) + "/" + script_info.length + " "; } - String exStr = "Exporting " + abcStr + cnt + path + " ..."; - informListeners("export", exStr); - script_info[i].export(this, abcList, directory, pcode, i); + for (Trait t : script_info[i].traits.traits) { + String exStr = "Exporting " + abcStr + cnt + t.getPath(this) + " ..."; + informListeners("export", exStr); + t.export(directory, this, abcList, pcode, i, -1, false); + } } } @@ -889,13 +888,15 @@ public class ABC { return -1; } - public int findScriptByPath(String name) { + public TreeLeafScript findScriptTraitByPath(String name) { for (int c = 0; c < script_info.length; c++) { - String s = script_info[c].getPath(this); - if (name.equals(s)) { - return c; + for (int t = 0; t < script_info[c].traits.traits.length; t++) { + Trait tr = script_info[c].traits.traits[t]; + if (tr.getPath(this).equals(name)) { + return new TreeLeafScript(this, c, t); + } } } - return -1; + return null; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/gui/ClassesListTree.java b/trunk/src/com/jpexs/decompiler/flash/abc/gui/ClassesListTree.java index 218509892..b9759e922 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/gui/ClassesListTree.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/gui/ClassesListTree.java @@ -17,6 +17,10 @@ package com.jpexs.decompiler.flash.abc.gui; import com.jpexs.decompiler.flash.Main; +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.types.Multiname; +import com.jpexs.decompiler.flash.abc.types.Namespace; +import com.jpexs.decompiler.flash.abc.types.ScriptInfo; import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; import com.jpexs.decompiler.flash.gui.View; @@ -95,9 +99,20 @@ public class ClassesListTree extends JTree implements TreeSelectionListener { public HashMap getTreeList(List list) { HashMap ret = new HashMap(); for (ABCContainerTag tag : list) { - for (int i = 0; i < tag.getABC().script_info.length; i++) { - String path = tag.getABC().script_info[i].getPath(tag.getABC()); - ret.put(path, new TreeLeafScript(tag.getABC(), i)); + ABC abc = tag.getABC(); + for (int i = 0; i < abc.script_info.length; i++) { + ScriptInfo script = abc.script_info[i]; + for (int j = 0; j < script.traits.traits.length; j++) { + Trait t = script.traits.traits[j]; + Multiname name = t.getName(abc); + Namespace ns = name.getNamespace(abc.constants); + String packageName = ns.getName(abc.constants); + String objectName = name.getName(abc.constants, new ArrayList()); + String path = packageName + "." + objectName; + ret.put(path, new TreeLeafScript(abc, i, j)); + } + + } } return ret; @@ -141,7 +156,7 @@ public class ClassesListTree extends JTree implements TreeSelectionListener { abcPanel.navigator.setABC(abcList, scriptLeaf.abc); abcPanel.navigator.setClassIndex(classIndex, scriptLeaf.scriptIndex); abcPanel.setAbc(scriptLeaf.abc); - abcPanel.decompiledTextArea.setScript(scriptLeaf.scriptIndex, scriptLeaf.abc, abcList); + abcPanel.decompiledTextArea.setScript(scriptLeaf, abcList); abcPanel.decompiledTextArea.setClassIndex(classIndex); abcPanel.decompiledTextArea.setNoTrait(); abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setCode(""); diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/gui/DecompiledEditorPane.java b/trunk/src/com/jpexs/decompiler/flash/abc/gui/DecompiledEditorPane.java index 230ae8bb2..2daed5b42 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/gui/DecompiledEditorPane.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/gui/DecompiledEditorPane.java @@ -38,7 +38,7 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL private List classHighlights = new ArrayList(); private Highlighting currentMethodHighlight; private ABC abc; - private int scriptIndex = -1; + private TreeLeafScript script; public int lastTraitIndex = 0; private boolean ignoreCarret = false; private boolean reset = false; @@ -46,8 +46,8 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL private int classIndex = -1; private boolean isStatic = false; - public int getScriptIndex() { - return scriptIndex; + public TreeLeafScript getScriptLeaf() { + return script; } public boolean getIsStatic() { @@ -138,7 +138,7 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL for (Highlighting cm : classHighlights) { if ((pos >= cm.startPos) && (pos < cm.startPos + cm.len)) { classIndex = (int) cm.offset; - displayClass(classIndex, scriptIndex); + displayClass(classIndex, script.scriptIndex); break; } } @@ -155,7 +155,7 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL for (Highlighting th : traitHighlights) { if ((pos >= th.startPos) && (pos < th.startPos + th.len)) { lastTraitIndex = (int) th.offset; - if (abc != null) { + if ((abc != null) && (classIndex != -1)) { t = abc.findTraitByTraitId(classIndex, lastTraitIndex); isStatic = abc.isStaticTraitId(classIndex, lastTraitIndex); if (t != null) { @@ -227,7 +227,7 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL this.classHighlights = classHighlights; } } - private HashMap bufferedClasses = new HashMap(); + private HashMap bufferedClasses = new HashMap(); public void gotoLastTrait() { gotoTrait(lastTraitIndex); @@ -285,8 +285,11 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL bufferedClasses.clear(); } - public void setScript(int scriptIndex, ABC abc, List abcList) { + public void setScript(TreeLeafScript scriptLeaf, List abcList) { + int scriptIndex = scriptLeaf.scriptIndex; + int scriptTraitIndex = scriptLeaf.traitIndex; ScriptInfo script = null; + ABC abc = scriptLeaf.abc; if (scriptIndex > -1) { script = abc.script_info[scriptIndex]; } @@ -294,22 +297,22 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL highlights = new ArrayList(); traitHighlights = new ArrayList(); methodHighlights = new ArrayList(); - this.scriptIndex = scriptIndex; + this.script = scriptLeaf; return; } setText("//Please wait..."); String hilightedCode; - if (!bufferedClasses.containsKey(script)) { - hilightedCode = script.convert(abcList, abc, false, true, scriptIndex); + if (!bufferedClasses.containsKey(scriptLeaf)) { + hilightedCode = script.traits.traits[scriptTraitIndex].convertPackaged("", abcList, abc, false, false, scriptIndex, -1, true, new ArrayList()); highlights = Highlighting.getInstrHighlights(hilightedCode); traitHighlights = Highlighting.getTraitHighlights(hilightedCode); methodHighlights = Highlighting.getMethodHighlights(hilightedCode); classHighlights = Highlighting.getClassHighlights(hilightedCode); hilightedCode = Highlighting.stripHilights(hilightedCode); - bufferedClasses.put(scriptIndex, new BufferedClass(hilightedCode, highlights, traitHighlights, methodHighlights, classHighlights)); + bufferedClasses.put(scriptLeaf, new BufferedClass(hilightedCode, highlights, traitHighlights, methodHighlights, classHighlights)); } else { - BufferedClass bc = bufferedClasses.get(script); + BufferedClass bc = bufferedClasses.get(scriptLeaf); hilightedCode = bc.text; highlights = bc.highlights; traitHighlights = bc.traitHighlights; @@ -318,17 +321,17 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL } this.abc = abc; this.abcList = abcList; - this.scriptIndex = scriptIndex; + this.script = scriptLeaf; setText(hilightedCode); } public void reloadClass() { int ci = classIndex; - if (bufferedClasses.containsKey(scriptIndex)) { - bufferedClasses.remove(scriptIndex); + if (bufferedClasses.containsKey(script)) { + bufferedClasses.remove(script); } - if ((scriptIndex != -1) && (abc != null)) { - setScript(scriptIndex, abc, abcList); + if ((script != null) && (abc != null)) { + setScript(script, abcList); } setNoTrait(); setClassIndex(ci); diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/gui/TreeLeafScript.java b/trunk/src/com/jpexs/decompiler/flash/abc/gui/TreeLeafScript.java index e50e98d8a..4b62d0fb2 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/gui/TreeLeafScript.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/gui/TreeLeafScript.java @@ -26,9 +26,11 @@ public class TreeLeafScript { public ABC abc; public int scriptIndex; + public int traitIndex = 0; - public TreeLeafScript(ABC abc, int scriptIndex) { + public TreeLeafScript(ABC abc, int scriptIndex, int traitIndex) { this.abc = abc; this.scriptIndex = scriptIndex; + this.traitIndex = traitIndex; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/types/ScriptInfo.java b/trunk/src/com/jpexs/decompiler/flash/abc/types/ScriptInfo.java index cb9196b1a..297379c6c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/types/ScriptInfo.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/types/ScriptInfo.java @@ -18,11 +18,8 @@ package com.jpexs.decompiler.flash.abc.types; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.types.traits.Trait; -import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; import com.jpexs.decompiler.flash.abc.types.traits.Traits; import com.jpexs.decompiler.flash.tags.ABCContainerTag; -import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -45,43 +42,15 @@ public class ScriptInfo { return "method_index=" + init_index + "\r\n" + traits.toString(abc, fullyQualifiedNames); } - public String getPath(ABC abc) { - String packageName = ""; - String scriptName = ""; - int classCount = 0; - for (Trait t : traits.traits) { - Multiname name = t.getName(abc); - Namespace ns = name.getNamespace(abc.constants); - if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) { - packageName = ns.getName(abc.constants); - scriptName = name.getName(abc.constants, new ArrayList()); - if (t instanceof TraitClass) { - classCount++; - } - } - } - if (classCount > 1) { - scriptName = "[script]"; - } - return packageName + "." + scriptName; - } - public String convert(List abcTags, ABC abc, boolean pcode, boolean highlighting, int scriptIndex) { return traits.convert("", abcTags, abc, false, pcode, true, scriptIndex, -1, highlighting, new ArrayList()); } public void export(ABC abc, List abcList, String directory, boolean pcode, int scriptIndex) throws IOException { - String path = getPath(abc); - String packageName = path.substring(0, path.lastIndexOf(".")); - String className = path.substring(path.lastIndexOf(".") + 1); - File outDir = new File(directory + File.separatorChar + packageName.replace('.', File.separatorChar)); - if (!outDir.exists()) { - outDir.mkdirs(); + for (Trait t : traits.traits) { + t.export(directory, abc, abcList, pcode, scriptIndex, -1, false); } - String fileName = outDir.toString() + File.separator + className + ".as"; - FileOutputStream fos = new FileOutputStream(fileName); - fos.write(convert(abcList, abc, pcode, false, scriptIndex).getBytes()); - fos.close(); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java b/trunk/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java index 22aa6db68..05fcd429a 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java @@ -21,7 +21,11 @@ import com.jpexs.decompiler.flash.abc.types.Multiname; import com.jpexs.decompiler.flash.abc.types.Namespace; import com.jpexs.decompiler.flash.helpers.Helper; import com.jpexs.decompiler.flash.tags.ABCContainerTag; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; import java.io.Serializable; +import java.util.ArrayList; import java.util.List; public abstract class Trait implements Serializable { @@ -140,4 +144,27 @@ public abstract class Trait implements Serializable { } public abstract int removeTraps(int scriptIndex, int classIndex, boolean isStatic, ABC abc); + + public String getPath(ABC abc) { + Multiname name = getName(abc); + Namespace ns = name.getNamespace(abc.constants); + String packageName = ns.getName(abc.constants); + String objectName = name.getName(abc.constants, new ArrayList()); + return packageName + "." + objectName; + } + + public void export(String directory, ABC abc, List abcList, boolean pcode, int scriptIndex, int classIndex, boolean isStatic) throws IOException { + Multiname name = getName(abc); + Namespace ns = name.getNamespace(abc.constants); + String packageName = ns.getName(abc.constants); + String objectName = name.getName(abc.constants, new ArrayList()); + File outDir = new File(directory + File.separatorChar + packageName.replace('.', File.separatorChar)); + if (!outDir.exists()) { + outDir.mkdirs(); + } + String fileName = outDir.toString() + File.separator + objectName + ".as"; + FileOutputStream fos = new FileOutputStream(fileName); + fos.write(convertPackaged("", abcList, abc, isStatic, pcode, scriptIndex, classIndex, false, new ArrayList()).getBytes()); + fos.close(); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java b/trunk/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java index e24b132d8..4d83de491 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java @@ -326,16 +326,19 @@ public class TraitClass extends Trait implements TraitWithSlot { List namesInThisPackage = new ArrayList(); for (ABCContainerTag tag : abcTags) { for (ScriptInfo si : tag.getABC().script_info) { - String spath = si.getPath(tag.getABC()); - String pkg = ""; - String name = spath; - if (spath.contains(".")) { - pkg = spath.substring(0, spath.lastIndexOf(".")); - name = spath.substring(spath.lastIndexOf(".") + 1); - } - if (pkg.equals(packageName)) { - namesInThisPackage.add(name); + for (Trait t : si.traits.traits) { + String spath = t.getPath(tag.getABC()); + String pkg = ""; + String name = spath; + if (spath.contains(".")) { + pkg = spath.substring(0, spath.lastIndexOf(".")); + name = spath.substring(spath.lastIndexOf(".") + 1); + } + if (pkg.equals(packageName)) { + namesInThisPackage.add(name); + } } + } } //imports diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java index cc2c788d1..78753a67a 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java @@ -1357,8 +1357,12 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi if (abcPanel != null) { for (int i = 0; i < tlsList.size(); i++) { TreeLeafScript tls = tlsList.get(i); - Main.startWork("Exporting " + (i + 1) + "/" + tlsList.size() + " " + tls.abc.script_info[tls.scriptIndex].getPath(tls.abc) + " ..."); - tls.abc.script_info[tls.scriptIndex].export(tls.abc, abcPanel.list, selFile, isPcode, tls.scriptIndex); + + + for (Trait t : tls.abc.script_info[tls.scriptIndex].traits.traits) { + Main.startWork("Exporting " + (i + 1) + "/" + tlsList.size() + " " + t.getPath(tls.abc) + " ..."); + t.export(selFile, tls.abc, abcList, isPcode, tls.scriptIndex, -1, false); + } } } else { List allNodes = new ArrayList(); @@ -1483,7 +1487,7 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi } else { int bi = abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex(); if (bi != -1) { - cnt += abcPanel.abc.bodies[bi].removeTraps(abcPanel.abc.constants, abcPanel.abc, abcPanel.decompiledTextArea.getScriptIndex(), abcPanel.decompiledTextArea.getClassIndex(), abcPanel.decompiledTextArea.getIsStatic()); + cnt += abcPanel.abc.bodies[bi].removeTraps(abcPanel.abc.constants, abcPanel.abc, abcPanel.decompiledTextArea.getScriptLeaf().scriptIndex, abcPanel.decompiledTextArea.getClassIndex(), abcPanel.decompiledTextArea.getIsStatic()); } abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(bi, abcPanel.abc); } @@ -1587,9 +1591,9 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_REMOVE_DEAD_CODE) { abcPanel.abc.bodies[bi].removeDeadCode(abcPanel.abc.constants); } else if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_REMOVE_TRAPS) { - abcPanel.abc.bodies[bi].removeTraps(abcPanel.abc.constants, abcPanel.abc, abcPanel.decompiledTextArea.getScriptIndex(), abcPanel.decompiledTextArea.getClassIndex(), abcPanel.decompiledTextArea.getIsStatic()); + abcPanel.abc.bodies[bi].removeTraps(abcPanel.abc.constants, abcPanel.abc, abcPanel.decompiledTextArea.getScriptLeaf().scriptIndex, abcPanel.decompiledTextArea.getClassIndex(), abcPanel.decompiledTextArea.getIsStatic()); } else if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_RESTORE_CONTROL_FLOW) { - abcPanel.abc.bodies[bi].removeTraps(abcPanel.abc.constants, abcPanel.abc, abcPanel.decompiledTextArea.getScriptIndex(), abcPanel.decompiledTextArea.getClassIndex(), abcPanel.decompiledTextArea.getIsStatic()); + abcPanel.abc.bodies[bi].removeTraps(abcPanel.abc.constants, abcPanel.abc, abcPanel.decompiledTextArea.getScriptLeaf().scriptIndex, abcPanel.decompiledTextArea.getClassIndex(), abcPanel.decompiledTextArea.getIsStatic()); abcPanel.abc.bodies[bi].restoreControlFlow(abcPanel.abc.constants); } } @@ -1675,7 +1679,7 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi abcPanel.navigator.setABC(abcList, scriptLeaf.abc); abcPanel.navigator.setClassIndex(classIndex, scriptLeaf.scriptIndex); abcPanel.setAbc(scriptLeaf.abc); - abcPanel.decompiledTextArea.setScript(scriptLeaf.scriptIndex, scriptLeaf.abc, abcList); + abcPanel.decompiledTextArea.setScript(scriptLeaf, abcList); abcPanel.decompiledTextArea.setClassIndex(classIndex); abcPanel.decompiledTextArea.setNoTrait(); abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setCode("");