mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-19 19:51:53 +00:00
Fixed: #2477 AS1/2 deobfuscation - and/or operators, jumps before function start,
jumps to function end, jumps in for..in return/break
This commit is contained in:
@@ -3767,7 +3767,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
ip = code.adr2pos(addr);
|
||||
addr += size;
|
||||
int nextip = code.adr2pos(addr);
|
||||
getVariables(aLocalData.insideDoInitAction, variables, functions, strings, usageTypes, new ActionGraphSource(path, aLocalData.insideDoInitAction, code.getActions().subList(ip, nextip), code.version, new HashMap<>(), new HashMap<>(), new HashMap<>(), code.getCharset()), 0, path + (cntName == null ? "" : "/" + cntName));
|
||||
getVariables(aLocalData.insideDoInitAction, variables, functions, strings, usageTypes, new ActionGraphSource(path, aLocalData.insideDoInitAction, code.getActions().subList(0, nextip), code.version, new HashMap<>(), new HashMap<>(), new HashMap<>(), code.getCharset(), ip), 0, path + (cntName == null ? "" : "/" + cntName));
|
||||
ip = nextip;
|
||||
}
|
||||
List<List<GraphTargetItem>> r = new ArrayList<>();
|
||||
@@ -3895,7 +3895,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
ActionList actions = src.getActions();
|
||||
actionsMap.put(src, actions);
|
||||
boolean insideDoInitAction = src instanceof DoInitActionTag;
|
||||
getVariables(insideDoInitAction, variables, functions, strings, usageTypes, new ActionGraphSource(path, insideDoInitAction, actions, version, new HashMap<>(), new HashMap<>(), new HashMap<>(), src.getSwf().getCharset()), 0, path);
|
||||
getVariables(insideDoInitAction, variables, functions, strings, usageTypes, new ActionGraphSource(path, insideDoInitAction, actions, version, new HashMap<>(), new HashMap<>(), new HashMap<>(), src.getSwf().getCharset(), 0), 0, path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -222,7 +222,7 @@ public class AVM2Graph extends Graph {
|
||||
* @param localRegAssignmentIps Local register assignment IPs
|
||||
*/
|
||||
public AVM2Graph(int swfVersion, AbcIndexing abcIndex, AVM2Code code, ABC abc, MethodBody body, boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, ScopeStack scopeStack, ScopeStack localScopeStack, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames, HashMap<Integer, Integer> localRegAssignmentIps) {
|
||||
super(AVM2GraphTargetDialect.INSTANCE, new AVM2GraphSource(code, isStatic, scriptIndex, classIndex, localRegs, abc, body, localRegNames, fullyQualifiedNames, localRegAssignmentIps), getExceptionEntries(body));
|
||||
super(AVM2GraphTargetDialect.INSTANCE, new AVM2GraphSource(code, isStatic, scriptIndex, classIndex, localRegs, abc, body, localRegNames, fullyQualifiedNames, localRegAssignmentIps), getExceptionEntries(body), 0);
|
||||
this.avm2code = code;
|
||||
this.abc = abc;
|
||||
this.body = body;
|
||||
@@ -1818,6 +1818,7 @@ public class AVM2Graph extends Graph {
|
||||
|
||||
Reference<GraphPart> nextRef = new Reference<>(null);
|
||||
Reference<GraphTargetItem> tiRef = new Reference<>(null);
|
||||
makeAllCommands(output, stack);
|
||||
SwitchItem sw = handleSwitch(switchedObject, switchStartItem, foundGotos, partCodes, partCodePos, visited, allParts, stack, stopPart, stopPartKind, loops, throwStates, localData, staticOperation, path, caseValuesMap, defaultPart, caseBodyParts, nextRef, tiRef);
|
||||
ret = new ArrayList<>();
|
||||
ret.addAll(output);
|
||||
|
||||
@@ -50,6 +50,7 @@ import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionConstantPool;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionEquals2;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionWith;
|
||||
import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2;
|
||||
import com.jpexs.decompiler.flash.action.swf7.ActionTry;
|
||||
@@ -1071,13 +1072,13 @@ public abstract class Action implements GraphSourceItem {
|
||||
HashMap<String, GraphTargetItem> variablesBackup = new LinkedHashMap<>(variables);
|
||||
HashMap<String, GraphTargetItem> functionsBackup = new LinkedHashMap<>(functions);
|
||||
try {
|
||||
return ActionGraph.translateViaGraph(uninitializedClassTraits, null, insideDoInitAction, insideFunction, regNames, variables, functions, actions, version, staticOperation, path, charset);
|
||||
return ActionGraph.translateViaGraph(uninitializedClassTraits, null, insideDoInitAction, insideFunction, regNames, variables, functions, actions, version, staticOperation, path, charset, 0);
|
||||
} catch (SecondPassException spe) {
|
||||
variables.clear();
|
||||
variables.putAll(variablesBackup);
|
||||
functions.clear();
|
||||
functions.putAll(functionsBackup);
|
||||
return ActionGraph.translateViaGraph(uninitializedClassTraits, spe.getData(), insideDoInitAction, insideFunction, regNames, variables, functions, actions, version, staticOperation, path, charset);
|
||||
return ActionGraph.translateViaGraph(uninitializedClassTraits, spe.getData(), insideDoInitAction, insideFunction, regNames, variables, functions, actions, version, staticOperation, path, charset, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1251,7 +1252,7 @@ public abstract class Action implements GraphSourceItem {
|
||||
ip++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
//FunctionActionItem after DefineFunction(/2) are left on the stack. For linestart offsets we consider this kind of stack empty.
|
||||
boolean isStackEmpty = true;
|
||||
for (int i = 0; i < stack.size(); i++) {
|
||||
@@ -1287,11 +1288,12 @@ public abstract class Action implements GraphSourceItem {
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
out = ActionGraph.translateViaGraph(graph.getUninitializedClassTraits(), null, insideDoInitAction, true, regNames, variables2, functions, actions.subList(adr2ip(actions, endAddr), adr2ip(actions, endAddr + size)), version, staticOperation, path + (cntName == null ? "" : "/" + cntName), charset);
|
||||
int startIp = adr2ip(actions, endAddr);
|
||||
try {
|
||||
out = ActionGraph.translateViaGraph(graph.getUninitializedClassTraits(), null, insideDoInitAction, true, regNames, variables2, functions, actions.subList(0, adr2ip(actions, endAddr + size)), version, staticOperation, path + (cntName == null ? "" : "/" + cntName), charset, startIp);
|
||||
} catch (SecondPassException spe) {
|
||||
variables2 = prepareVariables(cnt, variables);
|
||||
out = ActionGraph.translateViaGraph(graph.getUninitializedClassTraits(), spe.getData(), insideDoInitAction, true, regNames, variables2, functions, actions.subList(adr2ip(actions, endAddr), adr2ip(actions, endAddr + size)), version, staticOperation, path + (cntName == null ? "" : "/" + cntName), charset);
|
||||
out = ActionGraph.translateViaGraph(graph.getUninitializedClassTraits(), spe.getData(), insideDoInitAction, true, regNames, variables2, functions, actions.subList(0, adr2ip(actions, endAddr + size)), version, staticOperation, path + (cntName == null ? "" : "/" + cntName), charset, startIp);
|
||||
}
|
||||
} catch (OutOfMemoryError | TranslateException | StackOverflowError ex) {
|
||||
logger.log(Level.SEVERE, "Decompilation error in: " + path, ex);
|
||||
@@ -1320,7 +1322,7 @@ public abstract class Action implements GraphSourceItem {
|
||||
}
|
||||
|
||||
//return in for..in
|
||||
if ((action instanceof ActionPush) && (((ActionPush) action).values.size() == 1) && (((ActionPush) action).values.get(0) == Null.INSTANCE)) {
|
||||
/*if ((action instanceof ActionPush) && (((ActionPush) action).values.size() == 1) && (((ActionPush) action).values.get(0) == Null.INSTANCE)) {
|
||||
if (ip + 3 <= end) {
|
||||
if ((actions.get(ip + 1) instanceof ActionEquals) || (actions.get(ip + 1) instanceof ActionEquals2)) {
|
||||
if (actions.get(ip + 2) instanceof ActionNot) {
|
||||
@@ -1334,6 +1336,14 @@ public abstract class Action implements GraphSourceItem {
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
int nip = graph.checkIp(ip);
|
||||
if (nip != ip) {
|
||||
ip = nip;
|
||||
if (ip > end) {
|
||||
break;
|
||||
}
|
||||
action = actions.get(ip);
|
||||
}
|
||||
|
||||
if (action instanceof ActionStore) {
|
||||
|
||||
@@ -125,9 +125,10 @@ public class ActionGraph extends Graph {
|
||||
* @param functions Functions
|
||||
* @param version Version
|
||||
* @param charset Charset
|
||||
* @param startIp Start IP
|
||||
*/
|
||||
public ActionGraph(Map<String, Map<String, Trait>> uninitializedClassTraits, String path, boolean insideDoInitAction, boolean insideFunction, List<Action> code, HashMap<Integer, String> registerNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int version, String charset) {
|
||||
super(ActionGraphTargetDialect.INSTANCE, new ActionGraphSource(path, insideDoInitAction, code, version, registerNames, variables, functions, charset), new ArrayList<>());
|
||||
public ActionGraph(Map<String, Map<String, Trait>> uninitializedClassTraits, String path, boolean insideDoInitAction, boolean insideFunction, List<Action> code, HashMap<Integer, String> registerNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int version, String charset, int startIp) {
|
||||
super(ActionGraphTargetDialect.INSTANCE, new ActionGraphSource(path, insideDoInitAction, code, version, registerNames, variables, functions, charset, startIp), new ArrayList<>(), startIp);
|
||||
this.uninitializedClassTraits = uninitializedClassTraits;
|
||||
this.insideDoInitAction = insideDoInitAction;
|
||||
this.insideFunction = insideFunction;
|
||||
@@ -164,18 +165,23 @@ public class ActionGraph extends Graph {
|
||||
String functionName = (action instanceof ActionDefineFunction) ? ((ActionDefineFunction) action).functionName : ((ActionDefineFunction2) action).functionName;
|
||||
long endAddr = action.getAddress() + cnt.getHeaderSize();
|
||||
List<ActionList> outs = new ArrayList<>();
|
||||
List<Integer> startIps = new ArrayList<>();
|
||||
for (long size : cnt.getContainerSizes()) {
|
||||
if (size == 0) {
|
||||
outs.add(new ActionList(((ActionGraphSource) code).getCharset()));
|
||||
continue;
|
||||
}
|
||||
outs.add(new ActionList(alist.subList(Action.adr2ip(alist, endAddr), Action.adr2ip(alist, endAddr + size)), getGraphCode().getCharset()));
|
||||
int startIp = Action.adr2ip(alist, endAddr);
|
||||
startIps.add(startIp);
|
||||
outs.add(new ActionList(alist.subList(0, Action.adr2ip(alist, endAddr + size)), getGraphCode().getCharset()));
|
||||
endAddr += size;
|
||||
}
|
||||
|
||||
for (ActionList al : outs) {
|
||||
for (int i = 0; i < outs.size(); i++) {
|
||||
ActionList al = outs.get(i);
|
||||
int startIp = startIps.get(i);
|
||||
subgraphs.put("loc" + Helper.formatAddress(code.pos2adr(ip)) + ": function " + functionName,
|
||||
new ActionGraph(uninitializedClassTraits, "", false, false, al, new HashMap<>(), new HashMap<>(), new HashMap<>(), SWF.DEFAULT_VERSION, ((ActionGraphSource) getGraphCode()).getCharset())
|
||||
new ActionGraph(uninitializedClassTraits, "", false, false, al, new HashMap<>(), new HashMap<>(), new HashMap<>(), SWF.DEFAULT_VERSION, ((ActionGraphSource) getGraphCode()).getCharset(), startIp)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -221,8 +227,8 @@ public class ActionGraph extends Graph {
|
||||
* @return List of graph target items
|
||||
* @throws InterruptedException On interrupt
|
||||
*/
|
||||
public static List<GraphTargetItem> translateViaGraph(Map<String, Map<String, Trait>> uninitializedClassTraits, SecondPassData secondPassData, boolean insideDoInitAction, boolean insideFunction, HashMap<Integer, String> registerNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, List<Action> code, int version, int staticOperation, String path, String charset) throws InterruptedException {
|
||||
ActionGraph g = new ActionGraph(uninitializedClassTraits, path, insideDoInitAction, insideFunction, code, registerNames, variables, functions, version, charset);
|
||||
public static List<GraphTargetItem> translateViaGraph(Map<String, Map<String, Trait>> uninitializedClassTraits, SecondPassData secondPassData, boolean insideDoInitAction, boolean insideFunction, HashMap<Integer, String> registerNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, List<Action> code, int version, int staticOperation, String path, String charset, int startIp) throws InterruptedException {
|
||||
ActionGraph g = new ActionGraph(uninitializedClassTraits, path, insideDoInitAction, insideFunction, code, registerNames, variables, functions, version, charset, startIp);
|
||||
ActionLocalData localData = new ActionLocalData(secondPassData, insideDoInitAction, registerNames, uninitializedClassTraits);
|
||||
g.init(localData);
|
||||
return g.translate(localData, staticOperation, path);
|
||||
@@ -280,7 +286,7 @@ public class ActionGraph extends Graph {
|
||||
|
||||
@Override
|
||||
protected void finalProcess(GraphTargetItem parent, List<GraphTargetItem> list, int level, FinalProcessLocalData localData, String path) throws InterruptedException {
|
||||
|
||||
|
||||
if (level == 0) {
|
||||
List<GraphTargetItem> removed = new ArrayList<>();
|
||||
for (int i = list.size() - 1; i >= 0; i--) {
|
||||
@@ -295,7 +301,7 @@ public class ActionGraph extends Graph {
|
||||
}
|
||||
list.addAll(0, removed);
|
||||
}
|
||||
|
||||
|
||||
int targetStart;
|
||||
int targetEnd;
|
||||
GraphTargetItem targetStartItem = null;
|
||||
@@ -867,6 +873,7 @@ public class ActionGraph extends Graph {
|
||||
|
||||
Reference<GraphPart> nextRef = new Reference<>(null);
|
||||
Reference<GraphTargetItem> tiRef = new Reference<>(null);
|
||||
makeAllCommands(output, stack);
|
||||
SwitchItem sw = handleSwitch(switchedObject, switchStartItem, foundGotos, partCodes, partCodePos, visited, allParts, stack, stopPart, stopPartKind, loops, throwStates, localData, staticOperation, path, caseValuesMap, defaultPart, caseBodyParts, nextRef, tiRef);
|
||||
ret = new ArrayList<>();
|
||||
ret.addAll(output);
|
||||
@@ -882,7 +889,19 @@ public class ActionGraph extends Graph {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
private int ipAfterJumps(int nip) {
|
||||
while (nip < code.size() && code.get(nip) instanceof ActionJump) {
|
||||
ActionJump j = (ActionJump) code.get(nip);
|
||||
int nip2 = code.adr2pos(j.getTargetAddress());
|
||||
if (nip2 == nip) {
|
||||
break;
|
||||
}
|
||||
nip = nip2;
|
||||
}
|
||||
return nip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks IP and allows to modify it.
|
||||
*
|
||||
@@ -891,22 +910,67 @@ public class ActionGraph extends Graph {
|
||||
*/
|
||||
@Override
|
||||
protected int checkIp(int ip) {
|
||||
int oldIp = ip;
|
||||
|
||||
if (ip >= code.size()) {
|
||||
return ip;
|
||||
}
|
||||
|
||||
int oldIp = ip;
|
||||
|
||||
//return/break in for..in
|
||||
/*
|
||||
We need to skip following:
|
||||
|
||||
locA:Push null
|
||||
Equals/Equals2
|
||||
Not
|
||||
If locA
|
||||
...
|
||||
|
||||
Beware: There can be obfuscation jumps anywhere on the path!
|
||||
*/
|
||||
GraphSourceItem action = code.get(ip);
|
||||
if ((action instanceof ActionPush) && (((ActionPush) action).values.size() == 1) && (((ActionPush) action).values.get(0) == Null.INSTANCE)) {
|
||||
int nip = ip;
|
||||
if (nip + 1 < code.size()) {
|
||||
nip++;
|
||||
nip = ipAfterJumps(nip);
|
||||
if (nip < code.size() && ((code.get(nip) instanceof ActionEquals) || (code.get(nip) instanceof ActionEquals2))) {
|
||||
nip++;
|
||||
nip = ipAfterJumps(nip);
|
||||
if (nip < code.size() && code.get(nip) instanceof ActionNot) {
|
||||
nip++;
|
||||
nip = ipAfterJumps(nip);
|
||||
if (nip < code.size() && code.get(nip) instanceof ActionIf) {
|
||||
ActionIf aif = (ActionIf) code.get(nip);
|
||||
|
||||
int jip = code.adr2pos(aif.getTargetAddress());
|
||||
jip = ipAfterJumps(jip);
|
||||
if (jip == ip) {
|
||||
nip++;
|
||||
ip = nip;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//The simple approach is not working, there may be jumps inside
|
||||
/*
|
||||
if (ip + 3 <= code.size()) {
|
||||
if ((code.get(ip + 1) instanceof ActionEquals) || (code.get(ip + 1) instanceof ActionEquals2)) {
|
||||
if (code.get(ip + 2) instanceof ActionNot) {
|
||||
if (code.get(ip + 3) instanceof ActionIf) {
|
||||
ActionIf aif = (ActionIf) code.get(ip + 3);
|
||||
if (code.adr2pos(code.pos2adr(ip + 3) + 5 /*IF numbytes*/ + aif.getJumpOffset()) == ip) {
|
||||
if (code.adr2pos(code.pos2adr(ip + 3) + 5 //IF numbytes
|
||||
+ aif.getJumpOffset()) == ip) {
|
||||
ip += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
if (oldIp != ip) {
|
||||
if (ip == code.size()) { //no next checkIp call since its after code size
|
||||
|
||||
@@ -107,8 +107,9 @@ public class ActionGraphSource extends GraphSource {
|
||||
* @param functions Functions
|
||||
* @param charset Charset
|
||||
*/
|
||||
public ActionGraphSource(String path, boolean insideDoInitAction, List<Action> actions, int version, HashMap<Integer, String> registerNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, String charset) {
|
||||
this.actions = actions instanceof ActionList ? (ActionList) actions : new ActionList(actions, charset);
|
||||
public ActionGraphSource(String path, boolean insideDoInitAction, List<Action> actions, int version, HashMap<Integer, String> registerNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, String charset, int startIp) {
|
||||
this.startIp = startIp;
|
||||
this.actions = actions instanceof ActionList ? (ActionList) actions : new ActionList(actions, charset);
|
||||
this.version = version;
|
||||
this.registerNames = registerNames;
|
||||
this.variables = variables;
|
||||
|
||||
@@ -43,6 +43,7 @@ import com.jpexs.decompiler.flash.action.swf4.ActionMBStringLength;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionMultiply;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionNot;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionOr;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPop;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionStringAdd;
|
||||
@@ -84,6 +85,7 @@ import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.model.FalseItem;
|
||||
import com.jpexs.decompiler.graph.model.PushItem;
|
||||
import com.jpexs.helpers.CancellableWorker;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -146,7 +148,7 @@ public class ActionDeobfuscator extends SWFDecompilerAdapter {
|
||||
actions.removeUnreachableActions();
|
||||
actions.removeZeroJumps();
|
||||
getTimeCount = 0;
|
||||
|
||||
|
||||
// GetTime, If => Jump, assume GetTime > 0
|
||||
FastActionListIterator iterator = actions.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
@@ -162,10 +164,30 @@ public class ActionDeobfuscator extends SWFDecompilerAdapter {
|
||||
ActionJump jump = new ActionJump(0, actions.getCharset());
|
||||
ActionItem jumpItem = new ActionItem(jump);
|
||||
jumpItem.setJumpTarget(a2Item.getJumpTarget());
|
||||
|
||||
/* This simple approach does not work
|
||||
|
||||
iterator.remove(); // GetTime
|
||||
iterator.next();
|
||||
iterator.remove(); // If
|
||||
iterator.add(jumpItem); // replace If with Jump
|
||||
*/
|
||||
|
||||
//Must remove + add in this particular order,
|
||||
//otherwise if will map the jumpsTo after the new jumpItem.
|
||||
|
||||
iterator.next(); //to If
|
||||
iterator.add(jumpItem); // Add Jump after If
|
||||
|
||||
//Now go back and remove GetTime, If...
|
||||
iterator.prev(); //to If
|
||||
iterator.prev(); //to GetTime
|
||||
|
||||
iterator.remove(); //GetTime
|
||||
iterator.next();
|
||||
iterator.remove(); //If
|
||||
iterator.next();
|
||||
|
||||
changed = true;
|
||||
ret = true;
|
||||
getTimeCount--;
|
||||
@@ -184,12 +206,36 @@ public class ActionDeobfuscator extends SWFDecompilerAdapter {
|
||||
ActionJump jump = new ActionJump(0, actions.getCharset());
|
||||
ActionItem jumpItem = new ActionItem(jump);
|
||||
jumpItem.setJumpTarget(a2Item.getJumpTarget());
|
||||
/* This simple approach does not work
|
||||
iterator.remove(); // GetTime
|
||||
iterator.next();
|
||||
iterator.remove(); // Increment
|
||||
iterator.next();
|
||||
iterator.remove(); // If
|
||||
iterator.add(jumpItem); // replace If with Jump
|
||||
*/
|
||||
|
||||
|
||||
//Must remove + add in this particular order,
|
||||
//otherwise if will map the jumpsTo after the new jumpItem.
|
||||
|
||||
iterator.next(); //to Increment
|
||||
iterator.next(); //to If
|
||||
iterator.add(jumpItem); // Add Jump after If
|
||||
|
||||
//Now go back and remove GetTime, Increment, If...
|
||||
iterator.prev(); //to If
|
||||
iterator.prev(); //to Increment
|
||||
iterator.prev(); //to GetTime
|
||||
|
||||
iterator.remove(); //GetTime
|
||||
iterator.next();
|
||||
iterator.remove(); //Increment
|
||||
iterator.next();
|
||||
iterator.remove(); //If
|
||||
|
||||
iterator.next();
|
||||
|
||||
changed = true;
|
||||
ret = true;
|
||||
}
|
||||
@@ -208,7 +254,7 @@ public class ActionDeobfuscator extends SWFDecompilerAdapter {
|
||||
boolean ret = false;
|
||||
actions.removeUnreachableActions();
|
||||
actions.removeZeroJumps();
|
||||
|
||||
|
||||
ActionConstantPool cPool = getConstantPool(actions);
|
||||
LocalDataArea localData = new LocalDataArea(new Stage(null), true);
|
||||
localData.stack = new FixItemCounterStack();
|
||||
@@ -481,7 +527,7 @@ public class ActionDeobfuscator extends SWFDecompilerAdapter {
|
||||
if (item.action.isExit()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
FixItemCounterStack stack = (FixItemCounterStack) localData.stack;
|
||||
int instructionsProcessed = 0;
|
||||
int skippedInstructions = 0;
|
||||
@@ -560,7 +606,7 @@ public class ActionDeobfuscator extends SWFDecompilerAdapter {
|
||||
|
||||
if (!(action instanceof ActionPush
|
||||
|| action instanceof ActionPushDuplicate
|
||||
//|| action instanceof ActionPop
|
||||
|| action instanceof ActionPop
|
||||
|| action instanceof ActionAsciiToChar
|
||||
|| action instanceof ActionCharToAscii
|
||||
|| action instanceof ActionDecrement
|
||||
@@ -660,7 +706,7 @@ public class ActionDeobfuscator extends SWFDecompilerAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
if (isEnd || (stack.allItemsFixed() && (action instanceof ActionIf || (jumpFound && action instanceof ActionJump) || action instanceof ActionSetVariable))) {
|
||||
if (isEnd || (stack.allItemsFixed() && (action instanceof ActionPop || action instanceof ActionIf || (jumpFound && action instanceof ActionJump) || action instanceof ActionSetVariable))) {
|
||||
result.item = item;
|
||||
result.instructionsProcessed = instructionsProcessed;
|
||||
result.minSkippedInstructions = skippedInstructions;
|
||||
@@ -676,7 +722,11 @@ public class ActionDeobfuscator extends SWFDecompilerAdapter {
|
||||
|
||||
if (isEnd) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (jumpedHere && item.prev.isContainerLastAction()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (action instanceof ActionReturn) {
|
||||
|
||||
@@ -132,7 +132,7 @@ public final class FastActionListIterator implements Iterator<ActionItem> {
|
||||
public void remove() {
|
||||
item = list.removeItem(item.prev);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds an action after the current item.
|
||||
*
|
||||
|
||||
@@ -136,13 +136,13 @@ public class ActionWaitForFrame extends Action implements ActionStore {
|
||||
HashMap<String, GraphTargetItem> functionsBackup = new LinkedHashMap<>(functions);
|
||||
|
||||
try {
|
||||
body = ActionGraph.translateViaGraph(uninitializedClassTraits, null, insideDoInitAction, true, regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path, getCharset());
|
||||
body = ActionGraph.translateViaGraph(uninitializedClassTraits, null, insideDoInitAction, true, regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path, getCharset(), 0);
|
||||
} catch (SecondPassException spe) {
|
||||
variables.clear();
|
||||
variables.putAll(variablesBackup);
|
||||
functions.clear();
|
||||
functions.putAll(functionsBackup);
|
||||
body = ActionGraph.translateViaGraph(uninitializedClassTraits, spe.getData(), insideDoInitAction, true, regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path, getCharset());
|
||||
body = ActionGraph.translateViaGraph(uninitializedClassTraits, spe.getData(), insideDoInitAction, true, regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path, getCharset(), 0);
|
||||
}
|
||||
output.add(new IfFrameLoadedActionItem(frameTi, body, this, lineStartAction));
|
||||
}
|
||||
|
||||
@@ -182,13 +182,13 @@ public class ActionWaitForFrame2 extends Action implements ActionStore {
|
||||
HashMap<String, GraphTargetItem> variablesBackup = new LinkedHashMap<>(variables);
|
||||
HashMap<String, GraphTargetItem> functionsBackup = new LinkedHashMap<>(functions);
|
||||
try {
|
||||
body = ActionGraph.translateViaGraph(uninitializedClassTraits, null, insideDoInitAction, true, regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path, getCharset());
|
||||
body = ActionGraph.translateViaGraph(uninitializedClassTraits, null, insideDoInitAction, true, regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path, getCharset(), 0);
|
||||
} catch (SecondPassException spe) {
|
||||
variables.clear();
|
||||
variables.putAll(variablesBackup);
|
||||
functions.clear();
|
||||
functions.putAll(functionsBackup);
|
||||
body = ActionGraph.translateViaGraph(uninitializedClassTraits, spe.getData(), insideDoInitAction, true, regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path, getCharset());
|
||||
body = ActionGraph.translateViaGraph(uninitializedClassTraits, spe.getData(), insideDoInitAction, true, regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path, getCharset(), 0);
|
||||
}
|
||||
output.add(new IfFrameLoadedActionItem(frame, body, this, lineStartAction));
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ public class PcodeGraphVizExporter {
|
||||
*/
|
||||
public void exportAs12(ASMSource src, GraphTextWriter writer) throws InterruptedException {
|
||||
ActionList alist = src.getActions();
|
||||
ActionGraph gr = new ActionGraph(new HashMap<>(), "", false, false, alist, new HashMap<>(), new HashMap<>(), new HashMap<>(), SWF.DEFAULT_VERSION, Utf8Helper.charsetName);
|
||||
ActionGraph gr = new ActionGraph(new HashMap<>(), "", false, false, alist, new HashMap<>(), new HashMap<>(), new HashMap<>(), SWF.DEFAULT_VERSION, Utf8Helper.charsetName, 0);
|
||||
export(gr, writer);
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ import com.jpexs.decompiler.graph.model.UniversalLoopItem;
|
||||
import com.jpexs.decompiler.graph.model.WhileItem;
|
||||
import com.jpexs.decompiler.graph.precontinues.GraphPrecontinueDetector;
|
||||
import com.jpexs.helpers.CancellableWorker;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.Reference;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
@@ -101,6 +102,11 @@ public class Graph {
|
||||
* Exceptions in the graph
|
||||
*/
|
||||
private final List<GraphException> exceptions;
|
||||
|
||||
/**
|
||||
* Graph startIp
|
||||
*/
|
||||
protected int startIp = 0;
|
||||
|
||||
/**
|
||||
* Debug flag to print all parts
|
||||
@@ -122,7 +128,7 @@ public class Graph {
|
||||
* Debug flag to not process Ifs
|
||||
*/
|
||||
protected boolean debugDoNotProcess = false;
|
||||
|
||||
|
||||
/**
|
||||
* Logger
|
||||
*/
|
||||
@@ -152,11 +158,13 @@ public class Graph {
|
||||
* @param dialect Dialect
|
||||
* @param code Graph source
|
||||
* @param exceptions Exceptions in the graph
|
||||
* @param startIp Start ip
|
||||
*/
|
||||
public Graph(GraphTargetDialect dialect, GraphSource code, List<GraphException> exceptions) {
|
||||
public Graph(GraphTargetDialect dialect, GraphSource code, List<GraphException> exceptions, int startIp) {
|
||||
this.dialect = dialect;
|
||||
this.code = code;
|
||||
this.exceptions = exceptions;
|
||||
this.startIp = startIp;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2950,7 +2958,7 @@ public class Graph {
|
||||
|
||||
if (vCanHandleVisited) {
|
||||
if (visited.contains(part)) {
|
||||
String labelName = "addr" + part.start;
|
||||
String labelName = "addr" + Helper.formatAddress(code.pos2adr(part.start, true)); //was: part.start;
|
||||
List<GraphTargetItem> firstCode = partCodes.get(part);
|
||||
int firstCodePos = partCodePos.get(part);
|
||||
if (firstCodePos > firstCode.size()) {
|
||||
@@ -3298,6 +3306,7 @@ public class Graph {
|
||||
}
|
||||
Reference<GraphPart> nextRef = new Reference<>(null);
|
||||
Reference<GraphTargetItem> tiRef = new Reference<>(null);
|
||||
makeAllCommands(currentRet, stack);
|
||||
SwitchItem sw = handleSwitch(switchedItem, originalSwitchedItem.getSrc(), foundGotos, partCodes, partCodePos, visited, allParts, stack, stopPart, stopPartKind, loops, throwStates, localData, staticOperation, path,
|
||||
caseValues, defaultPart, caseBodyParts, nextRef, tiRef);
|
||||
GraphPart next = nextRef.getVal();
|
||||
@@ -3767,7 +3776,7 @@ public class Graph {
|
||||
HashMap<Integer, List<Integer>> refs = code.visitCode(alternateEntries);
|
||||
List<GraphPart> ret = new ArrayList<>();
|
||||
boolean[] visited = new boolean[code.size()];
|
||||
ret.add(makeGraph(null, new GraphPath(), code, 0, 0, allBlocks, refs, visited));
|
||||
ret.add(makeGraph(null, new GraphPath(), code, startIp, 0, allBlocks, refs, visited));
|
||||
for (int pos : alternateEntries) {
|
||||
GraphPart e1 = new GraphPart(-1, -1);
|
||||
e1.path = new GraphPath("e");
|
||||
@@ -3811,9 +3820,9 @@ public class Graph {
|
||||
if (parent != null) {
|
||||
ret.refs.add(parent);
|
||||
parent.nextParts.add(ret);
|
||||
}
|
||||
}
|
||||
while (ip < code.size()) {
|
||||
ip = checkIp(ip);
|
||||
ip = checkIp(ip);
|
||||
if (ip >= code.size()) {
|
||||
break;
|
||||
}
|
||||
@@ -3870,8 +3879,10 @@ public class Graph {
|
||||
} else if (ins.isJump()) {
|
||||
part.end = ip;
|
||||
allBlocks.add(part);
|
||||
ip = ins.getBranches(code).get(0);
|
||||
ip = ins.getBranches(code).get(0);
|
||||
ip = checkIp(ip);
|
||||
makeGraph(part, path, code, ip, lastIp, allBlocks, refs, visited);
|
||||
lastIp = -1;
|
||||
break;
|
||||
} else if (ins.isBranch()) {
|
||||
part.end = ip;
|
||||
@@ -3879,7 +3890,7 @@ public class Graph {
|
||||
allBlocks.add(part);
|
||||
List<Integer> branches = ins.getBranches(code);
|
||||
for (int i = 0; i < branches.size(); i++) {
|
||||
makeGraph(part, path.sub(i, ip), code, branches.get(i), ip, allBlocks, refs, visited);
|
||||
makeGraph(part, path.sub(i, ip), code, checkIp(branches.get(i)), ip, allBlocks, refs, visited);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -4083,6 +4094,7 @@ public class Graph {
|
||||
protected SwitchItem handleSwitch(GraphTargetItem switchedObject,
|
||||
GraphSourceItem switchStartItem, List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, Set<GraphPart> visited, Set<GraphPart> allParts, TranslateStack stack, List<GraphPart> stopPart, List<StopPartKind> stopPartKind, List<Loop> loops, List<ThrowState> throwStates, BaseLocalData localData, int staticOperation, String path,
|
||||
List<GraphTargetItem> caseValuesMap, GraphPart defaultPart, List<GraphPart> caseBodyParts, Reference<GraphPart> nextRef, Reference<GraphTargetItem> tiRef) throws InterruptedException {
|
||||
|
||||
boolean hasDefault = false;
|
||||
/*
|
||||
case 4:
|
||||
|
||||
@@ -32,6 +32,11 @@ import java.util.Set;
|
||||
*/
|
||||
public abstract class GraphSource implements Serializable {
|
||||
|
||||
/**
|
||||
* Start IP
|
||||
*/
|
||||
protected int startIp = 0;
|
||||
|
||||
/**
|
||||
* Gets the size of the graph source
|
||||
*
|
||||
@@ -84,7 +89,7 @@ public abstract class GraphSource implements Serializable {
|
||||
* @param pos Position of the instruction
|
||||
* @return Instruction as string
|
||||
*/
|
||||
public abstract String insToString(int pos);
|
||||
public abstract String insToString(int pos);
|
||||
|
||||
/**
|
||||
* Visits the code
|
||||
@@ -162,7 +167,7 @@ public abstract class GraphSource implements Serializable {
|
||||
for (int i = 0; i < siz; i++) {
|
||||
refs.put(i, new ArrayList<>());
|
||||
}
|
||||
visitCode(0, 0, refs, -1);
|
||||
visitCode(startIp, 0, refs, -1);
|
||||
int pos = 0;
|
||||
for (int e : alternateEntries) {
|
||||
pos++;
|
||||
|
||||
Reference in New Issue
Block a user