#731 AS2 decompilation problem fixed

This commit is contained in:
honfika@gmail.com
2014-11-29 16:20:08 +01:00
parent 3d092df4ef
commit 87611fabbc
6 changed files with 69 additions and 17 deletions

View File

@@ -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.instructions.AVM2Instruction;
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;

View File

@@ -27,6 +27,7 @@ import com.jpexs.decompiler.flash.action.special.ActionStore;
import com.jpexs.decompiler.flash.action.swf4.ActionAdd;
import com.jpexs.decompiler.flash.action.swf4.ActionCharToAscii;
import com.jpexs.decompiler.flash.action.swf4.ActionEquals;
import com.jpexs.decompiler.flash.action.swf4.ActionGetTime;
import com.jpexs.decompiler.flash.action.swf4.ActionIf;
import com.jpexs.decompiler.flash.action.swf4.ActionJump;
import com.jpexs.decompiler.flash.action.swf4.ActionMultiply;
@@ -41,6 +42,7 @@ import com.jpexs.decompiler.flash.action.swf5.ActionBitLShift;
import com.jpexs.decompiler.flash.action.swf5.ActionBitOr;
import com.jpexs.decompiler.flash.action.swf5.ActionBitRShift;
import com.jpexs.decompiler.flash.action.swf5.ActionBitXor;
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.ecma.EcmaScript;
@@ -66,9 +68,63 @@ public class ActionDeobfuscatorSimple implements SWFDecompilerListener {
@Override
public void actionListParsed(ActionList actions, SWF swf) {
removeGetTimes(actions);
removeObfuscationIfs(actions);
}
private boolean removeGetTimes(ActionList actions) {
if (actions.size() == 0) {
return false;
}
boolean changed = true;
while (changed) {
changed = false;
removeUnreachableActions(actions);
removeZeroJumps(actions);
// GetTime, If => Jump, assume GetTime > 0
for (int i = 0; i < actions.size() - 1; i++) {
Action a = actions.get(i);
Action a2 = actions.get(i + 1);
if (a instanceof ActionGetTime && a2 instanceof ActionIf) {
ActionIf aIf = (ActionIf) a2;
ActionJump jump = new ActionJump(0);
jump.setAddress(aIf.getAddress());
jump.setJumpOffset(aIf.getJumpOffset());
actions.remove(i); // GetTime
actions.remove(i); // If
actions.addAction(i, jump); // replace If with Jump
changed = true;
break;
}
}
if (!changed) {
// GetTime, Increment If => Jump
for (int i = 0; i < actions.size() - 2; i++) {
Action a = actions.get(i);
Action a1 = actions.get(i + 1);
Action a2 = actions.get(i + 2);
if (a instanceof ActionGetTime && a1 instanceof ActionIncrement && a2 instanceof ActionIf) {
ActionIf aIf = (ActionIf) a2;
ActionJump jump = new ActionJump(0);
jump.setAddress(aIf.getAddress());
jump.setJumpOffset(aIf.getJumpOffset());
actions.remove(i); // GetTime
actions.remove(i); // Increment
actions.remove(i); // If
actions.addAction(i, jump); // replace If with Jump
changed = true;
break;
}
}
}
}
return false;
}
private boolean removeObfuscationIfs(ActionList actions) {
if (actions.size() == 0) {
return false;
@@ -84,10 +140,10 @@ public class ActionDeobfuscatorSimple implements SWFDecompilerListener {
if (result.idx != -1) {
int newIstructionCount = 1; // jump
if (!result.stack.isEmpty()) {
newIstructionCount++;
newIstructionCount += result.stack.size();
}
if (newIstructionCount + 1 < result.instructionsProcessed) {
if (newIstructionCount < result.instructionsProcessed) {
Action target = actions.get(result.idx);
Action prevAction = actions.get(i);
@@ -258,6 +314,7 @@ public class ActionDeobfuscatorSimple implements SWFDecompilerListener {
if (action instanceof ActionPush) {
ActionPush push = (ActionPush) action;
boolean ok = true;
instructionsProcessed += push.values.size() - 1;
for (Object value : push.values) {
if (value instanceof ConstantIndex || value instanceof RegisterNumber) {
ok = false;

View File

@@ -37,8 +37,8 @@ public class Cache<K, V> implements Freed {
private static final List<Cache> instances = new ArrayList<>();
public static final int STORAGE_FILES = 1;
public static final int STORAGE_MEMORY = 2;
private boolean weak;
private String name;
private final boolean weak;
private final String name;
static {
Runtime.getRuntime().addShutdownHook(new Thread() {

View File

@@ -4,7 +4,6 @@ import com.jpexs.decompiler.flash.helpers.Freed;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -22,6 +21,8 @@ import java.util.logging.Logger;
/**
*
* @author JPEXS
* @param <K>
* @param <V>
*/
public class FileHashMap<K, V> extends AbstractMap<K, V> implements Freed {
@@ -75,8 +76,8 @@ public class FileHashMap<K, V> extends AbstractMap<K, V> implements Freed {
public static class FileEntry<K, V> implements Map.Entry<K, V> {
private FileHashMap<K, V> parent;
private K key;
private final FileHashMap<K, V> parent;
private final K key;
public FileEntry(FileHashMap<K, V> parent, K key) {
this.parent = parent;
@@ -248,9 +249,9 @@ public class FileHashMap<K, V> extends AbstractMap<K, V> implements Freed {
if (deleted) {
throw new NullPointerException();
}
Set<Entry<K, V>> ret = new HashSet<Entry<K, V>>();
Set<Entry<K, V>> ret = new HashSet<>();
for (K key : keySet()) {
ret.add(new FileEntry<K, V>(this, key));
ret.add(new FileEntry<>(this, key));
}
return ret;
}