From 6b8f82fb5d2a652c289fb3085286be493f1be3a5 Mon Sep 17 00:00:00 2001 From: Honfika Date: Tue, 19 Nov 2013 19:42:23 +0100 Subject: [PATCH] command line switch for renaming invalid identifiers --- trunk/src/com/jpexs/decompiler/flash/SWF.java | 19 ++++++++- .../com/jpexs/decompiler/flash/abc/ABC.java | 32 +++++++++++---- .../console/CommandLineArgumentParser.java | 39 +++++++++++++++++-- .../jpexs/decompiler/flash/gui/MainFrame.java | 3 +- 4 files changed, 79 insertions(+), 14 deletions(-) diff --git a/trunk/src/com/jpexs/decompiler/flash/SWF.java b/trunk/src/com/jpexs/decompiler/flash/SWF.java index ff8e1c654..93e6ff114 100644 --- a/trunk/src/com/jpexs/decompiler/flash/SWF.java +++ b/trunk/src/com/jpexs/decompiler/flash/SWF.java @@ -548,6 +548,23 @@ public final class SWF { return true; } + public static boolean renameInvalidIdentifiers(RenameType renameType, InputStream fis, OutputStream fos) { + try { + SWF swf = new SWF(fis, Configuration.parallelSpeedUp.get()); + int cnt = swf.deobfuscateIdentifiers(renameType); + swf.assignClassesToSymbols(); + System.out.println(cnt + " identifiers renamed."); + swf.saveTo(fos); + } catch (InterruptedException ex) { + return false; + } catch (FileNotFoundException ex) { + return false; + } catch (IOException ex) { + return false; + } + return true; + } + public boolean exportAS3Class(String className, String outdir, ExportMode exportMode, boolean parallel) throws Exception { List abcTags = new ArrayList<>(); @@ -1945,7 +1962,7 @@ public final class SWF { renameAS2Identifiers(null, selected); } - public int deobfuscateAS2Identifiers(RenameType renameType) throws InterruptedException { + private int deobfuscateAS2Identifiers(RenameType renameType) throws InterruptedException { return renameAS2Identifiers(renameType, null); } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/ABC.java b/trunk/src/com/jpexs/decompiler/flash/abc/ABC.java index 4d91a2cc5..1ca3bdea4 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/ABC.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/ABC.java @@ -314,7 +314,9 @@ public class ABC { //constant integers int constant_int_pool_count = ais.readU30(); constants.constant_int = new ArrayList<>(constant_int_pool_count); - constants.addInt(0); + if (constant_int_pool_count > 0) { + constants.addInt(0); + } for (int i = 1; i < constant_int_pool_count; i++) { //index 0 not used. Values 1..n-1 constants.addInt(ais.readS32()); } @@ -322,7 +324,9 @@ public class ABC { //constant unsigned integers int constant_uint_pool_count = ais.readU30(); constants.constant_uint = new ArrayList<>(constant_uint_pool_count); - constants.addUInt(0); + if (constant_uint_pool_count > 0) { + constants.addUInt(0); + } for (int i = 1; i < constant_uint_pool_count; i++) { //index 0 not used. Values 1..n-1 constants.addUInt(ais.readU32()); } @@ -330,7 +334,9 @@ public class ABC { //constant double int constant_double_pool_count = ais.readU30(); constants.constant_double = new ArrayList<>(constant_double_pool_count); - constants.addDouble(0); + if (constant_double_pool_count > 0) { + constants.addDouble(0); + } for (int i = 1; i < constant_double_pool_count; i++) { //index 0 not used. Values 1..n-1 constants.addDouble(ais.readDouble()); } @@ -340,7 +346,9 @@ public class ABC { if (minor_version >= MINORwithDECIMAL) { int constant_decimal_pool_count = ais.readU30(); constants.constant_decimal = new ArrayList<>(constant_decimal_pool_count); - constants.addDecimal(null); + if (constant_decimal_pool_count > 0) { + constants.addDecimal(null); + } for (int i = 1; i < constant_decimal_pool_count; i++) { //index 0 not used. Values 1..n-1 constants.addDecimal(ais.readDecimal()); } @@ -352,7 +360,9 @@ public class ABC { int constant_string_pool_count = ais.readU30(); constants.constant_string = new ArrayList<>(constant_string_pool_count); stringOffsets = new long[constant_string_pool_count]; - constants.addString(""); + if (constant_string_pool_count > 0) { + constants.addString(""); + } for (int i = 1; i < constant_string_pool_count; i++) { //index 0 not used. Values 1..n-1 long pos = ais.getPosition(); constants.addString(ais.readString()); @@ -362,7 +372,9 @@ public class ABC { //constant namespace int constant_namespace_pool_count = ais.readU30(); constants.constant_namespace = new ArrayList<>(constant_namespace_pool_count); - constants.addNamespace(null); + if (constant_namespace_pool_count > 0) { + constants.addNamespace(null); + } for (int i = 1; i < constant_namespace_pool_count; i++) { //index 0 not used. Values 1..n-1 constants.addNamespace(ais.readNamespace()); } @@ -370,7 +382,9 @@ public class ABC { //constant namespace set int constant_namespace_set_pool_count = ais.readU30(); constants.constant_namespace_set = new ArrayList<>(constant_namespace_set_pool_count); - constants.addNamespaceSet(null); + if (constant_namespace_set_pool_count > 0) { + constants.addNamespaceSet(null); + } for (int i = 1; i < constant_namespace_set_pool_count; i++) { //index 0 not used. Values 1..n-1 constants.addNamespaceSet(new NamespaceSet()); int namespace_count = ais.readU30(); @@ -387,7 +401,9 @@ public class ABC { //constant multiname int constant_multiname_pool_count = ais.readU30(); constants.constant_multiname = new ArrayList<>(constant_multiname_pool_count); - constants.addMultiname(null); + if (constant_multiname_pool_count > 0) { + constants.addMultiname(null); + } for (int i = 1; i < constant_multiname_pool_count; i++) { //index 0 not used. Values 1..n-1 constants.addMultiname(ais.readMultiname()); } diff --git a/trunk/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java b/trunk/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java index d26354d2b..9d43800bf 100644 --- a/trunk/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java +++ b/trunk/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java @@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler; import com.jpexs.decompiler.flash.ApplicationInfo; import com.jpexs.decompiler.flash.EventListener; import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.abc.RenameType; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.configuration.ConfigurationItem; import com.jpexs.decompiler.flash.gui.Main; @@ -76,7 +77,9 @@ public class CommandLineArgumentParser { System.out.println(" ...Compress SWF infile and save it to outfile"); System.out.println(" 7) -decompress infile outfile"); System.out.println(" ...Decompress infile and save it to outfile"); - System.out.println(" 8) -config key=value[,key2=value2][,key3=value3...] [other parameters]"); + System.out.println(" 8) -renameInvalidIdentifiers (typeNumber|randomWord) infile outfile"); + System.out.println(" ...Renames the invalid identifiers in infile and save it to outfile"); + System.out.println(" 9) -config key=value[,key2=value2][,key3=value3...] [other parameters]"); System.out.print(" ...Sets configuration values. Available keys[current setting]:"); for (ConfigurationItem item : commandlineConfigBoolean) { System.out.print(" " + item + "[" + item.get() + "]"); @@ -85,9 +88,9 @@ public class CommandLineArgumentParser { System.out.println(" Values are boolean, you can use 0/1, true/false, on/off or yes/no."); System.out.println(" If no other parameters passed, configuration is saved. Otherwise it is used only once."); System.out.println(" DO NOT PUT space between comma (,) and next value."); - System.out.println(" 9) -onerror (abort|retryN|ignore)"); + System.out.println(" 10) -onerror (abort|retryN|ignore)"); System.out.println(" ...error handling mode. \"abort\" stops the exporting, \"retry\" tries the exporting N times, \"ignore\" ignores the current file"); - System.out.println(" 10) -timeout N"); + System.out.println(" 11) -timeout N"); System.out.println(" ...decompilation timeout for a single method in AS3 or single action in AS1/2 in seconds"); System.out.println(); System.out.println("Examples:"); @@ -168,6 +171,8 @@ public class CommandLineArgumentParser { parseCompress(args); } else if (nextParam.equals("-decompress")) { parseDecompress(args); + } else if (nextParam.equals("-renameInvalidIdentifiers")) { + parseRenameInvalidIdentifiers(args); } else if (nextParam.equals("-dumpSWF")) { parseDumpSwf(args); } else if (nextParam.equals("-help") || nextParam.equals("--help") || nextParam.equals("/?")) { @@ -556,6 +561,34 @@ public class CommandLineArgumentParser { } } + private static void parseRenameInvalidIdentifiers(Queue args) throws FileNotFoundException { + if (args.size() < 3) { + badArguments(); + } + + String renameTypeStr = args.remove(); + RenameType renameType; + switch (renameTypeStr.toLowerCase()) { + case "typenumber": + renameType = RenameType.TYPENUMBER; + break; + case "randomword": + renameType = RenameType.RANDOMWORD; + break; + default: + System.err.println("Invalid rename type:" + renameTypeStr); + badArguments(); + return; + } + if (SWF.renameInvalidIdentifiers(renameType, new FileInputStream(args.remove()), new FileOutputStream(args.remove()))) { + System.out.println("OK"); + System.exit(0); + } else { + System.err.println("FAIL"); + System.exit(1); + } + } + private static void parseDumpSwf(Queue args) { if (args.isEmpty()) { badArguments(); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java index c38773e17..8e63187fd 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java @@ -2899,8 +2899,7 @@ public final class MainFrame extends AppRibbonFrame implements ActionListener, T @Override protected Object doInBackground() throws Exception { try { - int cnt = 0; - cnt = swf.deobfuscateIdentifiers(renameType); + int cnt = swf.deobfuscateIdentifiers(renameType); Main.stopWork(); View.showMessageDialog(null, translate("message.rename.renamed").replace("%count%", "" + cnt)); swf.assignClassesToSymbols();