mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-05-31 01:35:12 +00:00
AS2 deobfuscation fixes
This commit is contained in:
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action;
|
||||
import com.jpexs.decompiler.flash.AppResources;
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.action.model.ActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.ConstantPool;
|
||||
@@ -54,7 +55,9 @@ import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.ecma.Null;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.helpers.CodeFormatting;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.NulWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.collections.MyEntry;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
@@ -391,6 +394,23 @@ public class Action implements GraphSourceItem {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts list of actions to ASM source
|
||||
*
|
||||
* @param listeners
|
||||
* @param address
|
||||
* @param list List of actions
|
||||
* @param version SWF version
|
||||
* @param exportMode PCode or hex?
|
||||
* @return source ASM
|
||||
*
|
||||
*/
|
||||
public static String actionsToString(List<DisassemblyListener> listeners, long address, ActionList list, int version, ScriptExportMode exportMode) {
|
||||
HilightedTextWriter writer = new HilightedTextWriter(new CodeFormatting(), false);
|
||||
actionsToString(listeners, address, list, version, exportMode, writer);
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts list of actions to ASM source
|
||||
*
|
||||
@@ -671,6 +691,21 @@ public class Action implements GraphSourceItem {
|
||||
return actionsToTree(new HashMap<Integer, String>(), new HashMap<String, GraphTargetItem>(), new HashMap<String, GraphTargetItem>(), actions, version, staticOperation, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts list of actions to ActionScript source code
|
||||
*
|
||||
* @param asm
|
||||
* @param actions List of actions
|
||||
* @param path
|
||||
* @return source
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
public static String actionsToSource(final ASMSource asm, final List<Action> actions, final String path) throws InterruptedException {
|
||||
HilightedTextWriter writer = new HilightedTextWriter(new CodeFormatting(), false);
|
||||
actionsToSource(asm, actions, path, writer);
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts list of actions to ActionScript source code
|
||||
*
|
||||
@@ -685,12 +720,13 @@ public class Action implements GraphSourceItem {
|
||||
List<GraphTargetItem> tree = null;
|
||||
Throwable convertException = null;
|
||||
int timeout = Configuration.decompilationTimeoutSingleMethod.get();
|
||||
final int version = asm == null ? SWF.DEFAULT_VERSION : asm.getSwf().version;
|
||||
try {
|
||||
tree = CancellableWorker.call(new Callable<List<GraphTargetItem>>() {
|
||||
@Override
|
||||
public List<GraphTargetItem> call() throws Exception {
|
||||
int staticOperation = Graph.SOP_USE_STATIC; //(Boolean) Configuration.getConfig("autoDeobfuscate", true) ? Graph.SOP_SKIP_STATIC : Graph.SOP_USE_STATIC;
|
||||
List<GraphTargetItem> tree = actionsToTree(new HashMap<Integer, String>(), new HashMap<String, GraphTargetItem>(), new HashMap<String, GraphTargetItem>(), actions, asm.getSwf().version, staticOperation, path);
|
||||
List<GraphTargetItem> tree = actionsToTree(new HashMap<Integer, String>(), new HashMap<String, GraphTargetItem>(), new HashMap<String, GraphTargetItem>(), actions, version, staticOperation, path);
|
||||
Graph.graphToString(tree, new NulWriter(), new LocalData());
|
||||
return tree;
|
||||
}
|
||||
@@ -707,7 +743,9 @@ public class Action implements GraphSourceItem {
|
||||
}
|
||||
writer.continueMeasure();
|
||||
|
||||
asm.getActionSourcePrefix(writer);
|
||||
if (asm != null) {
|
||||
asm.getActionSourcePrefix(writer);
|
||||
}
|
||||
if (convertException == null) {
|
||||
Graph.graphToString(tree, writer, new LocalData());
|
||||
} else if (convertException instanceof TimeoutException) {
|
||||
@@ -717,7 +755,9 @@ public class Action implements GraphSourceItem {
|
||||
Logger.getLogger(Action.class.getName()).log(Level.SEVERE, "Decompilation error in: " + path, convertException);
|
||||
Helper.appendErrorComment(writer, convertException);
|
||||
}
|
||||
asm.getActionSourceSuffix(writer);
|
||||
if (asm != null) {
|
||||
asm.getActionSourceSuffix(writer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -186,4 +186,17 @@ public class ActionList extends ArrayList<Action> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Action.actionsToString(new ArrayList<DisassemblyListener>(), 0, this, SWF.DEFAULT_VERSION, ScriptExportMode.PCODE);
|
||||
}
|
||||
|
||||
public String toSource() {
|
||||
try {
|
||||
return Action.actionsToSource(null, this, "");
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(ActionList.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,11 +49,15 @@ import com.jpexs.decompiler.flash.action.swf5.ActionBitRShift;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionBitXor;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionCallFunction;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionConstantPool;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionDecrement;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionDefineLocal;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionEquals2;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionIncrement;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionModulo;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionPushDuplicate;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionReturn;
|
||||
import com.jpexs.decompiler.flash.action.swf6.ActionGreater;
|
||||
import com.jpexs.decompiler.flash.ecma.EcmaScript;
|
||||
import com.jpexs.decompiler.flash.helpers.SWFDecompilerListener;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
@@ -215,9 +219,10 @@ public class ActionDeobfuscator implements SWFDecompilerListener {
|
||||
return false;
|
||||
}
|
||||
|
||||
ActionConstantPool cPool = getConstantPool(actions);
|
||||
for (int i = 0; i < actions.size(); i++) {
|
||||
ExecutionResult result = new ExecutionResult();
|
||||
executeActions(actions, i, actions.size() - 1, result, fakeFunctions);
|
||||
executeActions(actions, i, actions.size() - 1, cPool, result, fakeFunctions);
|
||||
|
||||
if (result.idx != -1) {
|
||||
int newIstructionCount = 1; // jump
|
||||
@@ -285,12 +290,26 @@ public class ActionDeobfuscator implements SWFDecompilerListener {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void executeActions(ActionList actions, int idx, int endIdx, ExecutionResult result, Map<String, Object> fakeFunctions) {
|
||||
private ActionConstantPool getConstantPool(ActionList actions) {
|
||||
ActionConstantPool cPool = null;
|
||||
for (Action action : actions) {
|
||||
if (action instanceof ActionConstantPool) {
|
||||
if (cPool != null) {
|
||||
// there are multiple constant pools
|
||||
return null;
|
||||
}
|
||||
cPool = (ActionConstantPool) action;
|
||||
}
|
||||
}
|
||||
return cPool;
|
||||
}
|
||||
|
||||
private void executeActions(ActionList actions, int idx, int endIdx, ActionConstantPool constantPool, ExecutionResult result, Map<String, Object> fakeFunctions) {
|
||||
List<GraphTargetItem> output = new ArrayList<>();
|
||||
ActionLocalData localData = new ActionLocalData();
|
||||
FixItemCounterTranslateStack stack = new FixItemCounterTranslateStack();
|
||||
int instructionsProcessed = 0;
|
||||
ActionConstantPool constantPool = null;
|
||||
ActionConstantPool lastConstantPool = null;
|
||||
|
||||
try {
|
||||
while (true) {
|
||||
@@ -311,7 +330,7 @@ public class ActionDeobfuscator implements SWFDecompilerListener {
|
||||
}
|
||||
System.out.println();*/
|
||||
if (action instanceof ActionConstantPool) {
|
||||
constantPool = (ActionConstantPool) action;
|
||||
lastConstantPool = (ActionConstantPool) action;
|
||||
}
|
||||
|
||||
if (action instanceof ActionDefineLocal) {
|
||||
@@ -348,6 +367,8 @@ public class ActionDeobfuscator implements SWFDecompilerListener {
|
||||
|| action instanceof ActionPushDuplicate
|
||||
|| action instanceof ActionAdd
|
||||
|| action instanceof ActionAdd2
|
||||
|| action instanceof ActionIncrement
|
||||
|| action instanceof ActionDecrement
|
||||
|| action instanceof ActionSubtract
|
||||
|| action instanceof ActionModulo
|
||||
|| action instanceof ActionMultiply
|
||||
@@ -361,6 +382,8 @@ public class ActionDeobfuscator implements SWFDecompilerListener {
|
||||
|| action instanceof ActionGetVariable
|
||||
|| action instanceof ActionSetVariable
|
||||
|| action instanceof ActionEquals
|
||||
|| action instanceof ActionEquals2
|
||||
|| action instanceof ActionGreater
|
||||
|| action instanceof ActionNot
|
||||
|| action instanceof ActionIf
|
||||
|| action instanceof ActionConstantPool
|
||||
@@ -374,7 +397,7 @@ public class ActionDeobfuscator implements SWFDecompilerListener {
|
||||
ActionPush push = (ActionPush) action;
|
||||
boolean ok = true;
|
||||
for (Object value : push.values) {
|
||||
if (value instanceof ConstantIndex || value instanceof RegisterNumber) {
|
||||
if ((constantPool == null && value instanceof ConstantIndex) || value instanceof RegisterNumber) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
@@ -418,7 +441,7 @@ public class ActionDeobfuscator implements SWFDecompilerListener {
|
||||
if (/*localData.variables.size() == 1 && */stack.allItemsFixed() || action instanceof ActionEnd) {
|
||||
result.idx = idx == actions.size() ? idx - 1 : idx;
|
||||
result.instructionsProcessed = instructionsProcessed;
|
||||
result.constantPool = constantPool;
|
||||
result.constantPool = lastConstantPool;
|
||||
result.variables.clear();
|
||||
for (String variableName : localData.variables.keySet()) {
|
||||
Object value = localData.variables.get(variableName).getResult();
|
||||
@@ -458,7 +481,7 @@ public class ActionDeobfuscator implements SWFDecompilerListener {
|
||||
ExecutionResult result = new ExecutionResult();
|
||||
List<Action> lastActions = actions.getContainerLastActions(action);
|
||||
int lastActionIdx = actions.indexOf(lastActions.get(0));
|
||||
executeActions(actions, i + 1, lastActionIdx, result, null);
|
||||
executeActions(actions, i + 1, lastActionIdx, null, result, null);
|
||||
if (result.resultValue != null) {
|
||||
results.put(def.functionName, result.resultValue);
|
||||
for (int j = i; j <= lastActionIdx; j++) {
|
||||
|
||||
Reference in New Issue
Block a user