mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-17 19:08:07 +00:00
load AVM2 instuctions dynamically (much less memory usage after loading an swf, but still fast decompiling)
This commit is contained in:
@@ -866,17 +866,13 @@ public final class SWF implements TreeItem, Timelined {
|
||||
}
|
||||
|
||||
public List<MyEntry<ClassPath, ScriptPack>> getAS3Packs() {
|
||||
List<ABCContainerTag> abcTags = new ArrayList<>();
|
||||
List<MyEntry<ClassPath, ScriptPack>> packs = new ArrayList<>();
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof ABCContainerTag) {
|
||||
abcTags.add((ABCContainerTag) t);
|
||||
ABCContainerTag abcTag = (ABCContainerTag) t;
|
||||
packs.addAll(abcTag.getABC().getScriptPacks());
|
||||
}
|
||||
}
|
||||
List<MyEntry<ClassPath, ScriptPack>> packs = new ArrayList<>();
|
||||
for (int i = 0; i < abcTags.size(); i++) {
|
||||
ABCContainerTag t = abcTags.get(i);
|
||||
packs.addAll(t.getABC().getScriptPacks());
|
||||
}
|
||||
return uniqueAS3Packs(packs);
|
||||
}
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ public class ABC {
|
||||
public Set<Integer> getStringUsages() {
|
||||
Set<Integer> ret = new HashSet<>();
|
||||
for (MethodBody body : bodies) {
|
||||
for (AVM2Instruction ins : body.code.code) {
|
||||
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) {
|
||||
ret.add(ins.operands[i]);
|
||||
@@ -301,15 +301,15 @@ public class ABC {
|
||||
|
||||
//process reflection using getDefinitionByName too
|
||||
for (MethodBody body : bodies) {
|
||||
for (int ip = 0; ip < body.code.code.size(); ip++) {
|
||||
if (body.code.code.get(ip).definition instanceof CallPropertyIns) {
|
||||
int mIndex = body.code.code.get(ip).operands[0];
|
||||
for (int ip = 0; ip < body.getCode().code.size(); ip++) {
|
||||
if (body.getCode().code.get(ip).definition instanceof CallPropertyIns) {
|
||||
int mIndex = body.getCode().code.get(ip).operands[0];
|
||||
if (mIndex > 0) {
|
||||
Multiname m = constants.getMultiname(mIndex);
|
||||
if (m.getNameWithNamespace(constants, true).equals("flash.utils.getDefinitionByName")) {
|
||||
if (ip > 0) {
|
||||
if (body.code.code.get(ip - 1).definition instanceof PushStringIns) {
|
||||
int strIndex = body.code.code.get(ip - 1).operands[0];
|
||||
if (body.getCode().code.get(ip - 1).definition instanceof PushStringIns) {
|
||||
int strIndex = body.getCode().code.get(ip - 1).operands[0];
|
||||
String fullname = constants.getString(strIndex);
|
||||
String pkg = "";
|
||||
String name = fullname;
|
||||
@@ -331,7 +331,7 @@ public class ABC {
|
||||
}
|
||||
fullChanged += name;
|
||||
strIndex = constants.getStringId(fullChanged, true);
|
||||
body.code.code.get(ip - 1).operands[0] = strIndex;
|
||||
body.getCode().code.get(ip - 1).operands[0] = strIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -543,14 +543,6 @@ public class ABC {
|
||||
mb.max_scope_depth = ais.readU30("max_scope_depth");
|
||||
int code_length = ais.readU30("code_length");
|
||||
mb.codeBytes = ais.readBytes(code_length, "code");
|
||||
try {
|
||||
ABCInputStream ais2 = new ABCInputStream(new MemoryInputStream(mb.codeBytes));
|
||||
mb.code = new AVM2Code(ais2);
|
||||
} catch (UnknownInstructionCode re) {
|
||||
mb.code = new AVM2Code();
|
||||
logger.log(Level.SEVERE, null, re);
|
||||
}
|
||||
mb.code.compact();
|
||||
int ex_count = ais.readU30("ex_count");
|
||||
mb.exceptions = new ABCException[ex_count];
|
||||
for (int j = 0; j < ex_count; j++) {
|
||||
@@ -673,7 +665,7 @@ public class ABC {
|
||||
aos.writeU30(mb.max_regs);
|
||||
aos.writeU30(mb.init_scope_depth);
|
||||
aos.writeU30(mb.max_scope_depth);
|
||||
byte[] codeBytes = mb.code.getBytes();
|
||||
byte[] codeBytes = mb.getCode().getBytes();
|
||||
aos.writeU30(codeBytes.length);
|
||||
aos.write(codeBytes);
|
||||
aos.writeU30(mb.exceptions.length);
|
||||
@@ -755,13 +747,17 @@ public class ABC {
|
||||
if (classIndex == -1) {
|
||||
return null;
|
||||
}
|
||||
if (traitId < class_info.get(classIndex).static_traits.traits.size()) {
|
||||
return class_info.get(classIndex).static_traits.traits.get(traitId);
|
||||
} else if (traitId < class_info.get(classIndex).static_traits.traits.size() + instance_info.get(classIndex).instance_traits.traits.size()) {
|
||||
traitId -= class_info.get(classIndex).static_traits.traits.size();
|
||||
return instance_info.get(classIndex).instance_traits.traits.get(traitId);
|
||||
List<Trait> staticTraits = class_info.get(classIndex).static_traits.traits;
|
||||
if (traitId < staticTraits.size()) {
|
||||
return staticTraits.get(traitId);
|
||||
} else {
|
||||
return null; //Can be class or instance initializer
|
||||
List<Trait> instanceTraits = instance_info.get(classIndex).instance_traits.traits;
|
||||
if (traitId < staticTraits.size() + instanceTraits.size()) {
|
||||
traitId -= staticTraits.size();
|
||||
return instanceTraits.get(traitId);
|
||||
} else {
|
||||
return null; //Can be class or instance initializer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -769,27 +765,31 @@ public class ABC {
|
||||
if (classIndex == -1) {
|
||||
return -1;
|
||||
}
|
||||
if (traitId < class_info.get(classIndex).static_traits.traits.size()) {
|
||||
if (class_info.get(classIndex).static_traits.traits.get(traitId) instanceof TraitMethodGetterSetter) {
|
||||
return ((TraitMethodGetterSetter) class_info.get(classIndex).static_traits.traits.get(traitId)).method_info;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else if (traitId < class_info.get(classIndex).static_traits.traits.size() + instance_info.get(classIndex).instance_traits.traits.size()) {
|
||||
traitId -= class_info.get(classIndex).static_traits.traits.size();
|
||||
if (instance_info.get(classIndex).instance_traits.traits.get(traitId) instanceof TraitMethodGetterSetter) {
|
||||
return ((TraitMethodGetterSetter) instance_info.get(classIndex).instance_traits.traits.get(traitId)).method_info;
|
||||
List<Trait> staticTraits = class_info.get(classIndex).static_traits.traits;
|
||||
if (traitId < staticTraits.size()) {
|
||||
if (staticTraits.get(traitId) instanceof TraitMethodGetterSetter) {
|
||||
return ((TraitMethodGetterSetter) staticTraits.get(traitId)).method_info;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
traitId -= class_info.get(classIndex).static_traits.traits.size() + instance_info.get(classIndex).instance_traits.traits.size();
|
||||
if (traitId == 0) {
|
||||
return instance_info.get(classIndex).iinit_index;
|
||||
} else if (traitId == 1) {
|
||||
return class_info.get(classIndex).cinit_index;
|
||||
List<Trait> instanceTraits = instance_info.get(classIndex).instance_traits.traits;
|
||||
if (traitId < staticTraits.size() + instanceTraits.size()) {
|
||||
traitId -= staticTraits.size();
|
||||
if (instanceTraits.get(traitId) instanceof TraitMethodGetterSetter) {
|
||||
return ((TraitMethodGetterSetter) instanceTraits.get(traitId)).method_info;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
traitId -= staticTraits.size() + instanceTraits.size();
|
||||
if (traitId == 0) {
|
||||
return instance_info.get(classIndex).iinit_index;
|
||||
} else if (traitId == 1) {
|
||||
return class_info.get(classIndex).cinit_index;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -876,7 +876,7 @@ public class ABC {
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (AVM2Instruction ins : body.code.code) {
|
||||
for (AVM2Instruction ins : body.getCode().code) {
|
||||
for (int o = 0; o < ins.definition.operands.length; o++) {
|
||||
if (ins.definition.operands[o] == AVM2Code.DAT_MULTINAME_INDEX) {
|
||||
if (ins.operands[o] == multinameIndex) {
|
||||
@@ -1058,7 +1058,7 @@ public class ABC {
|
||||
|
||||
public void removeClass(int index) {
|
||||
for (MethodBody b : bodies) {
|
||||
for (AVM2Instruction ins : b.code.code) {
|
||||
for (AVM2Instruction ins : b.getCode().code) {
|
||||
for (int i = 0; i < ins.definition.operands.length; i++) {
|
||||
if (ins.definition.operands[i] == AVM2Code.DAT_CLASS_INDEX) {
|
||||
if (ins.operands[i] > index) {
|
||||
@@ -1112,7 +1112,7 @@ public class ABC {
|
||||
if (b.method_info > index) {
|
||||
b.method_info--;
|
||||
}
|
||||
for (AVM2Instruction ins : b.code.code) {
|
||||
for (AVM2Instruction ins : b.getCode().code) {
|
||||
for (int i = 0; i < ins.definition.operands.length; i++) {
|
||||
if (ins.definition.operands[i] == AVM2Code.DAT_METHOD_INDEX) {
|
||||
if (ins.operands[i] > index) {
|
||||
|
||||
@@ -47,9 +47,9 @@ import java.util.logging.Logger;
|
||||
*/
|
||||
public class ScriptPack implements TreeElementItem {
|
||||
|
||||
public ABC abc;
|
||||
public int scriptIndex;
|
||||
public List<Integer> traitIndices;
|
||||
public final ABC abc;
|
||||
public final int scriptIndex;
|
||||
public final List<Integer> traitIndices;
|
||||
private final ClassPath path;
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1238,10 +1238,10 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
MethodBody initBody = null;
|
||||
if (!isInterface) {
|
||||
initBody = abc.findBody(init);
|
||||
initBody.code.code.addAll(constructor == null ? 0 : 2, initcode);//after getlocal0,pushscope
|
||||
initBody.getCode().code.addAll(constructor == null ? 0 : 2, initcode);//after getlocal0,pushscope
|
||||
|
||||
if (sinitBody.code.code.get(sinitBody.code.code.size() - 1).definition instanceof ReturnVoidIns) {
|
||||
sinitBody.code.code.addAll(2, sinitcode); //after getlocal0,pushscope
|
||||
if (sinitBody.getCode().code.get(sinitBody.getCode().code.size() - 1).definition instanceof ReturnVoidIns) {
|
||||
sinitBody.getCode().code.addAll(2, sinitcode); //after getlocal0,pushscope
|
||||
}
|
||||
}
|
||||
sinitBody.markOffsets();
|
||||
@@ -1619,8 +1619,9 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
|
||||
mbody.method_info = abc.addMethodInfo(mi);
|
||||
mi.setBody(mbody);
|
||||
mbody.code = new AVM2Code();
|
||||
mbody.code.code = toInsList(src);
|
||||
List<AVM2Instruction> mbodyCode = toInsList(src);
|
||||
mbody.setCode(new AVM2Code());
|
||||
mbody.getCode().code = mbodyCode;
|
||||
|
||||
if (needsActivation) {
|
||||
if (localData.traitUsages.containsKey(mbody)) {
|
||||
@@ -1635,7 +1636,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
NameAVM2Item d = new NameAVM2Item(type, 0, tsc.getName(abc).getName(abc.constants, new ArrayList<String>(), true), NameAVM2Item.getDefaultValue("" + type), true, new ArrayList<Integer>());
|
||||
d.setSlotNumber(tsc.slot_id);
|
||||
d.setSlotScope(slotScope);
|
||||
mbody.code.code.addAll(0, toInsList(d.toSourceIgnoreReturnValue(localData, this)));
|
||||
mbodyCode.addAll(0, toInsList(d.toSourceIgnoreReturnValue(localData, this)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1646,7 +1647,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
acts.add(AssignableAVM2Item.generateSetLoc(localData.activationReg));
|
||||
acts.add(ins(new PushScopeIns()));
|
||||
|
||||
mbody.code.code.addAll(0, acts);
|
||||
mbodyCode.addAll(0, acts);
|
||||
}
|
||||
|
||||
if (constructor) {
|
||||
@@ -1668,7 +1669,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
}
|
||||
}
|
||||
int ac = -1;
|
||||
for (AVM2Instruction ins : mbody.code.code) {
|
||||
for (AVM2Instruction ins : mbodyCode) {
|
||||
if (ins.definition instanceof ConstructSuperIns) {
|
||||
ac = ins.operands[0];
|
||||
if (parentConstMinAC > ac) {
|
||||
@@ -1679,8 +1680,8 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
}
|
||||
if (ac == -1) {
|
||||
if (parentConstMinAC == 0) {
|
||||
mbody.code.code.add(0, new AVM2Instruction(0, new GetLocal0Ins(), new int[]{}));
|
||||
mbody.code.code.add(1, new AVM2Instruction(0, new ConstructSuperIns(), new int[]{0}));
|
||||
mbodyCode.add(0, new AVM2Instruction(0, new GetLocal0Ins(), new int[]{}));
|
||||
mbodyCode.add(1, new AVM2Instruction(0, new ConstructSuperIns(), new int[]{0}));
|
||||
|
||||
} else {
|
||||
throw new CompilationException("Parent constructor must be called", line);
|
||||
@@ -1688,12 +1689,12 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
}
|
||||
}
|
||||
if (className != null) {//It's method, not (inner) function
|
||||
mbody.code.code.add(0, new AVM2Instruction(0, new GetLocal0Ins(), new int[]{}));
|
||||
mbody.code.code.add(1, new AVM2Instruction(0, new PushScopeIns(), new int[]{}));
|
||||
mbodyCode.add(0, new AVM2Instruction(0, new GetLocal0Ins(), new int[]{}));
|
||||
mbodyCode.add(1, new AVM2Instruction(0, new PushScopeIns(), new int[]{}));
|
||||
}
|
||||
boolean addRet = false;
|
||||
if (!mbody.code.code.isEmpty()) {
|
||||
InstructionDefinition lastDef = mbody.code.code.get(mbody.code.code.size() - 1).definition;
|
||||
if (!mbodyCode.isEmpty()) {
|
||||
InstructionDefinition lastDef = mbodyCode.get(mbodyCode.size() - 1).definition;
|
||||
if (!((lastDef instanceof ReturnVoidIns) || (lastDef instanceof ReturnValueIns))) {
|
||||
addRet = true;
|
||||
}
|
||||
@@ -1702,16 +1703,16 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
}
|
||||
if (addRet) {
|
||||
if (retType.toString().equals("*") || retType.toString().equals("void") || constructor) {
|
||||
mbody.code.code.add(new AVM2Instruction(0, new ReturnVoidIns(), new int[]{}));
|
||||
mbodyCode.add(new AVM2Instruction(0, new ReturnVoidIns(), new int[]{}));
|
||||
} else {
|
||||
mbody.code.code.add(new AVM2Instruction(0, new PushUndefinedIns(), new int[]{}));
|
||||
mbody.code.code.add(new AVM2Instruction(0, new ReturnValueIns(), new int[]{}));
|
||||
mbodyCode.add(new AVM2Instruction(0, new PushUndefinedIns(), new int[]{}));
|
||||
mbodyCode.add(new AVM2Instruction(0, new ReturnValueIns(), new int[]{}));
|
||||
}
|
||||
}
|
||||
mbody.exceptions = localData.exceptions.toArray(new ABCException[localData.exceptions.size()]);
|
||||
int offset = 0;
|
||||
for (int i = 0; i < mbody.code.code.size(); i++) {
|
||||
AVM2Instruction ins = mbody.code.code.get(i);
|
||||
for (int i = 0; i < mbodyCode.size(); i++) {
|
||||
AVM2Instruction ins = mbodyCode.get(i);
|
||||
if (ins instanceof ExceptionMarkAVM2Instruction) {
|
||||
ExceptionMarkAVM2Instruction m = (ExceptionMarkAVM2Instruction) ins;
|
||||
switch (m.markType) {
|
||||
@@ -1725,7 +1726,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
mbody.exceptions[m.exceptionId].target = offset;
|
||||
break;
|
||||
}
|
||||
mbody.code.code.remove(i);
|
||||
mbodyCode.remove(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
@@ -2065,9 +2066,10 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
MethodInfo mi = new MethodInfo(new int[0], 0, 0, 0, new ValueKind[0], new int[0]);
|
||||
MethodBody mb = new MethodBody();
|
||||
mb.method_info = abc.addMethodInfo(mi);
|
||||
mb.code = new AVM2Code();
|
||||
mb.code.code.add(ins(new GetLocal0Ins()));
|
||||
mb.code.code.add(ins(new PushScopeIns()));
|
||||
mb.setCode(new AVM2Code());
|
||||
List<AVM2Instruction> mbCode = mb.getCode().code;
|
||||
mbCode.add(ins(new GetLocal0Ins()));
|
||||
mbCode.add(ins(new PushScopeIns()));
|
||||
|
||||
int traitScope = 2;
|
||||
|
||||
@@ -2078,37 +2080,37 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
TraitClass tc = (TraitClass) t;
|
||||
List<Integer> parents = new ArrayList<>();
|
||||
if (localData.documentClass) {
|
||||
mb.code.code.add(ins(new GetScopeObjectIns(), 0));
|
||||
mbCode.add(ins(new GetScopeObjectIns(), 0));
|
||||
traitScope++;
|
||||
} else {
|
||||
NamespaceSet nsset = new NamespaceSet(new int[]{abc.constants.constant_multiname.get(tc.name_index).namespace_index});
|
||||
mb.code.code.add(ins(new FindPropertyStrictIns(), abc.constants.getMultinameId(new Multiname(Multiname.MULTINAME, abc.constants.constant_multiname.get(tc.name_index).name_index, 0, abc.constants.getNamespaceSetId(nsset, true), 0, new ArrayList<Integer>()), true)));
|
||||
mbCode.add(ins(new FindPropertyStrictIns(), abc.constants.getMultinameId(new Multiname(Multiname.MULTINAME, abc.constants.constant_multiname.get(tc.name_index).name_index, 0, abc.constants.getNamespaceSetId(nsset, true), 0, new ArrayList<Integer>()), true)));
|
||||
}
|
||||
if (abc.instance_info.get(tc.class_info).isInterface()) {
|
||||
mb.code.code.add(ins(new PushNullIns()));
|
||||
mbCode.add(ins(new PushNullIns()));
|
||||
} else {
|
||||
|
||||
parentNamesAddNames(abc, allABCs, abc.instance_info.get(tc.class_info).name_index, parents, new ArrayList<String>(), new ArrayList<String>());
|
||||
for (int i = parents.size() - 1; i >= 1; i--) {
|
||||
mb.code.code.add(ins(new GetLexIns(), parents.get(i)));
|
||||
mb.code.code.add(ins(new PushScopeIns()));
|
||||
mbCode.add(ins(new GetLexIns(), parents.get(i)));
|
||||
mbCode.add(ins(new PushScopeIns()));
|
||||
traitScope++;
|
||||
}
|
||||
mb.code.code.add(ins(new GetLexIns(), parents.get(1)));
|
||||
mbCode.add(ins(new GetLexIns(), parents.get(1)));
|
||||
}
|
||||
mb.code.code.add(ins(new NewClassIns(), tc.class_info));
|
||||
mbCode.add(ins(new NewClassIns(), tc.class_info));
|
||||
if (!abc.instance_info.get(tc.class_info).isInterface()) {
|
||||
for (int i = parents.size() - 1; i >= 1; i--) {
|
||||
mb.code.code.add(ins(new PopScopeIns()));
|
||||
mbCode.add(ins(new PopScopeIns()));
|
||||
}
|
||||
}
|
||||
mb.code.code.add(ins(new InitPropertyIns(), tc.name_index));
|
||||
mbCode.add(ins(new InitPropertyIns(), tc.name_index));
|
||||
initScopes.put(t, traitScope);
|
||||
traitScope = 1;
|
||||
}
|
||||
}
|
||||
|
||||
mb.code.code.add(ins(new ReturnVoidIns()));
|
||||
mbCode.add(ins(new ReturnVoidIns()));
|
||||
mb.autoFillStats(abc, 1, false);
|
||||
abc.addMethodBody(mb);
|
||||
si.init_index = mb.method_info;
|
||||
|
||||
@@ -17,9 +17,12 @@ package com.jpexs.decompiler.flash.abc.types;
|
||||
|
||||
import com.jpexs.decompiler.flash.AppResources;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.ABCInputStream;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.CodeStats;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.UnknownInstructionCode;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
@@ -31,6 +34,8 @@ import com.jpexs.decompiler.graph.ScopeStack;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
import com.jpexs.helpers.CancellableWorker;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.MemoryInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -52,27 +57,47 @@ public class MethodBody implements Cloneable, Serializable {
|
||||
public int init_scope_depth;
|
||||
public int max_scope_depth;
|
||||
public byte[] codeBytes;
|
||||
public AVM2Code code;
|
||||
private AVM2Code code;
|
||||
public ABCException[] exceptions = new ABCException[0];
|
||||
public Traits traits = new Traits();
|
||||
public transient List<GraphTargetItem> convertedItems;
|
||||
public transient Throwable convertException;
|
||||
|
||||
public synchronized AVM2Code getCode() {
|
||||
if (code == null) {
|
||||
AVM2Code avm2Code;
|
||||
try {
|
||||
ABCInputStream ais = new ABCInputStream(new MemoryInputStream(codeBytes));
|
||||
avm2Code = new AVM2Code(ais);
|
||||
} catch (UnknownInstructionCode | IOException ex) {
|
||||
avm2Code = new AVM2Code();
|
||||
Logger.getLogger(MethodBody.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
avm2Code.compact();
|
||||
code = avm2Code;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(AVM2Code code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public List<Integer> getExceptionEntries() {
|
||||
List<Integer> ret = new ArrayList<>();
|
||||
for (ABCException e : exceptions) {
|
||||
ret.add(code.adr2pos(e.start));
|
||||
ret.add(code.adr2pos(e.end));
|
||||
ret.add(code.adr2pos(e.target));
|
||||
ret.add(getCode().adr2pos(e.start));
|
||||
ret.add(getCode().adr2pos(e.end));
|
||||
ret.add(getCode().adr2pos(e.target));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void markOffsets() {
|
||||
long offset = 0;
|
||||
for (int i = 0; i < code.code.size(); i++) {
|
||||
code.code.get(i).offset = offset;
|
||||
offset += code.code.get(i).getBytes().length;
|
||||
for (int i = 0; i < getCode().code.size(); i++) {
|
||||
getCode().code.get(i).offset = offset;
|
||||
offset += getCode().code.get(i).getBytes().length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,20 +105,20 @@ public class MethodBody implements Cloneable, Serializable {
|
||||
public String toString() {
|
||||
String s = "";
|
||||
s += "method_info=" + method_info + " max_stack=" + max_stack + " max_regs=" + max_regs + " scope_depth=" + init_scope_depth + " max_scope=" + max_scope_depth;
|
||||
s += "\r\nCode:\r\n" + code.toString();
|
||||
s += "\r\nCode:\r\n" + getCode().toString();
|
||||
return s;
|
||||
}
|
||||
|
||||
public int removeDeadCode(ConstantPool constants, Trait trait, MethodInfo info) throws InterruptedException {
|
||||
return code.removeDeadCode(constants, trait, info, this);
|
||||
return getCode().removeDeadCode(constants, trait, info, this);
|
||||
}
|
||||
|
||||
public void restoreControlFlow(ConstantPool constants, Trait trait, MethodInfo info) throws InterruptedException {
|
||||
code.restoreControlFlow(constants, trait, info, this);
|
||||
getCode().restoreControlFlow(constants, trait, info, this);
|
||||
}
|
||||
|
||||
public int removeTraps(ConstantPool constants, ABC abc, Trait trait, int scriptIndex, int classIndex, boolean isStatic, String path) throws InterruptedException {
|
||||
return code.removeTraps(constants, trait, abc.method_info.get(method_info), this, abc, scriptIndex, classIndex, isStatic, path);
|
||||
return getCode().removeTraps(constants, trait, abc.method_info.get(method_info), this, abc, scriptIndex, classIndex, isStatic, path);
|
||||
}
|
||||
|
||||
public HashMap<Integer, String> getLocalRegNames(ABC abc) {
|
||||
@@ -115,7 +140,7 @@ public class MethodBody implements Cloneable, Serializable {
|
||||
pos++;
|
||||
}
|
||||
|
||||
HashMap<Integer, String> debugRegNames = code.getLocalRegNamesFromDebug(abc);
|
||||
HashMap<Integer, String> debugRegNames = getCode().getLocalRegNamesFromDebug(abc);
|
||||
for (int k : debugRegNames.keySet()) {
|
||||
ret.put(k, debugRegNames.get(k));
|
||||
}
|
||||
@@ -127,7 +152,7 @@ public class MethodBody implements Cloneable, Serializable {
|
||||
System.err.println("Decompiling " + path);
|
||||
}
|
||||
if (exportMode != ScriptExportMode.AS) {
|
||||
code.toASMSource(constants, trait, method_info.get(this.method_info), this, exportMode, writer);
|
||||
getCode().toASMSource(constants, trait, method_info.get(this.method_info), this, exportMode, writer);
|
||||
} else {
|
||||
if (!Configuration.decompile.get()) {
|
||||
writer.appendNoHilight("//" + AppResources.translate("decompilation.skipped")).newLine();
|
||||
@@ -140,7 +165,7 @@ public class MethodBody implements Cloneable, Serializable {
|
||||
public Void call() throws InterruptedException {
|
||||
MethodBody converted = convertMethodBody(path, isStatic, scriptIndex, classIndex, abc, trait, constants, method_info, scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits);
|
||||
HashMap<Integer, String> localRegNames = getLocalRegNames(abc);
|
||||
convertedItems = converted.code.toGraphTargetItems(path, isStatic, scriptIndex, classIndex, abc, constants, method_info, converted, localRegNames, scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits, Graph.SOP_USE_STATIC, new HashMap<Integer, Integer>(), converted.code.visitCode(converted));
|
||||
convertedItems = converted.getCode().toGraphTargetItems(path, isStatic, scriptIndex, classIndex, abc, constants, method_info, converted, localRegNames, scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits, Graph.SOP_USE_STATIC, new HashMap<Integer, Integer>(), converted.getCode().visitCode(converted));
|
||||
Graph.graphToString(convertedItems, writer, LocalData.create(constants, localRegNames, fullyQualifiedNames));
|
||||
return null;
|
||||
}
|
||||
@@ -165,7 +190,7 @@ public class MethodBody implements Cloneable, Serializable {
|
||||
|
||||
public GraphTextWriter toString(final String path, ScriptExportMode exportMode, final ABC abc, final Trait trait, final ConstantPool constants, final List<MethodInfo> method_info, final GraphTextWriter writer, final List<String> fullyQualifiedNames) throws InterruptedException {
|
||||
if (exportMode != ScriptExportMode.AS) {
|
||||
code.toASMSource(constants, trait, method_info.get(this.method_info), this, exportMode, writer);
|
||||
getCode().toASMSource(constants, trait, method_info.get(this.method_info), this, exportMode, writer);
|
||||
} else {
|
||||
if (!Configuration.decompile.get()) {
|
||||
writer.startMethod(this.method_info);
|
||||
@@ -193,7 +218,7 @@ public class MethodBody implements Cloneable, Serializable {
|
||||
|
||||
public MethodBody convertMethodBody(String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, Trait trait, ConstantPool constants, List<MethodInfo> method_info, ScopeStack scopeStack, boolean isStaticInitializer, List<String> fullyQualifiedNames, Traits initTraits) throws InterruptedException {
|
||||
MethodBody b = Helper.deepCopy(this);
|
||||
AVM2Code deobfuscated = b.code;
|
||||
AVM2Code deobfuscated = b.getCode();
|
||||
deobfuscated.markMappedOffsets();
|
||||
if (Configuration.autoDeobfuscate.get()) {
|
||||
try {
|
||||
@@ -224,7 +249,7 @@ public class MethodBody implements Cloneable, Serializable {
|
||||
|
||||
public boolean autoFillStats(ABC abc, int initScope, boolean hasThis) {
|
||||
//System.out.println("--------------");
|
||||
CodeStats stats = code.getStats(abc, this, initScope);
|
||||
CodeStats stats = getCode().getStats(abc, this, initScope);
|
||||
if (stats == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public class MethodInfo {
|
||||
public void delete(ABC abc, boolean d) {
|
||||
this.deleted = true;
|
||||
if (body != null) {
|
||||
for (AVM2Instruction ins : body.code.code) {
|
||||
for (AVM2Instruction ins : body.getCode().code) {
|
||||
if (ins.definition instanceof NewFunctionIns) {
|
||||
abc.method_info.get(ins.operands[0]).delete(abc, d);
|
||||
}
|
||||
@@ -269,7 +269,7 @@ public class MethodInfo {
|
||||
public GraphTextWriter getParamStr(GraphTextWriter writer, ConstantPool constants, MethodBody body, ABC abc, List<String> fullyQualifiedNames) {
|
||||
HashMap<Integer, String> localRegNames = new HashMap<>();
|
||||
if (body != null) {
|
||||
localRegNames = body.code.getLocalRegNamesFromDebug(abc);
|
||||
localRegNames = body.getCode().getLocalRegNamesFromDebug(abc);
|
||||
}
|
||||
for (int i = 0; i < param_types.length; i++) {
|
||||
if (i > 0) {
|
||||
|
||||
@@ -266,7 +266,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
|
||||
for (ABCException ex : body.exceptions) {
|
||||
parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(ex.type_index), ignorePackage, fullyQualifiedNames);
|
||||
}
|
||||
for (AVM2Instruction ins : body.code.code) {
|
||||
for (AVM2Instruction ins : body.getCode().code) {
|
||||
if (ins.definition instanceof NewFunctionIns) {
|
||||
if (ins.operands[0] != method_index) {
|
||||
if (!visitedMethods.contains(ins.operands[0])) {
|
||||
|
||||
Reference in New Issue
Block a user