mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-18 16:38:08 +00:00
restorecontrolflow removed
This commit is contained in:
@@ -3107,7 +3107,6 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
tag.getABC().removeTraps();
|
||||
} else if (level == DeobfuscationLevel.LEVEL_RESTORE_CONTROL_FLOW) {
|
||||
tag.getABC().removeTraps();
|
||||
tag.getABC().restoreControlFlow();
|
||||
}
|
||||
|
||||
((Tag) tag).setModified(true);
|
||||
|
||||
@@ -197,12 +197,6 @@ public class ABC {
|
||||
return rem;
|
||||
}
|
||||
|
||||
public void restoreControlFlow() throws InterruptedException {
|
||||
for (MethodBody body : bodies) {
|
||||
body.restoreControlFlow(constants, null/*FIXME*/, method_info.get(body.method_info));
|
||||
}
|
||||
}
|
||||
|
||||
public Set<Integer> getNsStringUsages() {
|
||||
Set<Integer> ret = new HashSet<>();
|
||||
for (int n = 1; n < constants.getNamespaceCount(); n++) {
|
||||
|
||||
@@ -256,8 +256,6 @@ import com.jpexs.decompiler.flash.abc.avm2.model.WithAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.DeclarationAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForEachInAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForInAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.pcode.ASM3Parser;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.PropertyAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.Reference;
|
||||
import com.jpexs.decompiler.flash.abc.types.ABCException;
|
||||
@@ -296,7 +294,6 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -1045,14 +1042,6 @@ public class AVM2Code implements Cloneable {
|
||||
}
|
||||
}
|
||||
|
||||
public void markMappedOffsets() {
|
||||
int ofs = 0;
|
||||
for (int i = 0; i < code.size(); i++) {
|
||||
code.get(i).mappedOffset = ofs;
|
||||
ofs += code.get(i).getBytesLength();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder s = new StringBuilder();
|
||||
@@ -1263,44 +1252,17 @@ public class AVM2Code implements Cloneable {
|
||||
ret.append("exceptiontarget " + e + ":");
|
||||
}
|
||||
}*/
|
||||
if (ins.replaceWith != null) {
|
||||
for (Object o : ins.replaceWith) {
|
||||
if (o instanceof Integer) {
|
||||
AVM2Instruction ins2 = code.get((Integer) o);
|
||||
if (ins2.isIgnored()) {
|
||||
continue;
|
||||
}
|
||||
writer.append("", ins2.mappedOffset > -1 ? ins2.mappedOffset : ofs);
|
||||
writer.appendNoHilight(ins2.toStringNoAddress(constants, new ArrayList<>()) + " ;copy from " + Helper.formatAddress(pos2adr((Integer) o)));
|
||||
writer.newLine();
|
||||
outputMap.add((Integer) o);
|
||||
} else if (o instanceof ControlFlowTag) {
|
||||
ControlFlowTag cft = (ControlFlowTag) o;
|
||||
if (cft.name.equals("appendjump")) {
|
||||
writer.appendNoHilight("jump ofs" + Helper.formatAddress(pos2adr(cft.value))).newLine();
|
||||
outputMap.add(-1);
|
||||
}
|
||||
if (cft.name.equals("mark")) {
|
||||
writer.appendNoHilight("ofs" + Helper.formatAddress(pos2adr(cft.value)) + ":");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!ins.isIgnored()) {
|
||||
if (markOffsets) {
|
||||
writer.append("", ins.mappedOffset > -1 ? ins.mappedOffset : ofs);
|
||||
}
|
||||
|
||||
if (ins.changeJumpTo > -1) {
|
||||
writer.appendNoHilight(ins.definition.instructionName + " ofs" + Helper.formatAddress(pos2adr(ins.changeJumpTo)));
|
||||
} else {
|
||||
writer.appendNoHilight(ins.toStringNoAddress(constants, new ArrayList<>()));
|
||||
}
|
||||
|
||||
writer.newLine();
|
||||
outputMap.add(ip);
|
||||
if (!ins.isIgnored()) {
|
||||
if (markOffsets) {
|
||||
writer.append("", ofs);
|
||||
}
|
||||
|
||||
writer.appendNoHilight(ins.toStringNoAddress(constants, new ArrayList<>()));
|
||||
writer.newLine();
|
||||
outputMap.add(ip);
|
||||
}
|
||||
|
||||
ip++;
|
||||
}
|
||||
} else if (exportMode == ScriptExportMode.CONSTANTS) {
|
||||
@@ -1322,16 +1284,6 @@ public class AVM2Code implements Cloneable {
|
||||
|
||||
for (AVM2Instruction ins : code) {
|
||||
ret.addAll(ins.getOffsets());
|
||||
if (ins.replaceWith != null) {
|
||||
for (Object o : ins.replaceWith) {
|
||||
if (o instanceof ControlFlowTag) {
|
||||
ControlFlowTag cft = (ControlFlowTag) o;
|
||||
if (cft.name.equals("appendjump")) {
|
||||
ret.add((long) pos2adr(cft.value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -2538,163 +2490,6 @@ public class AVM2Code implements Cloneable {
|
||||
return refs;
|
||||
}
|
||||
|
||||
private static class ControlFlowTag {
|
||||
|
||||
public String name;
|
||||
|
||||
public int value;
|
||||
|
||||
public ControlFlowTag(String name, int value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private void restoreControlFlow(int ip, HashMap<Integer, List<Integer>> refs, int[] visited2, HashMap<Integer, List<Object>> appended) throws ConvertException {
|
||||
List<Object> buf = new ArrayList<>();
|
||||
boolean cont = false;
|
||||
int continueip;
|
||||
for (; ip < code.size(); ip++) {
|
||||
AVM2Instruction ins = code.get(ip);
|
||||
|
||||
if ((refs.containsKey(ip) && refs.get(ip).size() > 1) || (visited2[ip] > 0)) {
|
||||
if (cont) {
|
||||
buf.add(new ControlFlowTag("appendjump", ip));
|
||||
}
|
||||
cont = false;
|
||||
if (visited2[ip] > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
visited2[ip]++;
|
||||
if (ins.definition instanceof LookupSwitchIns) {
|
||||
|
||||
if (cont) {
|
||||
buf.add(new ControlFlowTag("appendjump", ip));
|
||||
}
|
||||
//cont = false;
|
||||
restoreControlFlow(adr2pos(pos2adr(ip) + ins.operands[0]), refs, visited2, appended);
|
||||
for (int i = 2; i < ins.operands.length; i++) {
|
||||
restoreControlFlow(adr2pos(pos2adr(ip) + ins.operands[i]), refs, visited2, appended);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (ins.definition instanceof JumpIns) {
|
||||
int newip = adr2pos(pos2adr(ip + 1) + ins.operands[0]);
|
||||
|
||||
boolean allJumpsOrIfs = true;
|
||||
for (int ref : refs.get(ip)) {
|
||||
if (ref < 0) {
|
||||
continue;
|
||||
}
|
||||
if (!(code.get(ref).definition instanceof JumpIns)) {
|
||||
if (!(code.get(ref).definition instanceof IfTypeIns)) {
|
||||
allJumpsOrIfs = false;
|
||||
break;
|
||||
} else {
|
||||
if (adr2pos(pos2adr(ref + 1) + code.get(ref).operands[0]) != ip) {
|
||||
allJumpsOrIfs = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (allJumpsOrIfs) {
|
||||
for (int ref : refs.get(ip)) {
|
||||
if (ref < 0) {
|
||||
continue;
|
||||
}
|
||||
code.get(ref).changeJumpTo = newip;
|
||||
}
|
||||
}
|
||||
if ((newip < code.size()) && (refs.containsKey(newip) && refs.get(newip).size() == 1)) {
|
||||
if (!cont) {
|
||||
continueip = ip;
|
||||
buf = new ArrayList<>();
|
||||
appended.put(continueip, buf);
|
||||
}
|
||||
cont = true;
|
||||
} else {
|
||||
if (cont) {
|
||||
buf.add(new ControlFlowTag("appendjump", newip));
|
||||
}
|
||||
cont = false;
|
||||
}
|
||||
ip = newip - 1;
|
||||
} else if (ins.definition instanceof IfTypeIns) {
|
||||
int newip = adr2pos(pos2adr(ip + 1) + ins.operands[0]);
|
||||
if (cont) {
|
||||
buf.add(new ControlFlowTag("appendjump", ip));
|
||||
}
|
||||
cont = false;
|
||||
restoreControlFlow(newip, refs, visited2, appended);
|
||||
} else if ((ins.definition instanceof ReturnVoidIns) || (ins.definition instanceof ReturnValueIns) || (ins.definition instanceof ThrowIns)) {
|
||||
if (cont) {
|
||||
buf.add(ip);
|
||||
}
|
||||
break;
|
||||
} else if (cont) {
|
||||
buf.add(ip);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void restoreControlFlowPass(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body) throws InterruptedException {
|
||||
try {
|
||||
HashMap<Integer, List<Integer>> refs;
|
||||
int[] visited2 = new int[code.size()];
|
||||
refs = visitCode(body);
|
||||
HashMap<Integer, List<Object>> appended = new HashMap<>();
|
||||
|
||||
restoreControlFlow(0, refs, visited2, appended);
|
||||
for (ABCException e : body.exceptions) {
|
||||
try {
|
||||
restoreControlFlow(adr2pos(e.start, true), refs, visited2, appended);
|
||||
restoreControlFlow(adr2pos(e.target), refs, visited2, appended);
|
||||
restoreControlFlow(adr2pos(e.end, true), refs, visited2, appended);
|
||||
} catch (ConvertException ex) {
|
||||
logger.log(Level.FINE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
for (int ip : appended.keySet()) {
|
||||
code.get(ip).replaceWith = appended.get(ip);
|
||||
}
|
||||
} catch (ConvertException cex) {
|
||||
logger.log(Level.SEVERE, "Error during restore control flow", cex);
|
||||
}
|
||||
try {
|
||||
List<Integer> outputMap = new ArrayList<>();
|
||||
HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false);
|
||||
toASMSource(constants, trait, info, body, outputMap, ScriptExportMode.PCODE, writer);
|
||||
String src = writer.toString();
|
||||
|
||||
AVM2Code acode = ASM3Parser.parse(new StringReader(src), constants, null, body, info);
|
||||
for (int i = 0; i < acode.code.size(); i++) {
|
||||
if (outputMap.size() > i) {
|
||||
int tpos = outputMap.get(i);
|
||||
if (tpos == -1) {
|
||||
} else if (code.get(tpos).mappedOffset >= 0) {
|
||||
acode.code.get(i).mappedOffset = code.get(tpos).mappedOffset;
|
||||
} else {
|
||||
acode.code.get(i).mappedOffset = pos2adr(tpos);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.code = acode.code;
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.SEVERE, null, ex);
|
||||
} catch (AVM2ParseException ex) {
|
||||
logger.log(Level.FINE, null, ex);
|
||||
}
|
||||
removeDeadCode(body);
|
||||
}
|
||||
|
||||
public void restoreControlFlow(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body) throws InterruptedException {
|
||||
restoreControlFlowPass(constants, trait, info, body);
|
||||
}
|
||||
|
||||
public void removeIgnored(MethodBody body) throws InterruptedException {
|
||||
//System.err.println("removing ignored...");
|
||||
for (int i = 0; i < code.size(); i++) {
|
||||
|
||||
@@ -53,12 +53,6 @@ public class AVM2Instruction implements Cloneable, GraphSourceItem {
|
||||
|
||||
private boolean ignored = false;
|
||||
|
||||
public long mappedOffset = -1;
|
||||
|
||||
public int changeJumpTo = -1;
|
||||
|
||||
public List<Object> replaceWith;
|
||||
|
||||
private int line;
|
||||
|
||||
private String file;
|
||||
@@ -378,7 +372,7 @@ public class AVM2Instruction implements Cloneable, GraphSourceItem {
|
||||
|
||||
@Override
|
||||
public long getOffset() {
|
||||
return mappedOffset > -1 ? mappedOffset : offset;
|
||||
return offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -91,7 +91,6 @@ import com.jpexs.decompiler.graph.model.TernarOpItem;
|
||||
import com.jpexs.decompiler.graph.model.TrueItem;
|
||||
import com.jpexs.decompiler.graph.model.UnboundedTypeItem;
|
||||
import com.jpexs.decompiler.graph.model.WhileItem;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.jpexs.decompiler.flash.SWC;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.ApplyTypeAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.BooleanAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.CoerceAVM2Item;
|
||||
@@ -38,7 +37,6 @@ import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.NameValuePair;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.NanAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.NewArrayAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.NewFunctionAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.NewObjectAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item;
|
||||
@@ -2486,12 +2484,9 @@ public class ActionScript3Parser {
|
||||
addScriptFromTree(allOpenedNamespaces, traits, documentClass, classPos);
|
||||
}
|
||||
|
||||
public ActionScript3Parser(ABC abc, List<ABC> otherAbcs) {
|
||||
try {
|
||||
initPlayer();
|
||||
} catch (IOException | InterruptedException ex) {
|
||||
public ActionScript3Parser(ABC abc, List<ABC> otherAbcs) throws IOException, InterruptedException {
|
||||
initPlayer();
|
||||
|
||||
}
|
||||
abcIndex = new AbcIndexing(playerGlobalAbcIndex);
|
||||
for (ABC a : otherAbcs) {
|
||||
abcIndex.addAbc(a);
|
||||
|
||||
@@ -179,10 +179,6 @@ public final class MethodBody implements Cloneable {
|
||||
return getCode().removeDeadCode(this);
|
||||
}
|
||||
|
||||
public void restoreControlFlow(AVM2ConstantPool constants, Trait trait, MethodInfo info) throws InterruptedException {
|
||||
getCode().restoreControlFlow(constants, trait, info, this);
|
||||
}
|
||||
|
||||
public int removeTraps(ABC abc, Trait trait, int scriptIndex, int classIndex, boolean isStatic, String path) throws InterruptedException {
|
||||
|
||||
return getCode().removeTraps(trait, method_info, this, abc, scriptIndex, classIndex, isStatic, path);
|
||||
@@ -195,7 +191,6 @@ public final class MethodBody implements Cloneable {
|
||||
removeTraps(abc, trait, scriptIndex, classIndex, isStatic, path);
|
||||
} else if (level == DeobfuscationLevel.LEVEL_RESTORE_CONTROL_FLOW) {
|
||||
removeTraps(abc, trait, scriptIndex, classIndex, isStatic, path);
|
||||
restoreControlFlow(abc.constants, trait, abc.method_info.get(method_info));
|
||||
}
|
||||
|
||||
((Tag) abc.parentTag).setModified(true);
|
||||
@@ -383,7 +378,6 @@ public final class MethodBody implements Cloneable {
|
||||
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 {
|
||||
MethodBody body = clone();
|
||||
AVM2Code code = body.getCode();
|
||||
code.markMappedOffsets();
|
||||
code.fixJumps(path, body);
|
||||
|
||||
if (convertData.deobfuscationMode != 0) {
|
||||
@@ -396,7 +390,6 @@ public final class MethodBody implements Cloneable {
|
||||
logger.log(Level.SEVERE, "Deobfuscation failed in: " + path, ex);
|
||||
body = clone();
|
||||
code = body.getCode();
|
||||
code.markMappedOffsets();
|
||||
code.fixJumps(path, body);
|
||||
return body;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user