mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-27 14:00:43 +00:00
Fixed #1842 AS1/2 Better handling obfuscated code, for..in
This commit is contained in:
+2
-1
@@ -37,6 +37,7 @@ import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.ecma.Null;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphPart;
|
||||
import com.jpexs.decompiler.graph.GraphSource;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
@@ -290,7 +291,7 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple {
|
||||
}
|
||||
|
||||
@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(Graph graph, GraphPart part, BaseLocalData localData, TranslateStack stack, int start, int end, int staticOperation, String path) throws InterruptedException {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -298,7 +298,7 @@ public class AVM2DeobfuscatorRegistersOld extends AVM2DeobfuscatorSimpleOld {
|
||||
}
|
||||
|
||||
@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(Graph graph, GraphPart part, BaseLocalData localData, TranslateStack stack, int start, int end, int staticOperation, String path) throws InterruptedException {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
|
||||
@@ -2427,7 +2427,7 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
}
|
||||
|
||||
public static void makeAllCommands(List<GraphTargetItem> commands, TranslateStack stack) {
|
||||
public void makeAllCommands(List<GraphTargetItem> commands, TranslateStack stack) {
|
||||
for (int i = 0; i < stack.size(); i++) {
|
||||
//These are often obfuscated, so ignore them
|
||||
if (stack.get(i) instanceof NewFunctionAVM2Item) {
|
||||
@@ -2435,7 +2435,7 @@ public class AVM2Graph extends Graph {
|
||||
i--;
|
||||
}
|
||||
}
|
||||
Graph.makeAllCommands(commands, stack);
|
||||
super.makeAllCommands(commands, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.abc.avm2.ConvertOutput;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphPart;
|
||||
import com.jpexs.decompiler.graph.GraphSource;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
@@ -115,7 +116,7 @@ public class AVM2GraphSource 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(Graph graph, GraphPart part, BaseLocalData localData, TranslateStack stack, int start, int end, int staticOperation, String path) throws InterruptedException {
|
||||
List<GraphTargetItem> ret = new ArrayList<>();
|
||||
ScopeStack newstack = ((AVM2LocalData) localData).scopeStack;
|
||||
Reference<GraphSourceItem> lineStartItem = new Reference<>(localData.lineStartInstruction);
|
||||
|
||||
@@ -1010,7 +1010,7 @@ public abstract class Action implements GraphSourceItem {
|
||||
return variables2;
|
||||
}
|
||||
|
||||
public static List<GraphTargetItem> actionsPartToTree(Set<GraphPart> switchParts, 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, String charset) throws InterruptedException, GraphPartChangeException {
|
||||
public static List<GraphTargetItem> actionsPartToTree(ActionGraph graph, Set<GraphPart> switchParts, 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, String charset) 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) + ")") : ""});
|
||||
}
|
||||
@@ -1135,7 +1135,7 @@ public abstract class Action implements GraphSourceItem {
|
||||
|
||||
if (((action instanceof ActionSetTarget) || (action instanceof ActionSetTarget2)) && (!stack.isEmpty())) {
|
||||
GraphTargetItem lastItem = output.remove(output.size() - 1);
|
||||
Graph.makeAllCommands(output, stack);
|
||||
graph.makeAllCommands(output, stack);
|
||||
output.add(lastItem);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,13 +22,16 @@ import com.jpexs.decompiler.flash.SWF;
|
||||
import static com.jpexs.decompiler.flash.action.Action.adr2ip;
|
||||
import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.EnumerateActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.EnumeratedValueActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.FunctionActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.GetPropertyActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.SetTarget2ActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.SetTargetActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.SetTypeActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.SetVariableActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.StoreRegisterActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.TemporaryRegister;
|
||||
import com.jpexs.decompiler.flash.action.model.TemporaryRegisterMark;
|
||||
import com.jpexs.decompiler.flash.action.model.clauses.ForInActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.clauses.TellTargetActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.operations.NeqActionItem;
|
||||
@@ -93,7 +96,7 @@ public class ActionGraph extends Graph {
|
||||
this.insideDoInitAction = insideDoInitAction;
|
||||
this.insideFunction = insideFunction;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ActionGraphSource getGraphCode() {
|
||||
return (ActionGraphSource) code;
|
||||
@@ -121,7 +124,7 @@ public class ActionGraph extends Graph {
|
||||
|
||||
for (ActionList al : outs) {
|
||||
subgraphs.put("loc" + Helper.formatAddress(code.pos2adr(ip)) + ": function " + functionName,
|
||||
new ActionGraph("", false, false, al, new HashMap<>(), new HashMap<>(), new HashMap<>(), SWF.DEFAULT_VERSION, ((ActionGraphSource)getGraphCode()).getCharset())
|
||||
new ActionGraph("", false, false, al, new HashMap<>(), new HashMap<>(), new HashMap<>(), SWF.DEFAULT_VERSION, ((ActionGraphSource) getGraphCode()).getCharset())
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -353,29 +356,65 @@ public class ActionGraph extends Graph {
|
||||
checkedLoop = null;
|
||||
}
|
||||
}
|
||||
if (checkedBody != null && (!checkedBody.isEmpty()) && (checkedBody.get(0) instanceof SetTypeActionItem)) {
|
||||
SetTypeActionItem sti = (SetTypeActionItem) checkedBody.get(0);
|
||||
if (checkedCondition instanceof NeqActionItem) {
|
||||
NeqActionItem ne = (NeqActionItem) checkedCondition;
|
||||
if (ne.rightSide instanceof DirectValueActionItem) {
|
||||
DirectValueActionItem dv = (DirectValueActionItem) ne.rightSide;
|
||||
if (dv.value == Null.INSTANCE) {
|
||||
GraphTargetItem en = list.get(t - 1);
|
||||
if (en instanceof EnumerateActionItem) {
|
||||
EnumerateActionItem eti = (EnumerateActionItem) en;
|
||||
list.remove(t);
|
||||
checkedBody.remove(0);
|
||||
if (checkedLoop == null) {
|
||||
checkedLoop = new Loop(localData.loops.size(), null, null);
|
||||
checkedBody.add(new BreakItem(null, null, checkedLoop.id));
|
||||
|
||||
if (checkedCondition instanceof NeqActionItem) {
|
||||
NeqActionItem ne = (NeqActionItem) checkedCondition;
|
||||
if (ne.rightSide instanceof DirectValueActionItem) {
|
||||
DirectValueActionItem dv = (DirectValueActionItem) ne.rightSide;
|
||||
if (dv.value == Null.INSTANCE) {
|
||||
GraphTargetItem en = list.get(t - 1);
|
||||
if (en instanceof EnumerateActionItem) {
|
||||
EnumerateActionItem eti = (EnumerateActionItem) en;
|
||||
if (checkedCondition instanceof NeqActionItem) {
|
||||
NeqActionItem neq = (NeqActionItem) checkedCondition;
|
||||
if (neq.leftSide instanceof StoreRegisterActionItem) {
|
||||
if (checkedBody != null && (!checkedBody.isEmpty()) && (checkedBody.get(0) instanceof SetTypeActionItem)) {
|
||||
SetTypeActionItem sti = (SetTypeActionItem) checkedBody.get(0);
|
||||
|
||||
if ((sti.getValue() instanceof DirectValueActionItem) && (((DirectValueActionItem) sti.getValue()).value instanceof RegisterNumber)) {
|
||||
if ((neq.rightSide instanceof DirectValueActionItem) && (((DirectValueActionItem) neq.rightSide).value instanceof Null)) {
|
||||
if (neq.leftSide.value instanceof EnumeratedValueActionItem) {
|
||||
if (((StoreRegisterActionItem) neq.leftSide).register.number == ((RegisterNumber) (((DirectValueActionItem) sti.getValue()).value)).number) {
|
||||
list.remove(t);
|
||||
checkedBody.remove(0);
|
||||
if (checkedLoop == null) {
|
||||
checkedLoop = new Loop(localData.loops.size(), null, null);
|
||||
checkedBody.add(new BreakItem(null, null, checkedLoop.id));
|
||||
}
|
||||
sti.setValue(new DirectValueActionItem(Null.INSTANCE));
|
||||
list.add(t, new ForInActionItem(null, null, checkedLoop, (GraphTargetItem) sti, eti.object, checkedBody));
|
||||
//sti.getObject()
|
||||
list.remove(t - 1);
|
||||
t--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (checkedBody != null) {
|
||||
list.remove(t);
|
||||
if (checkedLoop == null) {
|
||||
checkedLoop = new Loop(localData.loops.size(), null, null);
|
||||
checkedBody.add(new BreakItem(null, null, checkedLoop.id));
|
||||
}
|
||||
list.remove(t - 1);
|
||||
t--;
|
||||
if (eti.object instanceof SetTypeActionItem) {
|
||||
list.add(t++, eti.object);
|
||||
eti.object = ((SetTypeActionItem)eti.object).getObject();
|
||||
}
|
||||
list.add(t, new ForInActionItem(null, null, checkedLoop, (GraphTargetItem) neq.leftSide, eti.object, checkedBody));
|
||||
if (t + 1 < list.size()) {
|
||||
if (list.get(t + 1) instanceof EnumeratedValueActionItem) {
|
||||
list.remove(t + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sti.setValue(new DirectValueActionItem(Null.INSTANCE));
|
||||
list.add(t, new ForInActionItem(null, null, checkedLoop, (GraphTargetItem) sti/*sti.getObject()*/, eti.object, checkedBody));
|
||||
list.remove(t - 1);
|
||||
t--;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -386,6 +425,44 @@ public class ActionGraph extends Graph {
|
||||
|
||||
}
|
||||
|
||||
public void makeAllCommands(List<GraphTargetItem> commands, TranslateStack stack) {
|
||||
super.makeAllCommands(commands, stack);
|
||||
//ags.getVariables()
|
||||
ActionGraphSource ags = (ActionGraphSource) code;
|
||||
for (String varName : ags.getVariables().keySet()) {
|
||||
if (varName.matches("^__register.*")) {
|
||||
GraphTargetItem varValue = ags.getVariables().get(varName);
|
||||
if (varValue instanceof TemporaryRegister) {
|
||||
TemporaryRegister tempReg = (TemporaryRegister) varValue;
|
||||
|
||||
if (!tempReg.used) {
|
||||
if (varValue.value instanceof SetTypeActionItem) {
|
||||
SetTypeActionItem st = (SetTypeActionItem) varValue.value;
|
||||
for (int i = 0; i < commands.size(); i++) {
|
||||
if (commands.get(i) instanceof TemporaryRegisterMark) {
|
||||
TemporaryRegisterMark trm = (TemporaryRegisterMark) commands.get(i);
|
||||
if (st.getValue() instanceof StoreRegisterActionItem) {
|
||||
StoreRegisterActionItem sr = (StoreRegisterActionItem) st.getValue();
|
||||
if (sr.register.number == tempReg.getRegId()) {
|
||||
sr.temporary = false;
|
||||
}
|
||||
}
|
||||
if (trm.tempReg == tempReg) {
|
||||
commands.set(i, (GraphTargetItem) st);
|
||||
ags.getVariables().put(varName, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//System.err.println(varValue.value.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphTargetItem> translate(BaseLocalData localData, int staticOperation, String path) throws InterruptedException {
|
||||
List<GraphTargetItem> ret = super.translate(localData, staticOperation, path);
|
||||
|
||||
@@ -18,6 +18,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.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphPart;
|
||||
import com.jpexs.decompiler.graph.GraphPartChangeException;
|
||||
import com.jpexs.decompiler.graph.GraphSource;
|
||||
@@ -109,10 +110,10 @@ 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, GraphPartChangeException {
|
||||
public List<GraphTargetItem> translatePart(Graph graph, 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.allSwitchParts, localData.secondPassData, this.insideDoInitAction, fi, registerNames, variables, functions, stack, actions, start, end, version, staticOperation, path, charset);
|
||||
List<GraphTargetItem> r = Action.actionsPartToTree((ActionGraph)graph, localData.allSwitchParts, localData.secondPassData, this.insideDoInitAction, fi, registerNames, variables, functions, stack, actions, start, end, version, staticOperation, path, charset);
|
||||
localData.lineStartInstruction = fi.getVal();
|
||||
return r;
|
||||
}
|
||||
|
||||
+2
-24
@@ -279,7 +279,7 @@ public class ActionScript2ClassDetector {
|
||||
}
|
||||
|
||||
private boolean checkClassContent(List<GraphTargetItem> parts, HashMap<String, GraphTargetItem> variables, int partsPos, int commandsStartPos, int commandsEndPos, List<GraphTargetItem> commands, List<String> classNamePath, String scriptPath) {
|
||||
|
||||
|
||||
try {
|
||||
|
||||
GraphTargetItem extendsOp = null;
|
||||
@@ -299,29 +299,7 @@ public class ActionScript2ClassDetector {
|
||||
StoreRegisterActionItem sr = (StoreRegisterActionItem) item;
|
||||
definedRegisters.add(sr.register.number);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Hack:
|
||||
When register is not used after setting, then FFDec discards its value,
|
||||
but the value is crucial as there is setmember, atc.
|
||||
This will bypass the situation.
|
||||
|
||||
This happens when there are no methods/vars, constructor only.
|
||||
*/
|
||||
int numr = 0;
|
||||
for (String s : variables.keySet()) {
|
||||
Matcher m = regPattern.matcher(s);
|
||||
if (m.matches()) {
|
||||
if (variables.get(s) instanceof TemporaryRegister) {
|
||||
int regId = Integer.parseInt(m.group(1));
|
||||
if (!definedRegisters.contains(regId)) {
|
||||
parts.add(partsPos + numr, variables.get(s).value);
|
||||
numr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parts.size() > partsPos) {
|
||||
item = parts.get(partsPos);
|
||||
|
||||
@@ -31,6 +31,8 @@ import java.util.Objects;
|
||||
public class TemporaryRegister extends ActionItem {
|
||||
|
||||
private final int regId;
|
||||
|
||||
public boolean used = false;
|
||||
|
||||
public TemporaryRegister(int regId, GraphTargetItem value) {
|
||||
super(value.getSrc(), value.getLineStartItem(), value.getPrecedence(), value);
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2022 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TemporaryRegisterMark extends ActionItem {
|
||||
|
||||
public TemporaryRegister tempReg;
|
||||
|
||||
public TemporaryRegisterMark(TemporaryRegister tempReg) {
|
||||
this.tempReg = tempReg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsNewLine() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsSemicolon() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReturnValue() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+6
@@ -128,7 +128,13 @@ public class ForInActionItem extends LoopActionItem implements Block {
|
||||
}
|
||||
|
||||
writer.append(" in ");
|
||||
if (enumVariable.getPrecedence() > PRECEDENCE_PRIMARY) {
|
||||
writer.append("(");
|
||||
}
|
||||
enumVariable.toString(writer, localData);
|
||||
if (enumVariable.getPrecedence() > PRECEDENCE_PRIMARY) {
|
||||
writer.append(")");
|
||||
}
|
||||
writer.append(")").startBlock();
|
||||
for (GraphTargetItem ti : commands) {
|
||||
ti.toStringSemicoloned(writer, localData).newLine();
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.jpexs.decompiler.flash.action.ActionList;
|
||||
import com.jpexs.decompiler.flash.action.LocalDataArea;
|
||||
import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.TemporaryRegister;
|
||||
import com.jpexs.decompiler.flash.action.model.TemporaryRegisterMark;
|
||||
import com.jpexs.decompiler.flash.action.model.UnresolvedConstantActionItem;
|
||||
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
|
||||
import com.jpexs.decompiler.flash.action.parser.pcode.ASMParsedSymbol;
|
||||
@@ -448,6 +449,16 @@ public class ActionPush extends Action {
|
||||
}
|
||||
}
|
||||
if (dvt.computedRegValue instanceof TemporaryRegister) {
|
||||
((TemporaryRegister)dvt.computedRegValue).used = true;
|
||||
for(int i = 0; i < output.size(); i++) {
|
||||
if(output.get(i) instanceof TemporaryRegisterMark) {
|
||||
TemporaryRegisterMark trm = (TemporaryRegisterMark)output.get(i);
|
||||
if(trm.tempReg == dvt.computedRegValue) {
|
||||
output.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
stack.push(new TemporaryRegister(((RegisterNumber) o).number, ((TemporaryRegister) dvt.computedRegValue).value));
|
||||
} else {
|
||||
stack.push(dvt);
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.jpexs.decompiler.flash.action.model.PostIncrementActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.SetPropertyActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.StoreRegisterActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.TemporaryRegister;
|
||||
import com.jpexs.decompiler.flash.action.model.TemporaryRegisterMark;
|
||||
import com.jpexs.decompiler.flash.action.model.operations.PreDecrementActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.operations.PreIncrementActionItem;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
|
||||
@@ -164,7 +165,9 @@ public class ActionSetProperty extends Action {
|
||||
sr.temporary = true;
|
||||
((SetPropertyActionItem) ret).setValue(sr);
|
||||
}
|
||||
variables.put("__register" + sr.register.number, new TemporaryRegister(sr.register.number, ret));
|
||||
TemporaryRegister tr = new TemporaryRegister(sr.register.number, ret);
|
||||
variables.put("__register" + sr.register.number, tr);
|
||||
output.add(new TemporaryRegisterMark(tr));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.jpexs.decompiler.flash.action.model.PostIncrementActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.SetVariableActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.StoreRegisterActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.TemporaryRegister;
|
||||
import com.jpexs.decompiler.flash.action.model.TemporaryRegisterMark;
|
||||
import com.jpexs.decompiler.flash.action.model.operations.PreDecrementActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.operations.PreIncrementActionItem;
|
||||
import com.jpexs.decompiler.flash.ecma.EcmaScript;
|
||||
@@ -172,7 +173,9 @@ public class ActionSetVariable extends Action implements StoreTypeAction {
|
||||
((SetVariableActionItem) ret).setValue(sr);
|
||||
}
|
||||
|
||||
variables.put("__register" + sr.register.number, new TemporaryRegister(sr.register.number, ret));
|
||||
TemporaryRegister tr = new TemporaryRegister(sr.register.number, ret);
|
||||
variables.put("__register" + sr.register.number, tr);
|
||||
output.add(new TemporaryRegisterMark(tr));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.jpexs.decompiler.flash.action.model.PostIncrementActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.SetMemberActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.StoreRegisterActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.TemporaryRegister;
|
||||
import com.jpexs.decompiler.flash.action.model.TemporaryRegisterMark;
|
||||
import com.jpexs.decompiler.flash.action.model.operations.PreDecrementActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.operations.PreIncrementActionItem;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
|
||||
@@ -156,7 +157,9 @@ public class ActionSetMember extends Action {
|
||||
sr.temporary = true;
|
||||
((SetMemberActionItem) ret).setValue(sr);
|
||||
}
|
||||
variables.put("__register" + sr.register.number, new TemporaryRegister(sr.register.number, ret));
|
||||
TemporaryRegister tr = new TemporaryRegister(sr.register.number, ret);
|
||||
variables.put("__register" + sr.register.number, tr);
|
||||
output.add(new TemporaryRegisterMark(tr));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -161,7 +161,9 @@ public class ActionStoreRegister extends Action implements StoreTypeAction {
|
||||
}
|
||||
|
||||
if ((value instanceof EnumeratedValueActionItem)) {
|
||||
variables.put("__register" + registerNumber, new TemporaryRegister(registerNumber, new EnumerationAssignmentValueActionItem()));
|
||||
//variables.put("__register" + registerNumber, new TemporaryRegister(registerNumber, new EnumerationAssignmentValueActionItem()));
|
||||
//variables.put("__register" + registerNumber, null);
|
||||
variables.remove("__register" + registerNumber);
|
||||
}
|
||||
StoreRegisterActionItem ret = new StoreRegisterActionItem(this, lineStartAction, rn, value, define);
|
||||
if (value.getNotCoercedNoDup() instanceof CompoundableBinaryOp) {
|
||||
|
||||
@@ -1485,7 +1485,7 @@ public class Graph {
|
||||
}
|
||||
end = p.end;
|
||||
int start = p.start;
|
||||
ret.addAll(code.translatePart(part, localData, stack, start, end, staticOperation, path));
|
||||
ret.addAll(code.translatePart(this, part, localData, stack, start, end, staticOperation, path));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -2039,6 +2039,7 @@ public class Graph {
|
||||
}
|
||||
|
||||
protected List<GraphTargetItem> printGraph(List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, Set<GraphPart> visited, BaseLocalData localData, TranslateStack stack, Set<GraphPart> allParts, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<StopPartKind> stopPartKind, List<Loop> loops, List<ThrowState> throwStates, List<GraphTargetItem> ret, int staticOperation, String path, int recursionLevel) throws InterruptedException {
|
||||
loopPrintGraph:while(true) {
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
@@ -2273,7 +2274,7 @@ public class Graph {
|
||||
do {
|
||||
exHappened = false;
|
||||
try {
|
||||
output.addAll(code.translatePart(part, localData, stack, ipStart, part.end, staticOperation, path));
|
||||
output.addAll(code.translatePart(this, 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) {
|
||||
@@ -2282,7 +2283,8 @@ public class Graph {
|
||||
currentRet.addAll(output);
|
||||
//to check for stopparts,etc. we need to call printGraph again
|
||||
part = p;
|
||||
return printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, parent, part, stopPart, stopPartKind, loops, throwStates, ret, staticOperation, path, recursionLevel);
|
||||
//return printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, parent, part, stopPart, stopPartKind, loops, throwStates, ret, staticOperation, path, recursionLevel);
|
||||
continue loopPrintGraph;
|
||||
}
|
||||
exHappened = true;
|
||||
ipStart = ex.getIp();
|
||||
@@ -2932,7 +2934,8 @@ public class Graph {
|
||||
printGraph(foundGotos, partCodes, partCodePos, visited, localData, sPreLoop, allParts, part, currentLoop.loopBreak, stopPart, stopPartKind, loops, throwStates, ret, staticOperation, path, recursionLevel + 1);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3169,8 +3172,8 @@ public class Graph {
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
public static void makeAllCommands(List<GraphTargetItem> commands, TranslateStack stack) {
|
||||
|
||||
public void makeAllCommands(List<GraphTargetItem> commands, TranslateStack stack) {
|
||||
int clen = commands.size();
|
||||
boolean isExit = false;
|
||||
if (clen > 0) {
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -73,11 +74,10 @@ public class GraphPart implements Serializable {
|
||||
public int finishedTime;
|
||||
|
||||
public int order;
|
||||
|
||||
|
||||
public int numBlocks = Integer.MAX_VALUE;
|
||||
|
||||
//public List<GraphPart> throwParts = new ArrayList<>();
|
||||
|
||||
public enum StopPartType {
|
||||
|
||||
NONE, AND_OR, COMMONPART
|
||||
@@ -125,7 +125,7 @@ public class GraphPart implements Serializable {
|
||||
ordered.add(this);
|
||||
return time;
|
||||
}
|
||||
|
||||
|
||||
public void setNumblocks(int numBlocks) {
|
||||
this.numBlocks = numBlocks;
|
||||
numBlocks++;
|
||||
@@ -133,7 +133,7 @@ public class GraphPart implements Serializable {
|
||||
if (next.numBlocks > numBlocks) {
|
||||
next.setNumblocks(numBlocks);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean leadsTo(BaseLocalData localData, Graph gr, GraphSource code, GraphPart prev, GraphPart part, HashSet<GraphPart> visited, List<Loop> loops, List<ThrowState> throwStates, boolean useThrow) throws InterruptedException {
|
||||
@@ -141,6 +141,74 @@ public class GraphPart implements Serializable {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
|
||||
Stack<GraphPart> todo = new Stack<>();
|
||||
todo.push(this);
|
||||
|
||||
looptodo:while (!todo.isEmpty()) {
|
||||
GraphPart thisPart = todo.pop();
|
||||
|
||||
GraphPart tpart = gr.checkPart(null, localData, prev, thisPart, null);
|
||||
if (tpart == null) {
|
||||
continue;
|
||||
}
|
||||
if (tpart != thisPart) {
|
||||
todo.push(tpart);
|
||||
continue;
|
||||
}
|
||||
for (Loop l : loops) {
|
||||
if (l.phase == 1) {
|
||||
if (l.loopContinue == thisPart) {
|
||||
continue looptodo;
|
||||
}
|
||||
if (l.loopPreContinue == thisPart) {
|
||||
continue looptodo;
|
||||
}
|
||||
if (l.loopBreak == thisPart) {
|
||||
//return false; //?
|
||||
}
|
||||
}
|
||||
}
|
||||
if (visited.contains(thisPart)) {
|
||||
continue;
|
||||
}
|
||||
visited.add(thisPart);
|
||||
if (thisPart.end < code.size() && code.get(thisPart.end).isBranch() && (code.get(thisPart.end).ignoredLoops())) {
|
||||
continue;
|
||||
}
|
||||
for (GraphPart p : thisPart.nextParts) {
|
||||
if (p == part) {
|
||||
return true;
|
||||
}
|
||||
if (visited.contains(p)) {
|
||||
continue;
|
||||
}
|
||||
todo.push(p);
|
||||
}
|
||||
for (ThrowState ts : throwStates) {
|
||||
if (ts.state != 1) {
|
||||
if (ts.throwingParts.contains(thisPart)) {
|
||||
GraphPart p = ts.targetPart;
|
||||
|
||||
if (p == part) {
|
||||
return true;
|
||||
}
|
||||
if (visited.contains(p)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
todo.push(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean leadsToRecursive(BaseLocalData localData, Graph gr, GraphSource code, GraphPart prev, GraphPart part, HashSet<GraphPart> visited, List<Loop> loops, List<ThrowState> throwStates, boolean useThrow) throws InterruptedException {
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
|
||||
GraphPart tpart = gr.checkPart(null, localData, prev, this, null);
|
||||
if (tpart == null) {
|
||||
return false;
|
||||
|
||||
@@ -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, GraphPartChangeException;
|
||||
public abstract List<GraphTargetItem> translatePart(Graph graph, GraphPart part, BaseLocalData localData, TranslateStack stack, int start, int end, int staticOperation, String path) throws InterruptedException, GraphPartChangeException;
|
||||
|
||||
public abstract Set<Long> getImportantAddresses();
|
||||
|
||||
|
||||
@@ -48,6 +48,9 @@ public class CommaExpressionItem extends GraphTargetItem {
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
boolean first = true;
|
||||
for (GraphTargetItem t : commands) {
|
||||
if (t.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (!first) {
|
||||
writer.append(", ");
|
||||
}
|
||||
|
||||
@@ -101,13 +101,15 @@ public class DoWhileItem extends LoopItem implements Block {
|
||||
}
|
||||
writer.append("(");
|
||||
|
||||
boolean first = true;
|
||||
for (int i = 0; i < expression.size(); i++) {
|
||||
if (expression.get(i).isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (i != 0) {
|
||||
if (!first) {
|
||||
writer.append(", ");
|
||||
}
|
||||
first = false;
|
||||
if (i == expression.size() - 1) {
|
||||
expression.get(i).toStringBoolean(writer, localData);
|
||||
} else {
|
||||
|
||||
@@ -92,13 +92,15 @@ public class WhileItem extends LoopItem implements Block {
|
||||
writer.append(" ");
|
||||
}
|
||||
writer.append("(");
|
||||
boolean first = true;
|
||||
for (int i = 0; i < expression.size(); i++) {
|
||||
if (expression.get(i).isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (i != 0) {
|
||||
if (!first) {
|
||||
writer.append(", ");
|
||||
}
|
||||
first = false;
|
||||
if (i == expression.size() - 1) {
|
||||
expression.get(i).toStringBoolean(writer, localData);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user