diff --git a/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java b/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java index 1be51f3ba..ed0c72fc0 100644 --- a/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java +++ b/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java @@ -495,7 +495,7 @@ public class SWFInputStream extends InputStream { return readActionList(rri, version, 0); } - private static void getConstantPool(ConstantPool cpool, List localData, Stack stack, List output, ActionGraphSource code, int ip, int lastIp, List constantPools, List visited) { + private static void getConstantPool(ConstantPool cpool, List localData, Stack stack, List output, ActionGraphSource code, int ip, int lastIp, List constantPools, List visited, int version) { boolean debugMode = false; while ((ip > -1) && ip < code.size()) { if (visited.contains(ip)) { @@ -504,6 +504,10 @@ public class SWFInputStream extends InputStream { lastIp = ip; GraphSourceItem ins = code.get(ip); + if (ins.isIgnored()) { + ip++; + continue; + } if (ins instanceof ActionPush) { if (cpool != null) { @@ -546,6 +550,32 @@ public class SWFInputStream extends InputStream { if (ins.isBranch() || ins.isJump()) { if (ins instanceof ActionIf && !stack.isEmpty() && (stack.peek().isCompileTime())) { + ActionIf aif = (ActionIf) ins; + if (aif.ignoreUsed && (!aif.jumpUsed)) { + ins.setIgnored(true); + } + if ((!aif.ignoreUsed) && aif.jumpUsed) { + ActionJump jmpIns = new ActionJump(aif.offset); + ((ActionJump) jmpIns).setAddress(aif.getAddress(), version); + code.set(ip, (ActionJump) jmpIns); + } + + if ((aif.ignoreUsed && (!aif.jumpUsed)) || ((!aif.ignoreUsed) && aif.jumpUsed)) { + List needed = stack.peek().getNeededSources(); + for (GraphSourceItemPos ig : needed) { + if (ig.item instanceof ActionPush) { + if (!((ActionPush) ig.item).ignoredParts.contains(ig.pos)) { + ((ActionPush) ig.item).ignoredParts.add(ig.pos); + + if (((ActionPush) ig.item).ignoredParts.size() == ((ActionPush) ig.item).values.size()) { + ((Action) ig.item).ignored = true; + } + } + } else { + ((Action) ig.item).ignored = true; + } + } + } boolean condition = stack.peek().toBoolean(); if (debugMode) { if (condition) { @@ -555,7 +585,7 @@ public class SWFInputStream extends InputStream { } } stack.pop(); - getConstantPool(cpool, localData, stack, output, code, condition ? (code.adr2pos(((ActionIf) ins).getAddress() + ((ActionIf) ins).getBytes(code.version).length + ((ActionIf) ins).offset)) : ip + 1, ip, constantPools, visited); + getConstantPool(cpool, localData, stack, output, code, condition ? (code.adr2pos(((ActionIf) ins).getAddress() + ((ActionIf) ins).getBytes(code.version).length + ((ActionIf) ins).offset)) : ip + 1, ip, constantPools, visited, version); } else { if (ins instanceof ActionIf) { stack.pop(); @@ -565,7 +595,7 @@ public class SWFInputStream extends InputStream { for (int b : branches) { Stack brStack = (Stack) stack.clone(); if (b >= 0) { - getConstantPool(cpool, localData, brStack, output, code, b, ip, constantPools, visited); + getConstantPool(cpool, localData, brStack, output, code, b, ip, constantPools, visited, version); } else { if (debugMode) { System.out.println("Negative branch:" + b); @@ -582,11 +612,11 @@ public class SWFInputStream extends InputStream { } } - public static List getConstantPool(ActionGraphSource code, int addr) { + public static List getConstantPool(ActionGraphSource code, int addr, int version) { List ret = new ArrayList(); List localData = Helper.toList(new HashMap(), new HashMap(), new HashMap()); try { - getConstantPool(null, localData, new Stack(), new ArrayList(), code, code.adr2pos(addr), 0, ret, new ArrayList()); + getConstantPool(null, localData, new Stack(), new ArrayList(), code, code.adr2pos(addr), 0, ret, new ArrayList(), version); } catch (Exception ex) { log.log(Level.SEVERE, "Error during getting constantpool", ex); } @@ -649,7 +679,7 @@ public class SWFInputStream extends InputStream { } List pools = new ArrayList(); - pools = getConstantPool(new ActionGraphSource(ret, version, new HashMap(), new HashMap(), new HashMap()), ip); + pools = getConstantPool(new ActionGraphSource(ret, version, new HashMap(), new HashMap(), new HashMap()), ip, version); if (pools.size() == 1) { Action.setConstantPool(ret, pools.get(0)); @@ -685,6 +715,9 @@ public class SWFInputStream extends InputStream { Scanner sc = new Scanner(System.in); int prevIp = ip; while ((a = sis.readAction()) != null) { + if ((ip < ret.size()) && (!(ret.get(ip) instanceof ActionNop))) { + a = ret.get(ip); + } a.setAddress(prevIp, SWF.DEFAULT_VERSION); int info = a.actionLength + 1 + ((a.actionCode > 0x80) ? 2 : 0); int actual = 0; @@ -780,25 +813,36 @@ public class SWFInputStream extends InputStream { if (top.toBoolean()) { newip = rri.getPos() + aif.offset; //rri.setPos(newip); - if (!enableVariables) { + if (((!enableVariables) || (!top.isVariableComputed())) && (!aif.ignoreUsed)) { a = new ActionJump(aif.offset); a.setAddress(aif.getAddress(), SWF.DEFAULT_VERSION); } + aif.jumpUsed = true; + if (aif.ignoreUsed) { + aif.compileTime = false; + } if (debugMode) { System.out.println("jump"); } } else { + aif.ignoreUsed = true; + if (aif.jumpUsed) { + aif.compileTime = false; + } if (debugMode) { System.out.println("ignore"); } - if (!enableVariables) { + if (((!enableVariables) || (!top.isVariableComputed())) && (!aif.jumpUsed)) { a = new ActionNop(); a.setAddress(aif.getAddress(), SWF.DEFAULT_VERSION); } } - if (!enableVariables) { + if (((!enableVariables) || (!top.isVariableComputed())) && (!(aif.jumpUsed && aif.ignoreUsed))) { List needed = top.getNeededSources(); for (GraphSourceItemPos ig : needed) { + if (ig.item == null) { + continue; + } if (ig.item instanceof ActionPush) { if (!((ActionPush) ig.item).ignoredParts.contains(ig.pos)) { ((ActionPush) ig.item).ignoredParts.add(ig.pos); @@ -874,6 +918,8 @@ public class SWFInputStream extends InputStream { rri.setPos(ip); filePos = rri.getPos(); if (goaif) { + aif.ignoreUsed = true; + aif.jumpUsed = true; int oldPos = rri.getPos(); Stack substack = (Stack) stack.clone(); if (readActionListAtPos(enableVariables, localData, substack, cpool, sis, rri, rri.getPos() + aif.offset, ret, startIp)) { diff --git a/trunk/src/com/jpexs/decompiler/flash/action/Action.java b/trunk/src/com/jpexs/decompiler/flash/action/Action.java index d6ebfc21c..2fbca0dde 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/Action.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/Action.java @@ -648,7 +648,7 @@ public class Action implements GraphSourceItem { break; } Action action = actions.get(ip); - + //System.out.println(" ip "+ip+" "+action); //return in for..in if ((action instanceof ActionPush) && (((ActionPush) action).values.size() == 1) && (((ActionPush) action).values.get(0) instanceof Null)) { if (ip + 3 <= end) { @@ -722,7 +722,11 @@ public class Action implements GraphSourceItem { stack.pop(); ip++; } else { - action.translate(localData, stack, output); + try { + action.translate(localData, stack, output); + } catch (Exception ex) { + //ignore + } } } /*else if (action instanceof ActionStrictEquals) { if ((ip + 1 < actions.size()) && (actions.get(ip + 1) instanceof ActionIf)) { diff --git a/trunk/src/com/jpexs/decompiler/flash/action/ActionGraph.java b/trunk/src/com/jpexs/decompiler/flash/action/ActionGraph.java index f2d75affd..47e889773 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/ActionGraph.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/ActionGraph.java @@ -291,6 +291,12 @@ public class ActionGraph extends Graph { caseCommands.add(cc); } ret = new ArrayList(); + if (!output.isEmpty()) { + if (output.get(output.size() - 1) instanceof StoreRegisterTreeItem) { + output.remove(output.size() - 1); + } + } + ret.addAll(output); SwitchItem sti = new SwitchItem(null, currentLoop, switchedObject, caseValues, caseCommands, defaultCommands, valuesMapping); ret.add(sti); diff --git a/trunk/src/com/jpexs/decompiler/flash/action/ActionGraphSource.java b/trunk/src/com/jpexs/decompiler/flash/action/ActionGraphSource.java index 8005a2634..eaf3b3f90 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/ActionGraphSource.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/ActionGraphSource.java @@ -37,6 +37,10 @@ public class ActionGraphSource extends GraphSource { return actions.get(pos); } + public void set(int pos, Action t) { + actions.set(pos, t); + } + @Override public boolean isEmpty() { return actions.isEmpty(); diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionIf.java b/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionIf.java index 79b52c858..1804ec564 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionIf.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionIf.java @@ -34,6 +34,8 @@ public class ActionIf extends Action { public int offset; public String identifier; public boolean compileTime; + public boolean jumpUsed = false; + public boolean ignoreUsed = false; public ActionIf(SWFInputStream sis) throws IOException { super(0x9D, 2); diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java b/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java index 82bc98dcf..932947670 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java @@ -237,7 +237,11 @@ public class ActionPush extends Action { ((RegisterNumber) o).name = regNames.get(((RegisterNumber) o).number); } } - stack.push(new DirectValueTreeItem(this, pos, o, constantPool)); + DirectValueTreeItem dvt = new DirectValueTreeItem(this, pos, o, constantPool); + stack.push(dvt); + if (o instanceof RegisterNumber) { + dvt.computedRegValue = variables.get("__register" + ((RegisterNumber) o).number); + } pos++; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf5/ActionStackSwap.java b/trunk/src/com/jpexs/decompiler/flash/action/swf5/ActionStackSwap.java index a3005ab30..4bdd94c67 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf5/ActionStackSwap.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf5/ActionStackSwap.java @@ -17,6 +17,7 @@ package com.jpexs.decompiler.flash.action.swf5; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.graph.GraphSourceItemPos; import com.jpexs.decompiler.flash.graph.GraphTargetItem; import java.util.HashMap; import java.util.List; @@ -39,5 +40,7 @@ public class ActionStackSwap extends Action { GraphTargetItem b = stack.pop(); stack.push(a); stack.push(b); + a.moreSrc.add(new GraphSourceItemPos(this, 0)); + b.moreSrc.add(new GraphSourceItemPos(this, 0)); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf5/ActionStoreRegister.java b/trunk/src/com/jpexs/decompiler/flash/action/swf5/ActionStoreRegister.java index 2689139af..0035b1928 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf5/ActionStoreRegister.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf5/ActionStoreRegister.java @@ -68,6 +68,7 @@ public class ActionStoreRegister extends Action { if (regNames.containsKey(registerNumber)) { rn.name = regNames.get(registerNumber); } + variables.put("__register" + registerNumber, item); output.add(new StoreRegisterTreeItem(this, rn, item)); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DirectValueTreeItem.java b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DirectValueTreeItem.java index 258b0ee16..240f77249 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DirectValueTreeItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/treemodel/DirectValueTreeItem.java @@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.action.treemodel; import com.jpexs.decompiler.flash.action.swf4.ConstantIndex; import com.jpexs.decompiler.flash.action.swf4.Null; import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.GraphTargetItem; import com.jpexs.decompiler.flash.helpers.Helper; import java.util.List; @@ -26,6 +27,7 @@ public class DirectValueTreeItem extends TreeItem { public Object value; public List constants; + public GraphTargetItem computedRegValue; public DirectValueTreeItem(GraphSourceItem instruction, int instructionPos, Object value, List constants) { super(instruction, PRECEDENCE_PRIMARY); @@ -34,8 +36,19 @@ public class DirectValueTreeItem extends TreeItem { this.pos = instructionPos; } + @Override + public boolean isVariableComputed() { + if (computedRegValue != null) { + return true; + } + return false; + } + @Override public double toNumber() { + if (computedRegValue != null) { + return computedRegValue.toNumber(); + } if (value instanceof Double) { return (Double) value; } @@ -53,6 +66,9 @@ public class DirectValueTreeItem extends TreeItem { @Override public boolean toBoolean() { + if (computedRegValue != null) { + return computedRegValue.toBoolean(); + } if (value instanceof Boolean) { return (Boolean) value; } @@ -132,6 +148,6 @@ public class DirectValueTreeItem extends TreeItem { @Override public boolean isCompileTime() { - return (value instanceof Double) || (value instanceof Float) || (value instanceof Boolean) || (value instanceof Long) || (value instanceof Null); + return (value instanceof Double) || (value instanceof Float) || (value instanceof Boolean) || (value instanceof Long) || (value instanceof Null) || (computedRegValue != null && computedRegValue.isCompileTime()); } }