From 05d07018a57ef34d84cef12b40658f9a32959443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=F8=EDk?= Date: Sat, 6 Jul 2013 16:30:19 +0200 Subject: [PATCH] AS1/2 deobfuscation - renaming fix --- .../com/jpexs/decompiler/flash/KeyValue.java | 69 +++++++++++++++++++ trunk/src/com/jpexs/decompiler/flash/SWF.java | 45 +++++++----- .../flash/gui/action/ActionPanel.java | 4 +- 3 files changed, 98 insertions(+), 20 deletions(-) create mode 100644 trunk/src/com/jpexs/decompiler/flash/KeyValue.java diff --git a/trunk/src/com/jpexs/decompiler/flash/KeyValue.java b/trunk/src/com/jpexs/decompiler/flash/KeyValue.java new file mode 100644 index 000000000..d37cc3714 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/KeyValue.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2013 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash; + +import java.util.Objects; + +/** + * + * @param Key + * @param Value + * @author JPEXS + */ +public class KeyValue { + + public K key; + public V value; + + public KeyValue(K key, V value) { + this.key = key; + this.value = value; + } + + @Override + public String toString() { + return key.toString() + " = " + value.toString(); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 61 * hash + Objects.hashCode(this.key); + hash = 61 * hash + Objects.hashCode(this.value); + return hash; + } + + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + @SuppressWarnings("unchecked") + final KeyValue other = (KeyValue) obj; + if (!Objects.equals(this.key, other.key)) { + return false; + } + if (!Objects.equals(this.value, other.value)) { + return false; + } + return true; + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/SWF.java b/trunk/src/com/jpexs/decompiler/flash/SWF.java index 32762d4a4..0662ec6a5 100644 --- a/trunk/src/com/jpexs/decompiler/flash/SWF.java +++ b/trunk/src/com/jpexs/decompiler/flash/SWF.java @@ -1209,7 +1209,7 @@ public class SWF { public static final String validNextCharacters = validFirstCharacters + "0123456789"; public static final String fooCharacters = "bcdfghjklmnpqrstvwz"; public static final String fooJoinCharacters = "aeiouy"; - private HashMap allVariableNames = new HashMap<>(); + private List> allVariableNames = new ArrayList<>(); private HashSet allVariableNamesStr = new HashSet<>(); private List allFunctions = new ArrayList<>(); private HashMap allStrings = new HashMap<>(); @@ -1315,7 +1315,7 @@ public class SWF { return null; } - private static void getVariables(ConstantPool constantPool, List localData, Stack stack, List output, ActionGraphSource code, int ip, HashMap variables, List functions, HashMap strings, List visited, HashMap usageTypes) { + private static void getVariables(ConstantPool constantPool, List localData, Stack stack, List output, ActionGraphSource code, int ip, List> variables, List functions, HashMap strings, List visited, HashMap usageTypes) { boolean debugMode = false; while ((ip > -1) && ip < code.size()) { if (visited.contains(ip)) { @@ -1326,6 +1326,9 @@ public class SWF { if (debugMode) { System.err.println("Visit " + ip + ": ofs" + Helper.formatAddress(((Action) ins).getAddress()) + ":" + ((Action) ins).getASMSource(new ArrayList(), new ArrayList(), new ArrayList(), code.version, false) + " stack:" + Helper.stackToString(stack, Helper.toList(new ConstantPool()))); } + if (ins.isExit()) { + break; + } if (ins.isIgnored()) { ip++; continue; @@ -1400,7 +1403,7 @@ public class SWF { } if (name instanceof DirectValueTreeItem) { - variables.put((DirectValueTreeItem) name, constantPool); + variables.add(new KeyValue((DirectValueTreeItem) name, constantPool)); usageTypes.put((DirectValueTreeItem) name, usageType); } @@ -1461,7 +1464,7 @@ public class SWF { }; } - private static void getVariables(HashMap variables, List functions, HashMap strings, HashMap usageType, ActionGraphSource code, int addr) { + private static void getVariables(List> variables, List functions, HashMap strings, HashMap usageType, ActionGraphSource code, int addr) { List localData = Helper.toList(new HashMap(), new HashMap(), new HashMap()); try { getVariables(null, localData, new Stack(), new ArrayList(), code, code.adr2pos(addr), variables, functions, strings, new ArrayList(), usageType); @@ -1470,8 +1473,8 @@ public class SWF { } } - private HashMap getVariables(HashMap variables, List functions, HashMap strings, HashMap usageType, ASMSource src) { - HashMap ret = new HashMap<>(); + private List> getVariables(List> variables, List functions, HashMap strings, HashMap usageType, ASMSource src) { + List> ret = new ArrayList<>(); List actions = src.getActions(version); actionsMap.put(src, actions); getVariables(variables, functions, strings, usageType, new ActionGraphSource(actions, version, new HashMap(), new HashMap(), new HashMap()), 0); @@ -1579,7 +1582,7 @@ public class SWF { private int renameAS2Identifiers(RenameType renameType, Map selected) { actionsMap = new HashMap<>(); allFunctions = new ArrayList<>(); - allVariableNames = new HashMap<>(); + allVariableNames = new ArrayList<>(); allStrings = new HashMap<>(); List objs = new ArrayList<>(); @@ -1588,8 +1591,8 @@ public class SWF { getVariables(objs, ""); informListeners("rename", ""); int fc = 0; - for (DirectValueTreeItem ti : allVariableNames.keySet()) { - String name = ti.toStringNoH(allVariableNames.get(ti)); + for (KeyValue it : allVariableNames) { + String name = it.key.toStringNoH(it.value); allVariableNamesStr.add(name); } @@ -1737,31 +1740,35 @@ public class SWF { } HashSet stringsNoVarH = new HashSet<>(); + List allVariableNamesDv = new ArrayList<>(); + for (KeyValue it : allVariableNames) { + allVariableNamesDv.add(it.key); + } for (DirectValueTreeItem ti : allStrings.keySet()) { - if (!allVariableNames.containsKey(ti)) { + if (!allVariableNamesDv.contains(ti)) { stringsNoVarH.add(System.identityHashCode(allStrings.get(ti)) + "_" + ti.toStringNoH(allStrings.get(ti))); } } int vc = 0; - for (DirectValueTreeItem ti : allVariableNames.keySet()) { + for (KeyValue it : allVariableNames) { vc++; - String name = ti.toStringNoH(allVariableNames.get(ti)); - String changed = deobfuscateName(name, false, usageTypes.get(ti), renameType, selected); + String name = it.key.toStringNoH(it.value); + String changed = deobfuscateName(name, false, usageTypes.get(it.key), renameType, selected); if (changed != null) { boolean addNew = false; - String h = System.identityHashCode(allVariableNames.get(ti)) + "_" + name; + String h = System.identityHashCode(it.key) + "_" + name; if (stringsNoVarH.contains(h)) { addNew = true; } - ActionPush pu = (ActionPush) ti.src; + ActionPush pu = (ActionPush) it.key.src; if (pu.replacement == null) { pu.replacement = new ArrayList<>(); pu.replacement.addAll(pu.values); } - if (pu.replacement.get(ti.pos) instanceof ConstantIndex) { - ConstantIndex ci = (ConstantIndex) pu.replacement.get(ti.pos); - ConstantPool pool = allVariableNames.get(ti); + if (pu.replacement.get(it.key.pos) instanceof ConstantIndex) { + ConstantIndex ci = (ConstantIndex) pu.replacement.get(it.key.pos); + ConstantPool pool = it.value; if (pool == null) { continue; } @@ -1775,7 +1782,7 @@ public class SWF { pool.constants.set(ci.index, changed); } } else { - pu.replacement.set(ti.pos, changed); + pu.replacement.set(it.key.pos, changed); } ret++; } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java index babf8b457..e93818865 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java @@ -52,6 +52,8 @@ import java.io.StringReader; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import java.util.regex.Pattern; import javax.swing.BoxLayout; import javax.swing.JButton; @@ -277,7 +279,7 @@ public class ActionPanel extends JPanel implements ActionListener { } }; asm.addDisassemblyListener(listener); - lastDisasm = asm.getASMSource(SWF.DEFAULT_VERSION, true); + lastDisasm = asm.getASMSource(SWF.DEFAULT_VERSION, true); asm.removeDisassemblyListener(listener); srcWithHex = Helper.hexToComments(lastDisasm); srcNoHex = Helper.stripComments(lastDisasm);