DottedChains in identifier deobfuscation

This commit is contained in:
2015-07-16 13:20:23 +02:00
parent 36e7bdbaee
commit a911196575
9 changed files with 97 additions and 103 deletions
@@ -282,7 +282,7 @@ public class ABC {
}
}
public void deobfuscateIdentifiers(HashMap<String, String> namesMap, RenameType renameType, boolean classesOnly) {
public void deobfuscateIdentifiers(HashMap<DottedChain, DottedChain> namesMap, RenameType renameType, boolean classesOnly) {
Set<Integer> stringUsages = getStringUsages();
Set<Integer> namespaceUsages = getNsStringUsages();
Map<Integer, String> stringUsageTypes = new HashMap<>();
@@ -30,13 +30,13 @@ public class ClassPath {
public final String className;
public ClassPath(DottedChain packageStr, String className) {
this.packageStr = packageStr;
this.packageStr = packageStr == null ? DottedChain.EMPTY : packageStr;
this.className = className;
}
@Override
public String toString() {
return (packageStr == null || packageStr.isEmpty()) ? className : packageStr.toPrintableString(true) + "." + className;
return packageStr.isEmpty() ? className : packageStr.toPrintableString(true) + "." + className;
}
@Override
@@ -421,12 +421,7 @@ public class AVM2ConstantPool {
String str = getString(index);
DottedChain chain = dottedChainCache.get(str);
if (chain == null) {
if (str.isEmpty()) {
chain = DottedChain.EMPTY;
} else {
chain = new DottedChain(str.split("\\."));
}
chain = DottedChain.parse(str);
dottedChainCache.put(str, chain);
}
@@ -18,8 +18,9 @@ package com.jpexs.decompiler.flash.abc.avm2;
import com.jpexs.decompiler.flash.abc.RenameType;
import com.jpexs.decompiler.graph.DottedChain;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
@@ -109,7 +110,7 @@ public class AVM2Deobfuscation {
return null;
}
private String fooString(HashMap<String, String> deobfuscated, String orig, boolean firstUppercase, int rndSize, String usageType, RenameType renameType) {
private String fooString(HashMap<DottedChain, DottedChain> deobfuscated, String orig, boolean firstUppercase, int rndSize, String usageType, RenameType renameType) {
boolean exists;
String ret;
int pos = 0;
@@ -131,18 +132,21 @@ public class AVM2Deobfuscation {
} else if (renameType == RenameType.RANDOMWORD) {
int len = 3 + rnd.nextInt(rndSize - 3);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; i++) {
String c = "";
char c;
if ((i % 2) == 0) {
c = "" + FOO_CHARACTERS.charAt(rnd.nextInt(FOO_CHARACTERS.length()));
c = FOO_CHARACTERS.charAt(rnd.nextInt(FOO_CHARACTERS.length()));
} else {
c = "" + FOO_JOIN_CHARACTERS.charAt(rnd.nextInt(FOO_JOIN_CHARACTERS.length()));
c = FOO_JOIN_CHARACTERS.charAt(rnd.nextInt(FOO_JOIN_CHARACTERS.length()));
}
if (i == 0 && firstUppercase) {
c = c.toUpperCase(Locale.ENGLISH);
c = Character.toUpperCase(c);
}
ret += c;
sb.append(c);
}
ret = sb.toString();
}
for (int i = 1; i < constants.getStringCount(); i++) {
if (constants.getString(i).equals(ret)) {
@@ -156,18 +160,18 @@ public class AVM2Deobfuscation {
rndSize += 1;
continue;
}
if (deobfuscated.containsValue(ret)) {
if (deobfuscated.containsValue(DottedChain.parse(ret))) {
exists = true;
rndSize += 1;
continue;
}
} while (exists);
usageTypesCount.put(usageType, pos);
deobfuscated.put(orig, ret);
deobfuscated.put(DottedChain.parse(orig), DottedChain.parse(ret));
return ret;
}
public int deobfuscatePackageName(Map<Integer, String> stringUsageTypes, Set<Integer> stringUsages, HashMap<String, String> namesMap, int strIndex, RenameType renameType) {
public int deobfuscatePackageName(Map<Integer, String> stringUsageTypes, Set<Integer> stringUsages, HashMap<DottedChain, DottedChain> namesMap, int strIndex, RenameType renameType) {
if (strIndex <= 0) {
return strIndex;
}
@@ -177,41 +181,35 @@ public class AVM2Deobfuscation {
}
boolean isValid = isValidNSPart(s);
if (!isValid) {
String newName;
if (namesMap.containsKey(s)) {
newName = constants.setString(strIndex, namesMap.get(s));
DottedChain sChain = DottedChain.parse(s);
DottedChain newName;
if (namesMap.containsKey(sChain)) {
newName = namesMap.get(sChain);
constants.setString(strIndex, newName.toRawString());
} else {
String[] parts = null;
if (s.contains(".")) {
parts = s.split("\\.");
} else {
parts = new String[]{s};
}
StringBuilder ret = new StringBuilder();
for (int p = 0; p < parts.length; p++) {
if (p > 0) {
ret.append(".");
}
if (!isValidNSPart(parts[p])) {
ret.append(fooString(namesMap, parts[p], false, DEFAULT_FOO_SIZE, "package", renameType));
List<String> ret = new ArrayList<>();
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));
} else {
ret.append(parts[p]);
ret.add(part);
}
}
newName = ret.toString();
namesMap.put(s, newName);
newName = new DottedChain(ret);
namesMap.put(sChain, newName);
}
if (stringUsages.contains(strIndex)) {
strIndex = constants.addString(newName);
strIndex = constants.addString(newName.toRawString());
} else {
constants.setString(strIndex, newName);
constants.setString(strIndex, newName.toRawString());
}
}
return strIndex;
}
public int deobfuscateName(Map<Integer, String> stringUsageTypes, Set<Integer> stringUsages, Set<Integer> namespaceUsages, HashMap<String, String> namesMap, int strIndex, boolean firstUppercase, RenameType renameType) {
public int deobfuscateName(Map<Integer, String> stringUsageTypes, Set<Integer> stringUsages, Set<Integer> namespaceUsages, HashMap<DottedChain, DottedChain> namesMap, int strIndex, boolean firstUppercase, RenameType renameType) {
if (strIndex <= 0) {
return strIndex;
}
@@ -238,18 +236,20 @@ public class AVM2Deobfuscation {
}
if (!isValid) {
String newname;
if (namesMap.containsKey(s)) {
newname = namesMap.get(s);
DottedChain newname;
DottedChain sChain = DottedChain.parse(s);
if (namesMap.containsKey(sChain)) {
newname = namesMap.get(sChain);
} else {
newname = fooString(namesMap, constants.getString(strIndex), firstUppercase, DEFAULT_FOO_SIZE, stringUsageTypes.get(strIndex), renameType);
String str = fooString(namesMap, constants.getString(strIndex), firstUppercase, DEFAULT_FOO_SIZE, stringUsageTypes.get(strIndex), renameType);
newname = DottedChain.parse(str);
}
if (stringUsages.contains(strIndex) || namespaceUsages.contains(strIndex)) { // this name is already referenced as String
strIndex = constants.addString(s); // add new index
}
constants.setString(strIndex, newname);
if (!namesMap.containsKey(s)) {
namesMap.put(s, constants.getString(strIndex));
constants.setString(strIndex, newname.toRawString());
if (!namesMap.containsKey(sChain)) {
namesMap.put(sChain, DottedChain.parse(constants.getString(strIndex)));
}
}
return strIndex;
@@ -294,7 +294,7 @@ public class Multiname {
return isAttribute() ? "@*" : "*";
} else {
String name = constants.getString(name_index);
if (fullyQualifiedNames != null && fullyQualifiedNames.contains(name)) {
if (fullyQualifiedNames != null && fullyQualifiedNames.contains(DottedChain.parse(name))) {
DottedChain dc = getNameWithNamespace(constants);
return raw ? dc.toRawString() : dc.toPrintableString(true);
}
@@ -381,8 +381,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
for (ScriptInfo si : tag.getABC().script_info) {
for (Trait t : si.traits.traits) {
ClassPath classPath = t.getPath(tag.getABC());
DottedChain pkg = classPath.packageStr == null ? DottedChain.EMPTY : classPath.packageStr;
if (pkg.equals(packageName)) {
if (classPath.packageStr.equals(packageName)) {
namesInThisPackage.add(classPath.className);
}
}