Fixed #1185 AS3 Incorrect imports in obfuscated files

This commit is contained in:
Jindra Petřík
2021-02-10 18:22:05 +01:00
parent 273173771f
commit b2fd1c0dc5
12 changed files with 81 additions and 49 deletions

View File

@@ -101,6 +101,12 @@ public final class MethodBody implements Cloneable {
@Internal
private ABC abc;
/**
* DependencyParser uses this
*/
@Internal
private MethodBody lastConvertedBody = null;
public MethodBody() {
this.traits = new Traits();
this.codeBytes = SWFInputStream.BYTE_ARRAY_EMPTY;
@@ -297,7 +303,7 @@ public final class MethodBody implements Cloneable {
@Override
public Void call() throws InterruptedException {
try (Statistics s1 = new Statistics("MethodBody.convert")) {
MethodBody converted = convertMethodBody(convertData, path, isStatic, scriptIndex, classIndex, abc, trait, scopeStack, initializerType != GraphTextWriter.TRAIT_INSTANCE_INITIALIZER, fullyQualifiedNames, initTraits);
MethodBody converted = convertMethodBody(convertData.deobfuscationMode != 0, path, isStatic, scriptIndex, classIndex, abc, trait);
HashMap<Integer, String> localRegNames = getLocalRegNames(abc);
List<GraphTargetItem> convertedItems1;
try (Statistics s = new Statistics("AVM2Code.toGraphTargetItems")) {
@@ -319,7 +325,6 @@ public final class MethodBody implements Cloneable {
} catch (InterruptedException ex) {
throw ex;
} catch (Exception | OutOfMemoryError | StackOverflowError ex) {
ex.printStackTrace();
convertException = ex;
Throwable cause = ex.getCause();
if (ex instanceof ExecutionException && cause instanceof Exception) {
@@ -372,19 +377,29 @@ public final class MethodBody implements Cloneable {
return writer;
}
public MethodBody convertMethodBody(ConvertData convertData, String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, Trait trait, ScopeStack scopeStack, boolean isStaticInitializer, List<DottedChain> fullyQualifiedNames, List<Traits> initTraits) throws InterruptedException {
public MethodBody convertMethodBodyCanUseLast(boolean deobfuscate, String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, Trait trait) throws InterruptedException {
if (lastConvertedBody != null) {
return lastConvertedBody;
}
return convertMethodBody(deobfuscate, path, isStatic, scriptIndex, classIndex, abc, trait);
}
public void clearLastConverted() {
this.lastConvertedBody = null;
}
public MethodBody convertMethodBody(boolean deobfuscate, String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, Trait trait) throws InterruptedException {
MethodBody body = clone();
AVM2Code code = body.getCode();
code.markVirtualAddresses();
code.fixJumps(path, body);
if (convertData.deobfuscationMode != 0) {
if (deobfuscate) {
try {
code.removeTraps(trait, method_info, body, abc, scriptIndex, classIndex, isStatic, path);
} catch (ThreadDeath | InterruptedException ex) {
throw ex;
} catch (Throwable ex) {
ex.printStackTrace();
//ignore
logger.log(Level.SEVERE, "Deobfuscation failed in: " + path, ex);
body = clone();
@@ -394,6 +409,7 @@ public final class MethodBody implements Cloneable {
}
}
lastConvertedBody = body;
return body;
}

View File

@@ -168,7 +168,7 @@ public abstract class Trait implements Cloneable, Serializable {
return getName(abc).getNamespace(abc.constants).getName(abc.constants);
}
public void getDependencies(String ignoredCustom, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
public void getDependencies(int scriptIndex, int classIndex, boolean isStatic, String ignoredCustom, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
if (ignoredCustom == null) {
Namespace n = getName(abc).getNamespace(abc.constants);
if (n.kind == Namespace.KIND_NAMESPACE) {
@@ -189,7 +189,7 @@ public abstract class Trait implements Cloneable, Serializable {
return false;
}
public void writeImportsUsages(ABC abc, GraphTextWriter writer, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
public void writeImportsUsages(int scriptIndex, int classIndex, boolean isStatic, ABC abc, GraphTextWriter writer, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
List<String> namesInThisPackage = new ArrayList<>();
for (ABCContainerTag tag : abc.getAbcTags()) {
@@ -211,7 +211,7 @@ public abstract class Trait implements Cloneable, Serializable {
if (ns.kind == Namespace.KIND_NAMESPACE) {
customNs = ns.getName(abc.constants).toRawString();
}
getDependencies(customNs, abc, dependencies, uses, ignorePackage, new ArrayList<>());
getDependencies(scriptIndex, classIndex, isStatic, customNs, abc, dependencies, uses, ignorePackage, new ArrayList<>());
List<DottedChain> imports = new ArrayList<>();
for (Dependency d : dependencies) {

View File

@@ -68,8 +68,8 @@ public class TraitClass extends Trait implements TraitWithSlot {
}
@Override
public void getDependencies(String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
super.getDependencies(customNs, abc, dependencies, uses, ignorePackage == null ? getPackage(abc) : ignorePackage, fullyQualifiedNames);
public void getDependencies(int scriptIndex, int classIndex, boolean isStatic, String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
super.getDependencies(scriptIndex, -1, false, customNs, abc, dependencies, uses, ignorePackage == null ? getPackage(abc) : ignorePackage, fullyQualifiedNames);
ClassInfo classInfo = abc.class_info.get(class_info);
InstanceInfo instanceInfo = abc.instance_info.get(class_info);
DottedChain packageName = instanceInfo.getName(abc.constants).getNamespace(abc.constants).getName(abc.constants); //assume not null name
@@ -83,16 +83,16 @@ public class TraitClass extends Trait implements TraitWithSlot {
}
//static
classInfo.static_traits.getDependencies(customNs, abc, dependencies, uses, packageName, fullyQualifiedNames);
classInfo.static_traits.getDependencies(scriptIndex, class_info, true, customNs, abc, dependencies, uses, packageName, fullyQualifiedNames);
//static initializer
DependencyParser.parseDependenciesFromMethodInfo(customNs, abc, classInfo.cinit_index, dependencies, uses, packageName, fullyQualifiedNames, new ArrayList<>());
DependencyParser.parseDependenciesFromMethodInfo(null, scriptIndex, class_info, true, customNs, abc, classInfo.cinit_index, dependencies, uses, packageName, fullyQualifiedNames, new ArrayList<>());
//instance
instanceInfo.instance_traits.getDependencies(customNs, abc, dependencies, uses, packageName, fullyQualifiedNames);
instanceInfo.instance_traits.getDependencies(scriptIndex, class_info, false, customNs, abc, dependencies, uses, packageName, fullyQualifiedNames);
//instance initializer
DependencyParser.parseDependenciesFromMethodInfo(customNs, abc, instanceInfo.iinit_index, dependencies, uses, packageName, fullyQualifiedNames, new ArrayList<>());
DependencyParser.parseDependenciesFromMethodInfo(null, scriptIndex, class_info, false, customNs, abc, instanceInfo.iinit_index, dependencies, uses, packageName, fullyQualifiedNames, new ArrayList<>());
}
@Override
@@ -113,7 +113,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
DottedChain packageName = instanceInfoMultiname.getNamespace(abc.constants).getName(abc.constants); //assume not null name
fullyQualifiedNames = new ArrayList<>();
writeImportsUsages(abc, writer, packageName, fullyQualifiedNames);
writeImportsUsages(scriptIndex, classIndex, false, abc, writer, packageName, fullyQualifiedNames);
String instanceInfoName = instanceInfoMultiname.getName(abc.constants, fullyQualifiedNames, false, true);

View File

@@ -80,7 +80,7 @@ public class TraitFunction extends Trait implements TraitWithSlot {
@Override
public GraphTextWriter toString(Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel) throws InterruptedException {
writeImportsUsages(abc, writer, getPackage(abc), fullyQualifiedNames);
writeImportsUsages(scriptIndex, classIndex, false, abc, writer, getPackage(abc), fullyQualifiedNames);
getMetaData(parent, convertData, abc, writer);
writer.startMethod(method_info);
toStringHeader(parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel);
@@ -100,7 +100,7 @@ public class TraitFunction extends Trait implements TraitWithSlot {
@Override
public void convert(Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel) throws InterruptedException {
fullyQualifiedNames = new ArrayList<>();
writeImportsUsages(abc, writer, getPackage(abc), fullyQualifiedNames);
writeImportsUsages(scriptIndex, classIndex, false, abc, writer, getPackage(abc), fullyQualifiedNames);
writer.startMethod(method_info);
convertHeader(parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel);
int bodyIndex = abc.findBodyIndex(method_info);
@@ -126,14 +126,14 @@ public class TraitFunction extends Trait implements TraitWithSlot {
}
@Override
public void getDependencies(String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
public void getDependencies(int scriptIndex, int classIndex, boolean isStatic, String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
if (ignorePackage == null) {
ignorePackage = getPackage(abc);
}
super.getDependencies(customNs, abc, dependencies, uses, ignorePackage, fullyQualifiedNames);
super.getDependencies(scriptIndex, classIndex, false, customNs, abc, dependencies, uses, ignorePackage, fullyQualifiedNames);
//if (method_info != 0)
{
DependencyParser.parseDependenciesFromMethodInfo(customNs, abc, method_info, dependencies, uses, ignorePackage, fullyQualifiedNames, new ArrayList<>());
DependencyParser.parseDependenciesFromMethodInfo(this, scriptIndex, classIndex, false, customNs, abc, method_info, dependencies, uses, ignorePackage, fullyQualifiedNames, new ArrayList<>());
}
}

View File

@@ -61,11 +61,11 @@ public class TraitMethodGetterSetter extends Trait {
}
@Override
public void getDependencies(String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
public void getDependencies(int scriptIndex, int classIndex, boolean isStatic, String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
if (ignorePackage == null) {
ignorePackage = getPackage(abc);
}
super.getDependencies(customNs, abc, dependencies, uses, ignorePackage, fullyQualifiedNames);
super.getDependencies(scriptIndex, classIndex, isStatic, customNs, abc, dependencies, uses, ignorePackage, fullyQualifiedNames);
if (customNs == null) {
Namespace n = getName(abc).getNamespace(abc.constants);
@@ -75,7 +75,7 @@ public class TraitMethodGetterSetter extends Trait {
}
//if (method_info != 0)
{
DependencyParser.parseDependenciesFromMethodInfo(customNs, abc, method_info, dependencies, uses, ignorePackage, fullyQualifiedNames, new ArrayList<>());
DependencyParser.parseDependenciesFromMethodInfo(this, scriptIndex, classIndex, isStatic, customNs, abc, method_info, dependencies, uses, ignorePackage, fullyQualifiedNames, new ArrayList<>());
}
}
@@ -107,7 +107,7 @@ public class TraitMethodGetterSetter extends Trait {
@Override
public void convert(Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel) throws InterruptedException {
if (classIndex < 0) {
writeImportsUsages(abc, writer, getPackage(abc), fullyQualifiedNames);
writeImportsUsages(scriptIndex, classIndex, isStatic, abc, writer, getPackage(abc), fullyQualifiedNames);
}
writer.startMethod(method_info);
path = path + "." + getName(abc).getName(abc.constants, fullyQualifiedNames, false, true);
@@ -127,7 +127,7 @@ public class TraitMethodGetterSetter extends Trait {
public GraphTextWriter toString(Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel) throws InterruptedException {
if (classIndex < 0) {
writeImportsUsages(abc, writer, getPackage(abc), fullyQualifiedNames);
writeImportsUsages(scriptIndex, classIndex, isStatic, abc, writer, getPackage(abc), fullyQualifiedNames);
}
getMetaData(parent, convertData, abc, writer);
writer.startMethod(method_info);

View File

@@ -201,11 +201,11 @@ public class TraitSlotConst extends Trait implements TraitWithSlot {
}
@Override
public void getDependencies(String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
public void getDependencies(int scriptIndex, int classIndex, boolean isStatic, String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
if (ignorePackage == null) {
ignorePackage = getPackage(abc);
}
super.getDependencies(customNs, abc, dependencies, uses, ignorePackage, fullyQualifiedNames);
super.getDependencies(scriptIndex, classIndex, isStatic, customNs, abc, dependencies, uses, ignorePackage, fullyQualifiedNames);
DependencyParser.parseDependenciesFromMultiname(customNs, abc, dependencies, uses, abc.constants.getMultiname(type_index), getPackage(abc), fullyQualifiedNames, DependencyType.SIGNATURE);
}

View File

@@ -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.types.traits;
import com.jpexs.decompiler.flash.abc.ABC;
@@ -240,9 +241,9 @@ public class Traits implements Cloneable, Serializable {
}
}
public void getDependencies(int scriptIndex, int classIndex, boolean isStatic, String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
for (Trait t : traits) {
for (Trait t : traits) {
t.getDependencies(scriptIndex, classIndex, isStatic, customNs, abc, dependencies, uses, ignorePackage, fullyQualifiedNames);
}
}