mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-08 08:35:07 +00:00
Fixed #1972 AS3 Renaming invalid identifiers - various fixes
Fixed #1972 AS3 imports taken only from packages, not package internal
This commit is contained in:
@@ -2690,9 +2690,23 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
}
|
||||
|
||||
public int deobfuscateAS3Identifiers(RenameType renameType) {
|
||||
|
||||
Map<Tag, Map<Integer, String>> stringUsageTypesMap = new HashMap<>();
|
||||
Map<Tag, Set<Integer>> stringUsagesMap = new HashMap<>();
|
||||
informListeners("deobfuscate", "Getting usages...");
|
||||
for (Tag tag : getTags()) {
|
||||
if (tag instanceof ABCContainerTag) {
|
||||
((ABCContainerTag) tag).getABC().deobfuscateIdentifiers(deobfuscated, renameType, true);
|
||||
if (tag instanceof ABCContainerTag) {
|
||||
Map<Integer, String> stringUsageTypes = new HashMap<>();
|
||||
Set<Integer> stringUsages = ((ABCContainerTag)tag).getABC().getStringUsages();
|
||||
((ABCContainerTag)tag).getABC().getStringUsageTypes(stringUsageTypes);
|
||||
stringUsageTypesMap.put(tag, stringUsageTypes);
|
||||
stringUsagesMap.put(tag, stringUsages);
|
||||
}
|
||||
}
|
||||
|
||||
for (Tag tag : getTags()) {
|
||||
if (tag instanceof ABCContainerTag) {
|
||||
((ABCContainerTag) tag).getABC().deobfuscateIdentifiers(stringUsageTypesMap.get(tag),stringUsagesMap.get(tag), deobfuscated, renameType, true);
|
||||
((ABCContainerTag) tag).getABC().constants.clearCachedMultinames();
|
||||
((ABCContainerTag) tag).getABC().constants.clearCachedDottedChains();
|
||||
tag.setModified(true);
|
||||
@@ -2700,7 +2714,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
}
|
||||
for (Tag tag : getTags()) {
|
||||
if (tag instanceof ABCContainerTag) {
|
||||
((ABCContainerTag) tag).getABC().deobfuscateIdentifiers(deobfuscated, renameType, false);
|
||||
((ABCContainerTag) tag).getABC().deobfuscateIdentifiers(stringUsageTypesMap.get(tag),stringUsagesMap.get(tag), deobfuscated, renameType, false);
|
||||
((ABCContainerTag) tag).getABC().constants.clearCachedMultinames();
|
||||
((ABCContainerTag) tag).getABC().constants.clearCachedDottedChains();
|
||||
tag.setModified(true);
|
||||
|
||||
@@ -122,13 +122,13 @@ public class ABC implements Openable {
|
||||
|
||||
/* Map from multiname index of namespace value to namespace name**/
|
||||
private Map<String, DottedChain> namespaceMap;
|
||||
|
||||
|
||||
private String file;
|
||||
|
||||
|
||||
private String fileTitle;
|
||||
|
||||
|
||||
private OpenableList openableList;
|
||||
|
||||
|
||||
private boolean isOpenable = false;
|
||||
|
||||
public ABC(ABCContainerTag tag) {
|
||||
@@ -147,7 +147,7 @@ public class ABC implements Openable {
|
||||
public SWF getSwf() {
|
||||
return parentTag.getSwf();
|
||||
}
|
||||
|
||||
|
||||
public List<ABCContainerTag> getAbcTags() {
|
||||
Openable openable = getOpenable();
|
||||
if (openable instanceof SWF) {
|
||||
@@ -259,6 +259,7 @@ public class ABC implements Openable {
|
||||
public int removeTraps() throws InterruptedException {
|
||||
return removeTraps(null);
|
||||
}
|
||||
|
||||
public int removeTraps(DeobfuscationListener listener) throws InterruptedException {
|
||||
int rem = 0;
|
||||
for (int s = 0; s < script_info.size(); s++) {
|
||||
@@ -289,10 +290,41 @@ public class ABC implements Openable {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public void getTraitStringUsages(Set<Integer> ret, Traits traits) {
|
||||
for (Trait t:traits.traits) {
|
||||
if (t instanceof TraitClass) {
|
||||
int ci = ((TraitClass)t).class_info;
|
||||
getTraitStringUsages(ret, instance_info.get(ci).instance_traits);
|
||||
getTraitStringUsages(ret, class_info.get(ci).static_traits);
|
||||
}
|
||||
if (t instanceof TraitSlotConst) {
|
||||
TraitSlotConst tsc = (TraitSlotConst)t;
|
||||
if (tsc.value_kind == ValueKind.CONSTANT_Utf8) {
|
||||
ret.add(tsc.value_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Set<Integer> getStringUsages() {
|
||||
Set<Integer> ret = new HashSet<>();
|
||||
|
||||
for (ScriptInfo si:script_info) {
|
||||
getTraitStringUsages(ret, si.traits);
|
||||
}
|
||||
|
||||
for (MethodInfo mi: method_info) {
|
||||
if((mi.flags & MethodInfo.FLAG_HAS_OPTIONAL) == MethodInfo.FLAG_HAS_OPTIONAL) {
|
||||
for (ValueKind vk : mi.optional) {
|
||||
if (vk.value_kind == ValueKind.CONSTANT_Utf8) {
|
||||
ret.add(vk.value_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (MethodBody body : bodies) {
|
||||
getTraitStringUsages(ret, body.traits);
|
||||
for (AVM2Instruction ins : body.getCode().code) {
|
||||
for (int i = 0; i < ins.definition.operands.length; i++) {
|
||||
if (ins.definition.operands[i] == AVM2Code.DAT_STRING_INDEX) {
|
||||
@@ -308,7 +340,11 @@ public class ABC implements Openable {
|
||||
if (ret.containsKey(strIndex)) {
|
||||
if (!"name".equals(usageType)) {
|
||||
if (!ret.get(strIndex).equals(usageType)) {
|
||||
ret.put(strIndex, "name");
|
||||
if ("class".equals(usageType) || ret.get(strIndex).equals("class")) {
|
||||
ret.put(strIndex, "class");
|
||||
} else {
|
||||
ret.put(strIndex, "name");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -316,14 +352,14 @@ public class ABC implements Openable {
|
||||
}
|
||||
}
|
||||
|
||||
private void getStringUsageTypes(Map<Integer, String> ret, Traits traits, boolean classesOnly) {
|
||||
private void getStringUsageTypes(Map<Integer, String> ret, Traits traits) {
|
||||
for (Trait t : traits.traits) {
|
||||
int strIndex = constants.getMultiname(t.name_index).name_index;
|
||||
String usageType = "";
|
||||
if (t instanceof TraitClass) {
|
||||
TraitClass tc = (TraitClass) t;
|
||||
getStringUsageTypes(ret, class_info.get(tc.class_info).static_traits, classesOnly);
|
||||
getStringUsageTypes(ret, instance_info.get(tc.class_info).instance_traits, classesOnly);
|
||||
getStringUsageTypes(ret, class_info.get(tc.class_info).static_traits);
|
||||
getStringUsageTypes(ret, instance_info.get(tc.class_info).instance_traits);
|
||||
|
||||
if (instance_info.get(tc.class_info).name_index != 0) {
|
||||
setStringUsageType(ret, constants.getMultiname(instance_info.get(tc.class_info).name_index).name_index, "class");
|
||||
@@ -331,6 +367,9 @@ public class ABC implements Openable {
|
||||
if (instance_info.get(tc.class_info).super_index != 0) {
|
||||
setStringUsageType(ret, constants.getMultiname(instance_info.get(tc.class_info).super_index).name_index, "class");
|
||||
}
|
||||
for (int iface : instance_info.get(tc.class_info).interfaces) {
|
||||
setStringUsageType(ret, constants.getMultiname(iface).name_index, "class");
|
||||
}
|
||||
|
||||
usageType = "class";
|
||||
}
|
||||
@@ -339,14 +378,14 @@ public class ABC implements Openable {
|
||||
usageType = "method";
|
||||
MethodBody body = findBody(tm.method_info);
|
||||
if (body != null) {
|
||||
getStringUsageTypes(ret, body.traits, classesOnly);
|
||||
getStringUsageTypes(ret, body.traits);
|
||||
}
|
||||
}
|
||||
if (t instanceof TraitFunction) {
|
||||
TraitFunction tf = (TraitFunction) t;
|
||||
MethodBody body = findBody(tf.method_info);
|
||||
if (body != null) {
|
||||
getStringUsageTypes(ret, body.traits, classesOnly);
|
||||
getStringUsageTypes(ret, body.traits);
|
||||
}
|
||||
usageType = "function";
|
||||
}
|
||||
@@ -359,15 +398,13 @@ public class ABC implements Openable {
|
||||
usageType = "const";
|
||||
}
|
||||
}
|
||||
if (usageType.equals("class") || (!classesOnly)) {
|
||||
setStringUsageType(ret, strIndex, usageType);
|
||||
}
|
||||
setStringUsageType(ret, strIndex, usageType);
|
||||
}
|
||||
}
|
||||
|
||||
public void getStringUsageTypes(Map<Integer, String> ret, boolean classesOnly) {
|
||||
public void getStringUsageTypes(Map<Integer, String> ret) {
|
||||
for (ScriptInfo script : script_info) {
|
||||
getStringUsageTypes(ret, script.traits, classesOnly);
|
||||
getStringUsageTypes(ret, script.traits);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,32 +423,40 @@ public class ABC implements Openable {
|
||||
}
|
||||
}
|
||||
|
||||
public void deobfuscateIdentifiers(HashMap<DottedChain, DottedChain> namesMap, RenameType renameType, boolean classesOnly) {
|
||||
Set<Integer> stringUsages = getStringUsages();
|
||||
public void deobfuscateIdentifiers(Map<Integer, String> stringUsageTypes, Set<Integer> stringUsages, HashMap<DottedChain, DottedChain> namesMap, RenameType renameType, boolean doClasses) {
|
||||
Set<Integer> namespaceUsages = getNsStringUsages();
|
||||
Map<Integer, String> stringUsageTypes = new HashMap<>();
|
||||
informListeners("deobfuscate", "Getting usage types...");
|
||||
getStringUsageTypes(stringUsageTypes, classesOnly);
|
||||
AVM2Deobfuscation deobfuscation = getDeobfuscation();
|
||||
for (int i = 0; i < instance_info.size(); i++) {
|
||||
informListeners("deobfuscate", "class " + i + "/" + instance_info.size());
|
||||
InstanceInfo insti = instance_info.get(i);
|
||||
if (insti.name_index != 0) {
|
||||
constants.getMultiname(insti.name_index).name_index = deobfuscation.deobfuscateName(stringUsageTypes, stringUsages, namespaceUsages, namesMap, constants.getMultiname(insti.name_index).name_index, true, renameType);
|
||||
if (constants.getMultiname(insti.name_index).namespace_index != 0) {
|
||||
constants.getNamespace(constants.getMultiname(insti.name_index).namespace_index).name_index
|
||||
= deobfuscation.deobfuscatePackageName(stringUsageTypes, stringUsages, namesMap, constants.getNamespace(constants.getMultiname(insti.name_index).namespace_index).name_index, renameType);
|
||||
|
||||
if (doClasses) {
|
||||
for (int i = 0; i < instance_info.size(); i++) {
|
||||
informListeners("deobfuscate", "class " + i + "/" + instance_info.size());
|
||||
InstanceInfo insti = instance_info.get(i);
|
||||
if (insti.name_index != 0) {
|
||||
constants.getMultiname(insti.name_index).name_index = deobfuscation.deobfuscateName(stringUsageTypes, stringUsages, namespaceUsages, namesMap, constants.getMultiname(insti.name_index).name_index, true, renameType);
|
||||
if (constants.getMultiname(insti.name_index).namespace_index != 0) {
|
||||
constants.getNamespace(constants.getMultiname(insti.name_index).namespace_index).name_index
|
||||
= deobfuscation.deobfuscatePackageName(stringUsageTypes, stringUsages, namesMap, constants.getNamespace(constants.getMultiname(insti.name_index).namespace_index).name_index, renameType);
|
||||
}
|
||||
}
|
||||
if (insti.super_index != 0) {
|
||||
constants.getMultiname(insti.super_index).name_index = deobfuscation.deobfuscateName(stringUsageTypes, stringUsages, namespaceUsages, namesMap, constants.getMultiname(insti.super_index).name_index, true, renameType);
|
||||
}
|
||||
for (int iface : insti.interfaces) {
|
||||
constants.getMultiname(iface).name_index = deobfuscation.deobfuscateName(stringUsageTypes, stringUsages, namespaceUsages, namesMap, constants.getMultiname(iface).name_index, true, renameType);
|
||||
}
|
||||
}
|
||||
if (insti.super_index != 0) {
|
||||
constants.getMultiname(insti.super_index).name_index = deobfuscation.deobfuscateName(stringUsageTypes, stringUsages, namespaceUsages, namesMap, constants.getMultiname(insti.super_index).name_index, true, renameType);
|
||||
}
|
||||
}
|
||||
if (classesOnly) {
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 1; i < constants.getMultinameCount(); i++) {
|
||||
informListeners("deobfuscate", "name " + i + "/" + constants.getMultinameCount());
|
||||
|
||||
Multiname m = constants.getMultiname(i);
|
||||
int strIndex = m.name_index;
|
||||
if (m.kind == Multiname.MULTINAME && strIndex > 0 && "*".equals(constants.getString(strIndex))) {
|
||||
continue;
|
||||
}
|
||||
constants.getMultiname(i).name_index = deobfuscation.deobfuscateName(stringUsageTypes, stringUsages, namespaceUsages, namesMap, constants.getMultiname(i).name_index, false, renameType);
|
||||
}
|
||||
for (int i = 1; i < constants.getNamespaceCount(); i++) {
|
||||
@@ -436,7 +481,12 @@ public class ABC implements Openable {
|
||||
String fullname = constants.getString(strIndex);
|
||||
String pkg = "";
|
||||
String name = fullname;
|
||||
if (fullname.contains(".")) {
|
||||
boolean hasFourDots = false;
|
||||
if (fullname.contains("::")) {
|
||||
pkg = fullname.substring(0, fullname.lastIndexOf("::"));
|
||||
name = fullname.substring(fullname.lastIndexOf("::") + 2);
|
||||
hasFourDots = true;
|
||||
} else if (fullname.contains(".")) {
|
||||
pkg = fullname.substring(0, fullname.lastIndexOf('.'));
|
||||
name = fullname.substring(fullname.lastIndexOf('.') + 1);
|
||||
}
|
||||
@@ -450,7 +500,7 @@ public class ABC implements Openable {
|
||||
name = constants.getString(nameStrIndex);
|
||||
String fullChanged = "";
|
||||
if (!pkg.isEmpty()) {
|
||||
fullChanged = pkg + ".";
|
||||
fullChanged = pkg + (hasFourDots ? "::" : ".");
|
||||
}
|
||||
fullChanged += name;
|
||||
strIndex = constants.getStringId(fullChanged, true);
|
||||
@@ -507,6 +557,7 @@ public class ABC implements Openable {
|
||||
public ABC(ABCInputStream ais, SWF swf, ABCContainerTag tag) throws IOException {
|
||||
this(ais, swf, tag, null, null);
|
||||
}
|
||||
|
||||
public ABC(ABCInputStream ais, SWF swf, ABCContainerTag tag, String file, String fileTitle) throws IOException {
|
||||
this.parentTag = tag;
|
||||
this.file = file;
|
||||
@@ -514,7 +565,7 @@ public class ABC implements Openable {
|
||||
if (file != null || fileTitle != null) {
|
||||
isOpenable = true;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
read(ais, swf);
|
||||
} catch (IOException ie) {
|
||||
@@ -526,7 +577,7 @@ public class ABC implements Openable {
|
||||
|
||||
SWFDecompilerPlugin.fireAbcParsed(this, swf);
|
||||
}
|
||||
|
||||
|
||||
private void read(ABCInputStream ais, SWF swf) throws IOException {
|
||||
int minor_version = ais.readU16("minor_version");
|
||||
int major_version = ais.readU16("major_version");
|
||||
@@ -1039,7 +1090,7 @@ public class ABC implements Openable {
|
||||
|
||||
return abcMethodIndexing;
|
||||
}
|
||||
|
||||
|
||||
public void resetMethodIndexing() {
|
||||
abcMethodIndexing = null;
|
||||
}
|
||||
@@ -2168,8 +2219,8 @@ public class ABC implements Openable {
|
||||
@Override
|
||||
public String getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFileTitle() {
|
||||
if (fileTitle != null) {
|
||||
@@ -2185,7 +2236,7 @@ public class ABC implements Openable {
|
||||
}
|
||||
return new File(file).getName();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getShortPathTitle() {
|
||||
if (openableList != null) {
|
||||
@@ -2210,12 +2261,12 @@ public class ABC implements Openable {
|
||||
}
|
||||
return getFileTitle();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
return getSwf().isModified(); //??
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setOpenableList(OpenableList openableList) {
|
||||
this.openableList = openableList;
|
||||
@@ -2235,21 +2286,21 @@ public class ABC implements Openable {
|
||||
@Override
|
||||
public void saveTo(OutputStream os) throws IOException {
|
||||
saveToStream(os);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFile(String file) {
|
||||
this.file = file;
|
||||
fileTitle = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearModified() {
|
||||
getSwf().clearModified();
|
||||
List<ABC> allAbcs = new ArrayList<>();
|
||||
allAbcs.add(this);
|
||||
List<ScriptPack> packs = getScriptPacks(null, allAbcs);
|
||||
for(ScriptPack pack : packs) {
|
||||
for (ScriptPack pack : packs) {
|
||||
if (pack.isModified()) {
|
||||
pack.clearModified();
|
||||
}
|
||||
|
||||
@@ -198,8 +198,10 @@ public class AVM2Deobfuscation {
|
||||
newname = DottedChain.parseNoSuffix(str);
|
||||
|
||||
if (stringUsages.contains(strIndex) || namespaceUsages.contains(strIndex)) { // this name is already referenced as String
|
||||
String usageType = stringUsageTypes.get(strIndex);
|
||||
strIndex = constants.addString(s); // add new index
|
||||
}
|
||||
stringUsageTypes.put(strIndex, usageType);
|
||||
}
|
||||
constants.setString(strIndex, newname.toRawString());
|
||||
if (!namesMap.containsKey(sChain)) {
|
||||
namesMap.put(sChain, DottedChain.parseNoSuffix(constants.getString(strIndex)));
|
||||
|
||||
@@ -50,7 +50,7 @@ public class DependencyParser {
|
||||
|
||||
if (parseUsagesFromNS(ignoredCustom, abc, dependencies, uses, namespace_index, ignorePackage, name)) {
|
||||
return;
|
||||
} else if ((ns.kind != Namespace.KIND_PACKAGE) && (ns.kind != Namespace.KIND_PACKAGE_INTERNAL)) {
|
||||
} else if (ns.kind != Namespace.KIND_PACKAGE) { // && (ns.kind != Namespace.KIND_PACKAGE_INTERNAL)) {
|
||||
return;
|
||||
}
|
||||
newimport = newimport.addWithSuffix(name);
|
||||
|
||||
Reference in New Issue
Block a user