AS3 namespaces deobfuscation fix

This commit is contained in:
Jindra Petřík
2014-09-14 18:50:36 +02:00
parent a5cf35e285
commit 7193119f11
15 changed files with 213 additions and 214 deletions
@@ -801,7 +801,7 @@ public class ABC {
if (t instanceof TraitSlotConst) {
TraitSlotConst s = ((TraitSlotConst) t);
if (s.isNamespace()) {
String key = constants.getNamespace(s.value_index).getName(constants); //assume not null
String key = constants.getNamespace(s.value_index).getName(constants,true); //assume not null
String val = constants.getMultiname(s.name_index).getNameWithNamespace(constants, true);
namespaceMap.put(key, val);
}
@@ -74,7 +74,7 @@ public class ScriptPack implements TreeElementItem {
Multiname name = abc.script_info.get(scriptIndex).traits.traits.get(t).getName(abc);
Namespace ns = name.getNamespace(abc.constants);
if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) {
packageName = ns.getName(abc.constants); //assume not null
packageName = ns.getName(abc.constants,false); //assume not null
}
}
return packageName;
@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.␍ */
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.avm2.model;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
@@ -33,7 +34,7 @@ public class FindDefAVM2Item extends AVM2Item {
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) {
return writer.append(propertyName.getNamespace(localData.constantsAvm2).getName(localData.constantsAvm2)); //assume not null name
return writer.append(propertyName.getNamespace(localData.constantsAvm2).getName(localData.constantsAvm2,false)); //assume not null name
}
@Override
@@ -70,7 +70,7 @@ public class FullMultinameAVM2Item extends AVM2Item {
} else {
Namespace ns = constants.getMultiname(multinameIndex).getNamespace(constants);
if ((ns != null) && (ns.name_index != 0)) {
cns = ns.getName(constants);
cns = ns.getName(constants,false);
}
}
return cname.equals("XML") && cns.isEmpty();
@@ -2136,7 +2136,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
abc.constants.getMultinameId(
new Multiname(Multiname.QNAME,
abc.constants.getStringId(superName.getName(a.constants, new ArrayList<String>(), true), true),
abc.constants.getNamespaceId(new Namespace(superName.getNamespace(a.constants).kind, abc.constants.getStringId(superName.getNamespace(a.constants).getName(a.constants), true)), 0, true), 0, 0, new ArrayList<Integer>()), true)
abc.constants.getNamespaceId(new Namespace(superName.getNamespace(a.constants).kind, abc.constants.getStringId(superName.getNamespace(a.constants).getName(a.constants,true), true)), 0, true), 0, 0, new ArrayList<Integer>()), true)
);
}
}
@@ -2190,11 +2190,11 @@ public class AVM2SourceGenerator implements SourceGenerator {
continue;
}
for (Trait t : ii.traits.traits) {
if (eq(pkg, t.getName(abc).getNamespace(abc.constants).getName(abc.constants))) {
if (eq(pkg, t.getName(abc).getNamespace(abc.constants).getName(abc.constants,true))) {
if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList<String>(), true))) {
outName.setVal(obj);
outNs.setVal(pkg);
outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants));
outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants,true));
outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind);
outPropNsIndex.setVal(abc.constants.getNamespaceSubIndex(t.getName(abc).namespace_index));
outPropType.setVal(getTraitReturnType(abc, t));
@@ -2215,7 +2215,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
}
Multiname clsName = ii.getName(abc.constants);
if (obj.equals(clsName.getName(abc.constants, new ArrayList<String>(), true))) {
if (eq(pkg, clsName.getNamespace(abc.constants).getName(abc.constants))) {
if (eq(pkg, clsName.getNamespace(abc.constants).getName(abc.constants,true))) {
//class found
for (Trait t : ii.instance_traits.traits) {
@@ -2225,7 +2225,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList<String>(), true))) {
outName.setVal(obj);
outNs.setVal(pkg);
outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants));
outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants,true));
outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind);
outPropNsIndex.setVal(abc.constants.getNamespaceSubIndex(t.getName(abc).namespace_index));
outPropType.setVal(getTraitReturnType(abc, t));
@@ -2245,7 +2245,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList<String>(), true))) {
outName.setVal(obj);
outNs.setVal(pkg);
outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants));
outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants,true));
outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind);
outPropNsIndex.setVal(abc.constants.getNamespaceSubIndex(t.getName(abc).namespace_index));
outPropType.setVal(getTraitReturnType(abc, t));
@@ -2260,7 +2260,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
Multiname superName = abc.constants.constant_multiname.get(ii.super_index);
if (superName != null) {
return searchPrototypeChain(instanceOnly, abcs, superName.getNamespace(abc.constants).getName(abc.constants), superName.getName(abc.constants, new ArrayList<String>(), true), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue);
return searchPrototypeChain(instanceOnly, abcs, superName.getNamespace(abc.constants).getName(abc.constants,true), superName.getName(abc.constants, new ArrayList<String>(), true), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue);
} else {
return false;
}
@@ -2274,7 +2274,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
public static void parentNames(ABC abc, List<ABC> allABCs, int name_index, List<Integer> indices, List<String> names, List<String> namespaces, List<ABC> outABCs) {
indices.add(name_index);
names.add(abc.constants.constant_multiname.get(name_index).getName(abc.constants, new ArrayList<String>(), true));
namespaces.add(abc.constants.constant_multiname.get(name_index).getNamespace(abc.constants).getName(abc.constants));
namespaces.add(abc.constants.constant_multiname.get(name_index).getNamespace(abc.constants).getName(abc.constants,true));
Multiname mname = abc.constants.constant_multiname.get(name_index);
outABCs.add(abc);
@@ -2288,7 +2288,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
Multiname m = a.constants.constant_multiname.get(a.instance_info.get(i).name_index);
if (m.getName(a.constants, new ArrayList<String>(), true).equals(mname.getName(abc.constants, new ArrayList<String>(), true))) {
if (m.getNamespace(a.constants).hasName(a.constants, mname.getNamespace(abc.constants).getName(abc.constants))) {
if (m.getNamespace(a.constants).hasName(mname.getNamespace(abc.constants).getName(abc.constants,true),a.constants)) {
//Multiname superName = a.constants.constant_multiname.get(a.instance_info.get(i).super_index);
abcs.remove(a);
if (a.instance_info.get(i).super_index != 0) {
@@ -2392,7 +2392,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
for (int i = 1; i < abc.constants.constant_multiname.size(); i++) {
Multiname mname = abc.constants.constant_multiname.get(i);
if (mname != null && name.equals(mname.getName(abc.constants, new ArrayList<String>(), true))) {
if (mname.getNamespace(abc.constants) != null && pkg.equals(mname.getNamespace(abc.constants).getName(abc.constants))) {
if (mname.getNamespace(abc.constants) != null && pkg.equals(mname.getNamespace(abc.constants).getName(abc.constants,true))) {
name_index = i;
break;
}
@@ -219,7 +219,7 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
Reference<Integer> outPropNsIndex = new Reference<>(0);
Reference<GraphTargetItem> outPropType = new Reference<>(null);
Reference<ValueKind> outPropValue = new Reference<>(null);
if (AVM2SourceGenerator.searchPrototypeChain(false, abcs, m.getNamespace(a.constants).getName(a.constants), m.getName(a.constants, new ArrayList<String>(), true), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue)) {
if (AVM2SourceGenerator.searchPrototypeChain(false, abcs, m.getNamespace(a.constants).getName(a.constants,true), m.getName(a.constants, new ArrayList<String>(), true), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue)) {
objType = new TypeItem("".equals(outNs.getVal()) ? outName.getVal() : outNs.getVal() + "." + outName.getVal());
propType = outPropType.getVal();
propIndex = abc.constants.getMultinameId(new Multiname(Multiname.QNAME,
@@ -258,7 +258,7 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
for (int i = 0; i < openedNamespaces.size(); i++) {
int nsindex = openedNamespaces.get(i);
int nsKind = abc.constants.constant_namespace.get(openedNamespaces.get(i)).kind;
String nsname = abc.constants.constant_namespace.get(openedNamespaces.get(i)).getName(abc.constants);
String nsname = abc.constants.constant_namespace.get(openedNamespaces.get(i)).getName(abc.constants,true);
int name_index = 0;
for (int m = 1; m < abc.constants.constant_multiname.size(); m++) {
Multiname mname = abc.constants.constant_multiname.get(m);
@@ -328,7 +328,7 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
continue;
}
Multiname n = a.constants.constant_multiname.get(ii.name_index);
if (n.getNamespace(a.constants).kind == Namespace.KIND_PACKAGE && n.getNamespace(a.constants).getName(a.constants).equals(nsname)) {
if (n.getNamespace(a.constants).kind == Namespace.KIND_PACKAGE && n.getNamespace(a.constants).getName(a.constants,true).equals(nsname)) {
Reference<String> outName = new Reference<>("");
Reference<String> outNs = new Reference<>("");
Reference<String> outPropNs = new Reference<>("");
@@ -407,7 +407,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
continue;
}
if ((a.instance_info.get(c).getName(a.constants) != null && a == abc && a.instance_info.get(c).getName(a.constants).namespace_index == ni)
|| (ons.kind != Namespace.KIND_PRIVATE && a.instance_info.get(c).getName(a.constants) != null && a.instance_info.get(c).getName(a.constants).getNamespace(a.constants) != null && a.instance_info.get(c).getName(a.constants).getNamespace(a.constants).hasName(ons.getName(abc.constants), a.constants))) {
|| (ons.kind != Namespace.KIND_PRIVATE && a.instance_info.get(c).getName(a.constants) != null && a.instance_info.get(c).getName(a.constants).getNamespace(a.constants) != null && a.instance_info.get(c).getName(a.constants).getNamespace(a.constants).hasName(ons.getName(abc.constants,true), a.constants))) {
String cname = a.instance_info.get(c).getName(a.constants).getName(a.constants, new ArrayList<String>(), true);
if (parts.get(0).equals(cname)) {
if (!subtypes.isEmpty() && parts.size() > 1) {
@@ -157,7 +157,7 @@ public class Multiname {
}
int type = constants.getNamespace(index).kind;
int name_index = constants.getNamespace(index).name_index;
String name = name_index == 0 ? null : constants.getNamespace(index).getName(constants);
String name = name_index == 0 ? null : constants.getNamespace(index).getName(constants,true);
int sub = -1;
for (int n = 1; n < constants.getNamespaceCount(); n++) {
if (constants.getNamespace(n).kind == type && constants.getNamespace(n).name_index == name_index) {
@@ -272,7 +272,7 @@ public class Multiname {
String ret = "";
Namespace ns = getNamespace(constants);
if (ns != null) {
String nsname = ns.getName(constants);
String nsname = ns.getName(constants,raw);
if (nsname != null && !nsname.isEmpty()) {
ret += nsname + ".";
}
@@ -77,7 +77,7 @@ public class Namespace {
}
public String toString(AVM2ConstantPool constants) {
return getName(constants); //getPrefix(constants)+" "+getName(constants);
return getName(constants,false);
}
public String getNameWithKind(AVM2ConstantPool constants) {
@@ -97,18 +97,14 @@ public class Namespace {
return kindStr;
}
public String getName(AVM2ConstantPool constants) {
public String getName(AVM2ConstantPool constants, boolean raw) {
if (name_index == 0) {
return null;
}
return Deobfuscation.printNamespace(constants.getString(name_index));
}
public boolean hasName(AVM2ConstantPool constants, String name) {
if (name == null) {
return name_index == 0;
if(raw){
return constants.getString(name_index);
}
return name.equals(getName(constants));
return Deobfuscation.printNamespace(constants.getString(name_index));
}
public boolean hasName(String name, AVM2ConstantPool constants) {
@@ -50,7 +50,7 @@ public class ScriptInfo {
Namespace ns = name.getNamespace(abc.constants);
if ((ns.kind == Namespace.KIND_PACKAGE_INTERNAL)
|| (ns.kind == Namespace.KIND_PACKAGE)) {
String packageName = ns.getName(abc.constants); //assume not null package
String packageName = ns.getName(abc.constants,false); //assume not null package
String objectName = name.getName(abc.constants, new ArrayList<String>(), false);
List<Integer> traitIndices = new ArrayList<>();
@@ -134,7 +134,7 @@ public class ValueKind {
case CONSTANT_ExplicitNamespace:
case CONSTANT_StaticProtectedNs:
case CONSTANT_PrivateNs:
ret = "\"" + constants.getNamespace(value_index).getName(constants) + "\""; //assume not null name
ret = "\"" + constants.getNamespace(value_index).getName(constants,true) + "\""; //assume not null name
break;
}
return ret;
@@ -176,7 +176,7 @@ public class ValueKind {
case CONSTANT_ExplicitNamespace:
case CONSTANT_StaticProtectedNs:
case CONSTANT_PrivateNs:
ret = constants.getNamespace(value_index).getKindStr() + "(\"" + constants.getNamespace(value_index).getName(constants) + "\")"; //assume not null name
ret = constants.getNamespace(value_index).getKindStr() + "(\"" + constants.getNamespace(value_index).getName(constants,true) + "\")"; //assume not null name
break;
}
return ret;
@@ -63,7 +63,7 @@ public abstract class Trait implements Serializable {
if (m.namespace_index == -1) {
break;
}
nsname = abcTag.getABC().nsValueToName(abc.constants.getNamespace(m.namespace_index).getName(abc.constants));
nsname = abcTag.getABC().nsValueToName(abc.constants.getNamespace(m.namespace_index).getName(abc.constants,true));
if (nsname == null) {
break;
}
@@ -85,7 +85,7 @@ public abstract class Trait implements Serializable {
} else {
if (ns != null) {
if (ns.kind == Namespace.KIND_NAMESPACE) {
nsname = ns.getName(abc.constants);
nsname = ns.getName(abc.constants,true);
}
}
}
@@ -132,7 +132,7 @@ public abstract class Trait implements Serializable {
public GraphTextWriter toStringPackaged(Trait parent, String path, List<ABCContainerTag> abcTags, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<String> fullyQualifiedNames, boolean parallel) throws InterruptedException {
Namespace ns = abc.constants.getMultiname(name_index).getNamespace(abc.constants);
if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) {
String nsname = ns.getName(abc.constants);
String nsname = ns.getName(abc.constants,false);
writer.appendNoHilight("package");
if (!nsname.isEmpty()) {
writer.appendNoHilight(" " + nsname); //assume not null name
@@ -174,7 +174,7 @@ public abstract class Trait implements Serializable {
public String getPath(ABC abc) {
Multiname name = getName(abc);
Namespace ns = name.getNamespace(abc.constants);
String packageName = ns.getName(abc.constants);
String packageName = ns.getName(abc.constants,false);
String objectName = name.getName(abc.constants, new ArrayList<String>(), false);
return packageName + "." + objectName; //assume not null name
}
@@ -91,7 +91,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
if (name.isEmpty()) {
name = "*";
}
String newimport = ns.getName(abc.constants);
String newimport = ns.getName(abc.constants,false);
/*if ((ns.kind != Namespace.KIND_PACKAGE)
&& (ns.kind != Namespace.KIND_NAMESPACE)
&& (ns.kind != Namespace.KIND_STATIC_PROTECTED)) {
@@ -163,7 +163,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
if (name.isEmpty()) {
name = "*";
}
String newimport = ns.getName(abc.constants);
String newimport = ns.getName(abc.constants,false);
if (parseUsagesFromNS(abcTags, abc, imports, uses, namespace_index, ignorePackage, name)) {
return;
} else if ((ns.kind != Namespace.KIND_PACKAGE) && (ns.kind != Namespace.KIND_PACKAGE_INTERNAL)) {
@@ -321,7 +321,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
private List<String> getImportsUsages(List<ABCContainerTag> abcTags, ABC abc, List<String> imports, List<String> uses, List<String> fullyQualifiedNames) {
//constructor
String packageName = abc.instance_info.get(class_info).getName(abc.constants).getNamespace(abc.constants).getName(abc.constants); //assume not null name
String packageName = abc.instance_info.get(class_info).getName(abc.constants).getNamespace(abc.constants).getName(abc.constants,false); //assume not null name
parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(abc.instance_info.get(class_info).name_index), packageName, fullyQualifiedNames);
@@ -360,7 +360,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
public GraphTextWriter toString(Trait parent, String path, List<ABCContainerTag> abcTags, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<String> fullyQualifiedNames, boolean parallel) throws InterruptedException {
writer.startClass(class_info);
String packageName = abc.instance_info.get(class_info).getName(abc.constants).getNamespace(abc.constants).getName(abc.constants); //assume not null name
String packageName = abc.instance_info.get(class_info).getName(abc.constants).getNamespace(abc.constants).getName(abc.constants,false); //assume not null name
List<String> namesInThisPackage = new ArrayList<>();
for (ABCContainerTag tag : abcTags) {
for (ScriptInfo si : tag.getABC().script_info) {
@@ -103,11 +103,13 @@ public class Action implements GraphSourceItem {
private long address;
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"};
"as", "break", "case", "catch", "class", "const", "continue", "default", "delete", "do", "else",
"extends", "false", "finally", "for", "function", "if", "implements", "import", "in", "instanceof",
"interface", "internal", "is", "native", "new", "null", "package", "private", "protected", "public",
"return", "super", "switch", "this", "throw",/*to*/ "true", "try", "typeof", "use", "var", /*"void",*/ "while",
"with",
//syntactic keywords - can be used as identifiers, but that have special meaning in certain contexts
"each", "get", "set", "namespace", "#include", "include", "dynamic", "final", "native", "override", "static", "in"};
public static boolean isReservedWord(String s) {
if (s == null) {