diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/IdentifiersDeobfuscation.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/IdentifiersDeobfuscation.java index 518a12d6d..54503cc62 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/IdentifiersDeobfuscation.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/IdentifiersDeobfuscation.java @@ -38,7 +38,7 @@ import java.util.regex.Pattern; */ public class IdentifiersDeobfuscation { - private final Random rnd = new Random(); + private static final Random rnd = new Random(); private final int DEFAULT_FOO_SIZE = 10; @@ -88,6 +88,14 @@ public class IdentifiersDeobfuscation { "void", "while", "with" }; + // TODO, why do we have 2 different list? Moved from AVM2Deobfuscation + public static final String[] reservedWordsAS3_2 = { + "as", "break", "case", "catch", "class", "const", "continue", "default", "delete", "do", "each", "else", + "extends", "false", "finally", "for", "function", "get", "if", "implements", "import", "in", "instanceof", + "interface", "internal", "is", "native", "new", "null", "override", "package", "private", "protected", "public", + "return", "set", "super", "switch", "this", "throw", "true", "try", "typeof", "use", "var", /*"void",*/ "while", + "with", "dynamic", "default", "final", "in", "static"}; + //syntactic keywords - can be used as identifiers, but that have special meaning in certain contexts public static final String[] syntacticKeywordsAS3 = {"each", "get", "set", "namespace", "include", "dynamic", "final", "native", "override", "static"}; @@ -105,44 +113,38 @@ public class IdentifiersDeobfuscation { return false; } - private String fooString(boolean as3, HashMap deobfuscated, String orig, boolean firstUppercase, int rndSize) { - boolean exists; - String ret; - loopfoo: - do { - exists = false; - int len = 3 + rnd.nextInt(rndSize - 3); - StringBuilder sb = new StringBuilder(len); - for (int i = 0; i < len; i++) { - char c; - if ((i % 2) == 0) { - c = FOO_CHARACTERS.charAt(rnd.nextInt(FOO_CHARACTERS.length())); - } else { - c = FOO_JOIN_CHARACTERS.charAt(rnd.nextInt(FOO_JOIN_CHARACTERS.length())); - } - if (i == 0 && firstUppercase) { - c = Character.toUpperCase(c); - } - sb.append(c); + // TODO: Why do we need this method??? + public static boolean isReservedWord2(String s) { + if (s == null) { + return false; + } + String[] reservedWords = reservedWordsAS3_2; + s = s.trim(); + for (String rw : reservedWords) { + if (rw.equals(s)) { + return true; } - ret = sb.toString(); - if (allVariableNamesStr.contains(ret)) { - exists = true; - rndSize += 1; - continue loopfoo; + } + return false; + } + + public static String fooString(boolean firstUppercase, int rndSize) { + int len = 3 + rnd.nextInt(rndSize - 3); + StringBuilder sb = new StringBuilder(len); + for (int i = 0; i < len; i++) { + char c; + if ((i % 2) == 0) { + c = FOO_CHARACTERS.charAt(rnd.nextInt(FOO_CHARACTERS.length())); + } else { + c = FOO_JOIN_CHARACTERS.charAt(rnd.nextInt(FOO_JOIN_CHARACTERS.length())); } - if (isReservedWord(ret, as3)) { - exists = true; - rndSize += 1; - continue; + if (i == 0 && firstUppercase) { + c = Character.toUpperCase(c); } - if (deobfuscated.containsValue(DottedChain.parse(ret))) { - exists = true; - rndSize += 1; - continue; - } - } while (exists); - return ret; + sb.append(c); + } + + return sb.toString(); } public void deobfuscateInstanceNames(boolean as3, HashMap namesMap, RenameType renameType, List tags, Map selected) { @@ -266,25 +268,27 @@ public class IdentifiersDeobfuscation { if (namesMap.containsKey(sChain)) { return namesMap.get(sChain).toRawString(); } else { - Integer cnt = typeCounts.get(usageType); - if (cnt == null) { - cnt = 0; - } - String ret = null; - if (renameType == RenameType.TYPENUMBER) { + boolean found; + int rndSize = DEFAULT_FOO_SIZE; + do { + found = false; + if (renameType == RenameType.TYPENUMBER) { + ret = Helper.getNextId(usageType, typeCounts, true); + if (allVariableNamesStr.contains(ret)) { + found = true; + } + } else if (renameType == RenameType.RANDOMWORD) { + ret = fooString(firstUppercase, rndSize); + if (allVariableNamesStr.contains(ret) + || isReservedWord(ret, as3) + || namesMap.containsValue(DottedChain.parse(ret))) { + found = true; + rndSize++; + } + } + } while (found); - boolean found; - do { - found = false; - cnt++; - ret = usageType + "_" + cnt; - found = allVariableNamesStr.contains(ret); - } while (found); - typeCounts.put(usageType, cnt); - } else if (renameType == RenameType.RANDOMWORD) { - ret = fooString(as3, namesMap, s, firstUppercase, DEFAULT_FOO_SIZE); - } namesMap.put(DottedChain.parse(s), DottedChain.parse(ret)); return ret; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Deobfuscation.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Deobfuscation.java index 820139532..752d0c82b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Deobfuscation.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Deobfuscation.java @@ -16,14 +16,15 @@ */ package com.jpexs.decompiler.flash.abc.avm2; +import com.jpexs.decompiler.flash.IdentifiersDeobfuscation; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.abc.RenameType; import com.jpexs.decompiler.graph.DottedChain; +import com.jpexs.helpers.Helper; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Random; import java.util.Set; import java.util.regex.Pattern; @@ -33,27 +34,14 @@ import java.util.regex.Pattern; */ public class AVM2Deobfuscation { - private static final Random rnd = new Random(); - private static final int DEFAULT_FOO_SIZE = 10; - public static final String[] reservedWords = { - "as", "break", "case", "catch", "class", "const", "continue", "default", "delete", "do", "each", "else", - "extends", "false", "finally", "for", "function", "get", "if", "implements", "import", "in", "instanceof", - "interface", "internal", "is", "native", "new", "null", "override", "package", "private", "protected", "public", - "return", "set", "super", "switch", "this", "throw", "true", "try", "typeof", "use", "var", /*"void",*/ "while", - "with", "dynamic", "default", "final", "in", "static"}; - public static final String VALID_FIRST_CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"; public static final String VALID_NEXT_CHARACTERS = VALID_FIRST_CHARACTERS + "0123456789"; public static final String VALID_NS_CHARACTERS = ".:$"; - public static final String FOO_CHARACTERS = "bcdfghjklmnpqrstvwz"; - - public static final String FOO_JOIN_CHARACTERS = "aeiouy"; - private final SWF swf; private final AVM2ConstantPool constants; @@ -69,18 +57,9 @@ public class AVM2Deobfuscation { this.constants = constants; } - private static boolean isReserved(String s) { - for (String rw : reservedWords) { - if (rw.equals(s.trim())) { - return true; - } - } - return false; - } - private boolean isValidNSPart(String s) { boolean isValid = true; - if (isReserved(s)) { + if (IdentifiersDeobfuscation.isReservedWord2(s)) { isValid = false; } @@ -114,62 +93,29 @@ public class AVM2Deobfuscation { return null; } - private String fooString(HashMap deobfuscated, String orig, boolean firstUppercase, int rndSize, String usageType, RenameType renameType) { - boolean exists; - String ret; - int pos = 0; - + private String fooString(HashMap deobfuscated, String orig, boolean firstUppercase, String usageType, RenameType renameType) { if (usageType == null) { usageType = "name"; } - if (usageTypesCount.containsKey(usageType)) { - pos = usageTypesCount.get(usageType); - } - loopfoo: + String ret = null; + boolean found; + int rndSize = DEFAULT_FOO_SIZE; + do { - exists = false; - ret = ""; + found = false; if (renameType == RenameType.TYPENUMBER) { - pos++; - ret = usageType + "_" + pos; + ret = Helper.getNextId(usageType, usageTypesCount, true); } else if (renameType == RenameType.RANDOMWORD) { - int len = 3 + rnd.nextInt(rndSize - 3); - - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < len; i++) { - char c; - if ((i % 2) == 0) { - c = FOO_CHARACTERS.charAt(rnd.nextInt(FOO_CHARACTERS.length())); - } else { - c = FOO_JOIN_CHARACTERS.charAt(rnd.nextInt(FOO_JOIN_CHARACTERS.length())); - } - if (i == 0 && firstUppercase) { - c = Character.toUpperCase(c); - } - sb.append(c); - } - - ret = sb.toString(); + ret = IdentifiersDeobfuscation.fooString(firstUppercase, rndSize); } - if (swf.as3StringConstantExists(ret)) { - exists = true; - rndSize += 1; - continue loopfoo; - + if (swf.as3StringConstantExists(ret) + || IdentifiersDeobfuscation.isReservedWord2(ret) + || deobfuscated.containsValue(DottedChain.parse(ret))) { + found = true; + rndSize++; } - if (isReserved(ret)) { - exists = true; - rndSize += 1; - continue; - } - if (deobfuscated.containsValue(DottedChain.parse(ret))) { - exists = true; - rndSize += 1; - continue; - } - } while (exists); - usageTypesCount.put(usageType, pos); + } while (found); deobfuscated.put(DottedChain.parse(orig), DottedChain.parse(ret)); return ret; } @@ -194,7 +140,7 @@ public class AVM2Deobfuscation { for (int p = 0; p < sChain.size(); p++) { String part = sChain.get(p); if (!isValidNSPart(part)) { - ret.add(fooString(namesMap, part, false, DEFAULT_FOO_SIZE, "package", renameType)); + ret.add(fooString(namesMap, part, false, "package", renameType)); } else { ret.add(part); } @@ -218,7 +164,7 @@ public class AVM2Deobfuscation { } String s = constants.getString(strIndex); boolean isValid = true; - if (isReserved(s)) { + if (IdentifiersDeobfuscation.isReservedWord2(s)) { isValid = false; } @@ -244,7 +190,7 @@ public class AVM2Deobfuscation { if (namesMap.containsKey(sChain)) { newname = namesMap.get(sChain); } else { - String str = fooString(namesMap, constants.getString(strIndex), firstUppercase, DEFAULT_FOO_SIZE, stringUsageTypes.get(strIndex), renameType); + String str = fooString(namesMap, constants.getString(strIndex), firstUppercase, stringUsageTypes.get(strIndex), renameType); newname = DottedChain.parse(str); } if (stringUsages.contains(strIndex) || namespaceUsages.contains(strIndex)) { // this name is already referenced as String diff --git a/libsrc/ffdec_lib/src/com/jpexs/helpers/Helper.java b/libsrc/ffdec_lib/src/com/jpexs/helpers/Helper.java index 576718302..860fd3d31 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/helpers/Helper.java +++ b/libsrc/ffdec_lib/src/com/jpexs/helpers/Helper.java @@ -1365,4 +1365,24 @@ public class Helper { } return data; } + + public static String getNextId(String str, Map lastIds) { + return getNextId(str, lastIds, false); + } + + public static String getNextId(String str, Map lastIds, boolean addFirst) { + Integer a = lastIds.get(str); + if (a == null) { + lastIds.put(str, 1); + if (addFirst) { + str += "_1"; + } + + return str; + } + + a++; + lastIds.put(str, a); + return str + "_" + a; + } }