mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-25 04:11:13 +00:00
AS3: Larger classes support
SetSlot fix
This commit is contained in:
@@ -477,17 +477,17 @@ public class ABC {
|
||||
if (!s.contains("\r\n")) {
|
||||
parts = s.split("\n");
|
||||
}
|
||||
String ret = "";
|
||||
StringBuilder ret = new StringBuilder();
|
||||
for (int i = 0; i < parts.length; i++) {
|
||||
for (int t = 0; t < tabs; t++) {
|
||||
ret += IDENT_STRING;
|
||||
ret.append(IDENT_STRING);
|
||||
}
|
||||
ret += parts[i];
|
||||
ret.append(parts[i]);
|
||||
if (i < parts.length - 1) {
|
||||
ret += "\r\n";
|
||||
ret.append("\r\n");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
public Trait findTraitByTraitId(int classIndex, int traitId) {
|
||||
|
||||
@@ -704,11 +704,11 @@ public class AVM2Code implements Serializable {
|
||||
|
||||
public String toASMSource(ConstantPool constants, MethodBody body, List<Integer> outputMap) {
|
||||
invalidateCache();
|
||||
String ret = "";
|
||||
StringBuffer ret = new StringBuffer();
|
||||
String t = "";
|
||||
for (int e = 0; e < body.exceptions.length; e++) {
|
||||
ret += "exception " + e + " m[" + body.exceptions[e].name_index + "]\"" + Helper.escapeString(body.exceptions[e].getVarName(constants, new ArrayList<String>())) + "\" "
|
||||
+ "m[" + body.exceptions[e].type_index + "]\"" + Helper.escapeString(body.exceptions[e].getTypeName(constants, new ArrayList<String>())) + "\"\n";
|
||||
ret.append("exception " + e + " m[" + body.exceptions[e].name_index + "]\"" + Helper.escapeString(body.exceptions[e].getVarName(constants, new ArrayList<String>())) + "\" "
|
||||
+ "m[" + body.exceptions[e].type_index + "]\"" + Helper.escapeString(body.exceptions[e].getTypeName(constants, new ArrayList<String>())) + "\"\n");
|
||||
}
|
||||
List<Long> offsets = new ArrayList<Long>();
|
||||
for (AVM2Instruction ins : code) {
|
||||
@@ -728,21 +728,23 @@ public class AVM2Code implements Serializable {
|
||||
}
|
||||
long ofs = 0;
|
||||
int ip = 0;
|
||||
int largeLimit = 20000;
|
||||
boolean markOffsets=code.size()<=largeLimit;
|
||||
for (AVM2Instruction ins : code) {
|
||||
if (ins.labelname != null) {
|
||||
ret += ins.labelname + ":";
|
||||
ret.append(ins.labelname + ":");
|
||||
} else if (offsets.contains(ofs)) {
|
||||
ret += "ofs" + Helper.formatAddress(ofs) + ":";
|
||||
ret.append("ofs" + Helper.formatAddress(ofs) + ":");
|
||||
}
|
||||
for (int e = 0; e < body.exceptions.length; e++) {
|
||||
if (body.exceptions[e].start == ofs) {
|
||||
ret += "exceptionstart " + e + ":";
|
||||
ret.append("exceptionstart " + e + ":");
|
||||
}
|
||||
if (body.exceptions[e].end == ofs) {
|
||||
ret += "exceptionend " + e + ":";
|
||||
ret.append("exceptionend " + e + ":");
|
||||
}
|
||||
if (body.exceptions[e].target == ofs) {
|
||||
ret += "exceptiontarget " + e + ":";
|
||||
ret.append("exceptiontarget " + e + ":");
|
||||
}
|
||||
}
|
||||
if (ins.replaceWith != null) {
|
||||
@@ -753,36 +755,40 @@ public class AVM2Code implements Serializable {
|
||||
continue;
|
||||
}
|
||||
t = Highlighting.hilighOffset("", ins2.mappedOffset>-1?ins2.mappedOffset:ofs) + ins2.toStringNoAddress(constants, new ArrayList<String>()) + " ;copy from " + Helper.formatAddress(pos2adr((Integer) o)) + "\n";
|
||||
ret += t;
|
||||
ret.append(t);
|
||||
outputMap.add((Integer) o);
|
||||
} else if (o instanceof ControlFlowTag) {
|
||||
ControlFlowTag cft = (ControlFlowTag) o;
|
||||
if (cft.name.equals("appendjump")) {
|
||||
t = "jump ofs" + Helper.formatAddress(pos2adr(cft.value)) + "\n";
|
||||
ret += t;
|
||||
ret.append(t);
|
||||
outputMap.add(-1);
|
||||
}
|
||||
if (cft.name.equals("mark")) {
|
||||
ret += "ofs" + Helper.formatAddress(pos2adr(cft.value)) + ":";
|
||||
ret.append("ofs" + Helper.formatAddress(pos2adr(cft.value)) + ":");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!ins.isIgnored()) {
|
||||
String t1 = ins.toStringNoAddress(constants, new ArrayList<String>());
|
||||
t = ins.toStringNoAddress(constants, new ArrayList<String>());
|
||||
if (ins.changeJumpTo > -1) {
|
||||
t1 = ins.definition.instructionName + " ofs" + Helper.formatAddress(pos2adr(ins.changeJumpTo));
|
||||
t = ins.definition.instructionName + " ofs" + Helper.formatAddress(pos2adr(ins.changeJumpTo));
|
||||
}
|
||||
t = Highlighting.hilighOffset("", ins.mappedOffset>-1?ins.mappedOffset:ofs) + t1 + "\n";
|
||||
ret += t;
|
||||
if(markOffsets){
|
||||
t = Highlighting.hilighOffset("", ins.mappedOffset>-1?ins.mappedOffset:ofs) + t + "\n";
|
||||
}else{
|
||||
t = t + "\n";
|
||||
}
|
||||
ret.append(t);
|
||||
outputMap.add(ip);
|
||||
}
|
||||
}
|
||||
ofs += ins.getBytes().length;
|
||||
ip++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
String r=ret.toString();
|
||||
return r;
|
||||
}
|
||||
private boolean cacheActual = false;
|
||||
private List<Long> posCache;
|
||||
@@ -821,12 +827,12 @@ public class AVM2Code implements Serializable {
|
||||
}
|
||||
|
||||
public static String listToString(List<TreeItem> stack, ConstantPool constants, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
String ret = "";
|
||||
StringBuffer ret = new StringBuffer();
|
||||
for (int d = 0; d < stack.size(); d++) {
|
||||
TreeItem o = stack.get(d);
|
||||
ret += o.toStringSemicoloned(constants, localRegNames, fullyQualifiedNames) + "\r\n";
|
||||
ret.append(o.toStringSemicoloned(constants, localRegNames, fullyQualifiedNames) + "\r\n");
|
||||
}
|
||||
return ret;
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
private static String innerStackToString(List stack) {
|
||||
@@ -1897,6 +1903,7 @@ public class AVM2Code implements Serializable {
|
||||
try{
|
||||
list = Graph.translateViaGraph(path,this, abc, body);
|
||||
}catch(Exception ex2){
|
||||
Logger.getLogger(AVM2Code.class.getName()).log(Level.SEVERE, "Decompilation error in "+path,ex2);
|
||||
return "/*\r\n * Decompilation error\r\n * Code may be obfuscated\r\n * Error Message: " + ex2.getMessage() + "\r\n */";
|
||||
}
|
||||
/*try{
|
||||
@@ -1985,7 +1992,7 @@ public class AVM2Code implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
s = listToString(list, constants, localRegNames, fullyQualifiedNames);
|
||||
s = listToString(list, constants, localRegNames, fullyQualifiedNames);
|
||||
/*} catch (Exception ex) {
|
||||
Logger.getLogger(AVM2Code.class.getName()).log(Level.SEVERE, "Error in method "+path, ex);
|
||||
s = "/ *\r\n * Decompilation error\r\n * Code may be obfuscated\r\n * Error Message: " + ex.getMessage() + "\r\n * /";
|
||||
@@ -1993,13 +2000,13 @@ public class AVM2Code implements Serializable {
|
||||
}*/
|
||||
|
||||
|
||||
String sub = "";
|
||||
StringBuffer sub = new StringBuffer();
|
||||
int level = 0;
|
||||
|
||||
String parts[] = s.split("\r\n");
|
||||
|
||||
boolean processLoops = true;
|
||||
|
||||
|
||||
if (processLoops) {
|
||||
try {
|
||||
Stack<String> loopStack = new Stack<String>();
|
||||
@@ -2066,20 +2073,22 @@ public class AVM2Code implements Serializable {
|
||||
level--;
|
||||
} else if (strippedP.equals("{")) {
|
||||
level++;
|
||||
sub += tabString(level) + parts[p] + "\r\n";
|
||||
sub.append(tabString(level) + parts[p] + "\r\n");
|
||||
level++;
|
||||
} else if (strippedP.equals("}") || strippedP.equals("};")) {
|
||||
level--;
|
||||
sub += tabString(level) + parts[p] + "\r\n";
|
||||
sub.append(tabString(level) + parts[p] + "\r\n");
|
||||
level--;
|
||||
} else {
|
||||
sub += tabString(level) + parts[p] + "\r\n";
|
||||
sub.append(tabString(level) + parts[p] + "\r\n");
|
||||
}
|
||||
}
|
||||
if (!hilighted) {
|
||||
sub = Highlighting.stripHilights(sub);
|
||||
return Highlighting.stripHilights(sub.toString());
|
||||
}
|
||||
return sub;
|
||||
String ret=sub.toString();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@@ -22,12 +22,14 @@ import com.jpexs.asdec.abc.avm2.ConstantPool;
|
||||
import com.jpexs.asdec.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.asdec.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.asdec.abc.avm2.instructions.SetTypeIns;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.ClassTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.DecrementTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.GetSlotTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.IncrementTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.PostDecrementTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.PostIncrementTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.SetSlotTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.ThisTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.TreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.clauses.ExceptionTreeItem;
|
||||
import com.jpexs.asdec.abc.avm2.treemodel.operations.PreDecrementTreeItem;
|
||||
@@ -50,24 +52,31 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns {
|
||||
int slotIndex = ins.operands[0];
|
||||
TreeItem value = (TreeItem) stack.pop();
|
||||
TreeItem obj = (TreeItem) stack.pop(); //scopeId
|
||||
|
||||
if (obj instanceof ExceptionTreeItem) {
|
||||
return;
|
||||
}
|
||||
//if(value.startsWith("catched ")) return;
|
||||
Multiname slotname = null;
|
||||
for (int t = 0; t < body.traits.traits.length; t++) {
|
||||
if (body.traits.traits[t] instanceof TraitSlotConst) {
|
||||
if (((TraitSlotConst) body.traits.traits[t]).slot_id == slotIndex) {
|
||||
slotname = body.traits.traits[t].getName(abc);
|
||||
}
|
||||
}
|
||||
if (obj instanceof ExceptionTreeItem) {
|
||||
slotname = constants.constant_multiname[((ExceptionTreeItem) obj).exception.name_index];
|
||||
} else if (obj instanceof ClassTreeItem) {
|
||||
slotname = ((ClassTreeItem) obj).className;
|
||||
} else if (obj instanceof ThisTreeItem) {
|
||||
slotname = ((ThisTreeItem) obj).className;
|
||||
} else {
|
||||
//if(value.startsWith("catched ")) return;
|
||||
|
||||
for (int t = 0; t < body.traits.traits.length; t++) {
|
||||
if (body.traits.traits[t] instanceof TraitSlotConst) {
|
||||
if (((TraitSlotConst) body.traits.traits[t]).slot_id == slotIndex) {
|
||||
slotname = body.traits.traits[t].getName(abc);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (localRegNames.containsValue(slotname.getName(constants, fullyQualifiedNames))) {
|
||||
return;
|
||||
};
|
||||
if (slotname != null) {
|
||||
if (localRegNames.containsValue(slotname.getName(constants, fullyQualifiedNames))) {
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
if (value.getNotCoerced() instanceof IncrementTreeItem) {
|
||||
TreeItem inside = ((IncrementTreeItem) value.getNotCoerced()).object.getThroughRegister().getNotCoerced();
|
||||
|
||||
@@ -56,6 +56,9 @@ public class SetSlotTreeItem extends TreeItem implements SetTypeTreeItem, Assign
|
||||
}
|
||||
}
|
||||
}*/
|
||||
if(slotName==null){
|
||||
return ret+"/*UnknownSlot*/";
|
||||
}
|
||||
return ret + hilight(slotName.getName(constants, fullyQualifiedNames));
|
||||
}
|
||||
|
||||
|
||||
@@ -82,6 +82,9 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL
|
||||
}
|
||||
|
||||
private boolean displayMethod(int pos, int methodIndex) {
|
||||
if(abc==null){
|
||||
return false;
|
||||
}
|
||||
int bi = abc.findBodyIndex(methodIndex);
|
||||
if (bi == -1) {
|
||||
return false;
|
||||
@@ -134,11 +137,7 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (classIndex == -1) {
|
||||
setNoTrait();
|
||||
return;
|
||||
}
|
||||
|
||||
for (Highlighting tm : methodHighlights) {
|
||||
if ((pos >= tm.startPos) && (pos < tm.startPos + tm.len)) {
|
||||
displayMethod(pos, (int) tm.offset);
|
||||
@@ -152,6 +151,11 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (classIndex == -1) {
|
||||
setNoTrait();
|
||||
return;
|
||||
}
|
||||
for (Highlighting th : traitHighlights) {
|
||||
if ((pos >= th.startPos) && (pos < th.startPos + th.len)) {
|
||||
lastTraitIndex = (int) th.offset;
|
||||
|
||||
@@ -36,7 +36,7 @@ import java.util.Stack;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class MethodBody implements Cloneable,Serializable {
|
||||
public class MethodBody implements Cloneable, Serializable {
|
||||
|
||||
public int method_info;
|
||||
public int max_stack;
|
||||
@@ -94,26 +94,33 @@ public class MethodBody implements Cloneable,Serializable {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public String toString(String path,boolean pcode, boolean isStatic, int classIndex, ABC abc, ConstantPool constants, MethodInfo method_info[], Stack<TreeItem> scopeStack, boolean isStaticInitializer, boolean hilight, List<String> fullyQualifiedNames, Traits initTraits) {
|
||||
public String toString(String path, boolean pcode, boolean isStatic, int classIndex, ABC abc, ConstantPool constants, MethodInfo method_info[], Stack<TreeItem> scopeStack, boolean isStaticInitializer, boolean hilight, List<String> fullyQualifiedNames, Traits initTraits) {
|
||||
String s = "";
|
||||
if (!Main.DO_DECOMPILE) {
|
||||
s = "//NOT DECOMPILED";
|
||||
if (hilight) {
|
||||
s = Highlighting.hilighMethod(s, this.method_info);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
if (pcode) {
|
||||
s += code.toASMSource(constants, this);
|
||||
} else {
|
||||
AVM2Code deobfuscated = null;
|
||||
MethodBody b=(MethodBody)Helper.deepCopy(this);
|
||||
MethodBody b = (MethodBody) Helper.deepCopy(this);
|
||||
deobfuscated = b.code;
|
||||
deobfuscated.markMappedOffsets();
|
||||
deobfuscated.removeTraps(constants, b);
|
||||
deobfuscated.restoreControlFlow(constants, b);
|
||||
deobfuscated.restoreControlFlow(constants, b);
|
||||
try {
|
||||
s += deobfuscated.toSource(path,isStatic, classIndex, abc, constants, method_info, b, hilight, getLocalRegNames(abc), scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits);
|
||||
s += deobfuscated.toSource(path, isStatic, classIndex, abc, constants, method_info, b, hilight, getLocalRegNames(abc), scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits);
|
||||
s = s.trim();
|
||||
if (hilight) {
|
||||
s = Highlighting.hilighMethod(s, this.method_info);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
s = "//error:" + ex.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -282,6 +282,14 @@ public class TraitClass extends Trait {
|
||||
return imports;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String convertHeader(String path, List<DoABCTag> abcTags, ABC abc, boolean isStatic, boolean pcode, int classIndex, boolean highlight, List<String> fullyQualifiedNames) {
|
||||
String classHeader = abc.instance_info[class_info].getClassHeaderStr(abc, fullyQualifiedNames);
|
||||
return classHeader;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String convert(String path,List<DoABCTag> abcTags, ABC abc, boolean isStatic, boolean pcode, int classIndex, boolean highlight, List<String> fullyQualifiedNames) {
|
||||
if (!highlight) {
|
||||
|
||||
@@ -56,6 +56,7 @@ public class Traits implements Serializable{
|
||||
s += "\r\n\r\n";
|
||||
}
|
||||
String plus;
|
||||
//System.out.println(path+":"+traits[t].convertHeader(path, abcTags, abc, isStatic, pcode, classIndex, highlighting, fullyQualifiedNames));
|
||||
if (makePackages) {
|
||||
plus = traits[t].convertPackaged(path,abcTags, abc, isStatic, pcode, classIndex, highlighting, fullyQualifiedNames);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user