Fixed AS1/2 - ifFrameLoaded with nontrivial items inside

This commit is contained in:
Jindra Petřík
2021-11-28 10:32:51 +01:00
parent 526f484513
commit b3308a2599
8 changed files with 93 additions and 21 deletions

View File

@@ -82,6 +82,7 @@ import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.Graph;
import com.jpexs.decompiler.graph.GraphException;
import com.jpexs.decompiler.graph.GraphPart;
import com.jpexs.decompiler.graph.GraphPartChangeException;
import com.jpexs.decompiler.graph.GraphSource;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
@@ -239,7 +240,12 @@ public class AVM2Graph extends Graph {
AVM2LocalData localData2 = new AVM2LocalData(localData);
localData2.scopeStack = new ScopeStack();
List<GraphTargetItem> targetOutput = translatePart(localData2, finallyTryTargetPart, finallyTryTargetStack, 0 /*??*/, "try_target");
List<GraphTargetItem> targetOutput;
try {
targetOutput = translatePart(localData2, finallyTryTargetPart, finallyTryTargetStack, 0 /*??*/, "try_target");
} catch (GraphPartChangeException ex1) { //should not happen
targetOutput = new ArrayList<>();
}
int switchedReg = -1;
int finallyKind = FINALLY_KIND_UNKNOWN;
@@ -1043,8 +1049,12 @@ public class AVM2Graph extends Graph {
AVM2LocalData localData2 = new AVM2LocalData(localData);
localData2.scopeStack = new ScopeStack();
//We are assuming Finally target has only 1 part
finallyTargetItems = translatePart(localData2, finallyTryTargetPart, st2, staticOperation, path);//printGraph(foundGotos, partCodes, partCodePos, visited, localData2, st2, allParts, null, finallyTryTargetPart, finallyTargetStopPart, loops, throwStates, 0, path);
try {
//We are assuming Finally target has only 1 part
finallyTargetItems = translatePart(localData2, finallyTryTargetPart, st2, staticOperation, path);//printGraph(foundGotos, partCodes, partCodePos, visited, localData2, st2, allParts, null, finallyTryTargetPart, finallyTargetStopPart, loops, throwStates, 0, path);
} catch (GraphPartChangeException ex) { //should not happen
finallyTargetItems = new ArrayList<>();
}
//boolean targetHasThrow = false;
if (!finallyTargetItems.isEmpty() && (finallyTargetItems.get(finallyTargetItems.size() - 1) instanceof ThrowAVM2Item)) {
@@ -1132,7 +1142,11 @@ public class AVM2Graph extends Graph {
finallyCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, finallyPart, finallyStopPart, finallyStopPartKind, loops, throwStates, staticOperation, path);
}
if (switchPart != null) {
finallyCommands.addAll(translatePart(localData, switchPart, stack, staticOperation, path));
try {
finallyCommands.addAll(translatePart(localData, switchPart, stack, staticOperation, path));
} catch (GraphPartChangeException ex) {
//should not happen
}
stack.pop(); //value switched by lookupswitch
}
}
@@ -1421,17 +1435,21 @@ public class AVM2Graph extends Graph {
caseBodyParts.add(part.nextParts.get(0));
GraphTargetItem top = null;
int cnt = 1;
while (part.nextParts.size() > 1
&& part.nextParts.get(1).getHeight() > 1
&& ((AVM2Instruction) code.get(part.nextParts.get(1).end >= code.size() ? code.size() - 1 : part.nextParts.get(1).end)).definition instanceof IfStrictEqIns
&& ((top = translatePartGetStack(localData, part.nextParts.get(1), stack, staticOperation)) instanceof StrictEqAVM2Item)) {
cnt++;
part = part.nextParts.get(1);
caseBodyParts.add(part.nextParts.get(0));
try {
while (part.nextParts.size() > 1
&& part.nextParts.get(1).getHeight() > 1
&& ((AVM2Instruction) code.get(part.nextParts.get(1).end >= code.size() ? code.size() - 1 : part.nextParts.get(1).end)).definition instanceof IfStrictEqIns
&& ((top = translatePartGetStack(localData, part.nextParts.get(1), stack, staticOperation)) instanceof StrictEqAVM2Item)) {
cnt++;
part = part.nextParts.get(1);
caseBodyParts.add(part.nextParts.get(0));
set = (StrictEqAVM2Item) top;
caseValuesMapLeft.add(set.leftSide);
caseValuesMapRight.add(set.rightSide);
set = (StrictEqAVM2Item) top;
caseValuesMapLeft.add(set.leftSide);
caseValuesMapRight.add(set.rightSide);
}
} catch (GraphPartChangeException gpc) {
//ignore
}
List<GraphTargetItem> caseValuesMap = caseValuesMapLeft;
@@ -2331,5 +2349,4 @@ public class AVM2Graph extends Graph {
Graph.makeAllCommands(commands, stack);
}
}

View File

@@ -63,6 +63,7 @@ import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin;
import com.jpexs.decompiler.flash.tags.DoInitActionTag;
import com.jpexs.decompiler.flash.tags.base.ASMSource;
import com.jpexs.decompiler.graph.Graph;
import com.jpexs.decompiler.graph.GraphPartChangeException;
import com.jpexs.decompiler.graph.GraphSource;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphSourceItemContainer;
@@ -973,7 +974,7 @@ public abstract class Action implements GraphSourceItem {
this.ignored = ignored;
}
public static List<GraphTargetItem> actionsPartToTree(SecondPassData secondPassData, boolean insideDoInitAction, Reference<GraphSourceItem> fi, HashMap<Integer, String> registerNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, TranslateStack stack, List<Action> actions, int start, int end, int version, int staticOperation, String path) throws InterruptedException {
public static List<GraphTargetItem> actionsPartToTree(SecondPassData secondPassData, boolean insideDoInitAction, Reference<GraphSourceItem> fi, HashMap<Integer, String> registerNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, TranslateStack stack, List<Action> actions, int start, int end, int version, int staticOperation, String path) throws InterruptedException, GraphPartChangeException {
if (start < actions.size() && (end > 0) && (start > 0)) {
logger.log(Level.FINE, "Entering {0}-{1}{2}", new Object[]{start, end, actions.size() > 0 ? (" (" + actions.get(start).toString() + " - " + actions.get(end == actions.size() ? end - 1 : end) + ")") : ""});
}
@@ -1106,6 +1107,9 @@ public abstract class Action implements GraphSourceItem {
ip++;
}
if (ip > end + 1) {
throw new GraphPartChangeException(output, ip);
}
logger.log(Level.FINE, "Leaving {0}-{1}", new Object[]{start, end});
return output;
}

View File

@@ -50,6 +50,7 @@ import com.jpexs.decompiler.graph.AbstractGraphTargetVisitor;
import com.jpexs.decompiler.graph.Block;
import com.jpexs.decompiler.graph.Graph;
import com.jpexs.decompiler.graph.GraphPart;
import com.jpexs.decompiler.graph.GraphPartChangeException;
import com.jpexs.decompiler.graph.GraphSource;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphSourceItemContainer;
@@ -455,6 +456,7 @@ public class ActionGraph extends Graph {
int cnt = 1;
if (!secondSwitchFound) {
try {
while (part.nextParts.size() > 1
&& part.nextParts.get(1).getHeight() > 1
&& code.get(part.nextParts.get(1).end >= code.size() ? code.size() - 1 : part.nextParts.get(1).end) instanceof ActionIf
@@ -465,6 +467,9 @@ public class ActionGraph extends Graph {
set = (StrictEqActionItem) top;
caseValuesMap.add(set.rightSide);
}
} catch (GraphPartChangeException gce) {
//ignore
}
}
if (!secondSwitchFound && cnt == 1) {

View File

@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.action;
import com.jpexs.decompiler.flash.BaseLocalData;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.graph.GraphPart;
import com.jpexs.decompiler.graph.GraphPartChangeException;
import com.jpexs.decompiler.graph.GraphSource;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
@@ -99,7 +100,7 @@ public class ActionGraphSource extends GraphSource {
}
@Override
public List<GraphTargetItem> translatePart(GraphPart part, BaseLocalData localData, TranslateStack stack, int start, int end, int staticOperation, String path) throws InterruptedException {
public List<GraphTargetItem> translatePart(GraphPart part, BaseLocalData localData, TranslateStack stack, int start, int end, int staticOperation, String path) throws InterruptedException, GraphPartChangeException {
Reference<GraphSourceItem> fi = new Reference<>(localData.lineStartInstruction);
List<GraphTargetItem> r = Action.actionsPartToTree(localData.secondPassData, this.insideDoInitAction, fi, registerNames, variables, functions, stack, actions, start, end, version, staticOperation, path);

View File

@@ -1290,13 +1290,13 @@ public class Graph {
}
//@SuppressWarnings("unchecked")
protected GraphTargetItem translatePartGetStack(BaseLocalData localData, GraphPart part, TranslateStack stack, int staticOperation) throws InterruptedException {
protected GraphTargetItem translatePartGetStack(BaseLocalData localData, GraphPart part, TranslateStack stack, int staticOperation) throws InterruptedException, GraphPartChangeException {
stack = (TranslateStack) stack.clone();
translatePart(localData, part, stack, staticOperation, null);
return stack.pop();
}
protected List<GraphTargetItem> translatePart(BaseLocalData localData, GraphPart part, TranslateStack stack, int staticOperation, String path) throws InterruptedException {
protected List<GraphTargetItem> translatePart(BaseLocalData localData, GraphPart part, TranslateStack stack, int staticOperation, String path) throws InterruptedException, GraphPartChangeException {
List<GraphPart> sub = part.getSubParts();
List<GraphTargetItem> ret = new ArrayList<>();
int end;
@@ -2075,7 +2075,24 @@ public class Graph {
if (checkPartOutput(currentRet, foundGotos, partCodes, partCodePos, visited, code, localData, allParts, stack, parent, part, stopPart, stopPartKind, loops, throwStates, currentLoop, staticOperation, path, recursionLevel)) {
parseNext = false;
} else {
output.addAll(code.translatePart(part, localData, stack, part.start, part.end, staticOperation, path));
boolean exHappened = false;
int ipStart = part.start;
do {
exHappened = false;
try {
output.addAll(code.translatePart(part, localData, stack, ipStart, part.end, staticOperation, path));
} catch (GraphPartChangeException ex) { //Special case for ifFrameLoaded when it's over multiple parts
output.addAll(ex.getOutput());
for (GraphPart p : allParts) {
if (p.containsIP(ex.getIp())) {
exHappened = true;
ipStart = ex.getIp();
part = p;
break;
}
}
}
} while (exHappened);
if ((part.end >= code.size() - 1) && getNextParts(localData, part).isEmpty()) {
output.add(new ScriptEndItem());
}

View File

@@ -0,0 +1,27 @@
package com.jpexs.decompiler.graph;
import java.util.List;
/**
*
* @author JPEXS
*/
public class GraphPartChangeException extends Exception {
private final int ip;
private final List<GraphTargetItem> output;
public GraphPartChangeException(List<GraphTargetItem> output, int ip) {
this.output = output;
this.ip = ip;
}
public int getIp() {
return ip;
}
public List<GraphTargetItem> getOutput() {
return output;
}
}

View File

@@ -36,7 +36,7 @@ public abstract class GraphSource implements Serializable {
public abstract boolean isEmpty();
public abstract List<GraphTargetItem> translatePart(GraphPart part, BaseLocalData localData, TranslateStack stack, int start, int end, int staticOperation, String path) throws InterruptedException;
public abstract List<GraphTargetItem> translatePart(GraphPart part, BaseLocalData localData, TranslateStack stack, int start, int end, int staticOperation, String path) throws InterruptedException, GraphPartChangeException;
public abstract Set<Long> getImportantAddresses();