diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java index abb457414..7943573d3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java @@ -21,7 +21,7 @@ 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.deobfuscation.ActionDeobfuscatorSimpleFast; +import com.jpexs.decompiler.flash.action.deobfuscation.ActionDeobfuscator; import com.jpexs.decompiler.flash.action.model.ActionItem; import com.jpexs.decompiler.flash.action.model.ConstantPool; import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; @@ -835,7 +835,7 @@ public abstract class Action implements GraphSourceItem { SWFDecompilerPlugin.fireActionTreeCreated(tree, swf); int deobfuscationMode = Configuration.autoDeobfuscate.get() ? (Configuration.deobfuscationOldMode.get() ? 0 : 1) : -1; if (deobfuscationMode == 1) { - new ActionDeobfuscatorSimpleFast().actionTreeCreated(tree, swf); + new ActionDeobfuscator().actionTreeCreated(tree, swf); } Graph.graphToString(tree, new NulWriter(), new LocalData()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionListReader.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionListReader.java index d8ca84402..875a85787 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionListReader.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionListReader.java @@ -18,7 +18,7 @@ package com.jpexs.decompiler.flash.action; import com.jpexs.decompiler.flash.DisassemblyListener; import com.jpexs.decompiler.flash.SWFInputStream; -import com.jpexs.decompiler.flash.action.deobfuscation.ActionDeobfuscatorSimpleFast; +import com.jpexs.decompiler.flash.action.deobfuscation.ActionDeobfuscator; import com.jpexs.decompiler.flash.action.model.ConstantPool; import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; import com.jpexs.decompiler.flash.action.special.ActionDeobfuscateJump; @@ -179,7 +179,7 @@ public class ActionListReader { } else if (deobfuscationMode == 1) { try { try (Statistics s = new Statistics("ActionDeobfuscatorSimpleFast")) { - new ActionDeobfuscatorSimpleFast().actionListParsed(actions, sis.getSwf()); + new ActionDeobfuscator().actionListParsed(actions, sis.getSwf()); } } catch (ThreadDeath | InterruptedException ex) { throw ex; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/LocalDataArea.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/LocalDataArea.java index 2dc527f0e..ed50e54d9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/LocalDataArea.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/LocalDataArea.java @@ -18,10 +18,13 @@ package com.jpexs.decompiler.flash.action; import com.jpexs.decompiler.flash.ecma.EcmaScript; import java.util.HashMap; +import java.util.List; import java.util.Stack; public class LocalDataArea { + public List constantPool; + public Stack stack = new Stack<>(); public HashMap localVariables = new HashMap<>(); @@ -33,6 +36,7 @@ public class LocalDataArea { public String executionException; public void clear() { + constantPool = null; stack.clear(); localVariables.clear(); jump = null; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/ActionDeobfuscator.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/ActionDeobfuscator.java index f67a2c070..5101072c7 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/ActionDeobfuscator.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/ActionDeobfuscator.java @@ -17,15 +17,16 @@ package com.jpexs.decompiler.flash.action.deobfuscation; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.ActionList; import com.jpexs.decompiler.flash.action.ActionListReader; -import com.jpexs.decompiler.flash.action.ActionLocalData; -import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; -import com.jpexs.decompiler.flash.action.model.ReturnActionItem; +import com.jpexs.decompiler.flash.action.LocalDataArea; +import com.jpexs.decompiler.flash.action.fastactionlist.ActionItem; +import com.jpexs.decompiler.flash.action.fastactionlist.FastActionList; +import com.jpexs.decompiler.flash.action.fastactionlist.FastActionListIterator; import com.jpexs.decompiler.flash.action.special.ActionEnd; import com.jpexs.decompiler.flash.action.swf4.ActionAdd; import com.jpexs.decompiler.flash.action.swf4.ActionAnd; @@ -33,6 +34,7 @@ import com.jpexs.decompiler.flash.action.swf4.ActionAsciiToChar; import com.jpexs.decompiler.flash.action.swf4.ActionCharToAscii; import com.jpexs.decompiler.flash.action.swf4.ActionDivide; import com.jpexs.decompiler.flash.action.swf4.ActionEquals; +import com.jpexs.decompiler.flash.action.swf4.ActionGetTime; import com.jpexs.decompiler.flash.action.swf4.ActionGetVariable; import com.jpexs.decompiler.flash.action.swf4.ActionIf; import com.jpexs.decompiler.flash.action.swf4.ActionJump; @@ -76,77 +78,143 @@ import com.jpexs.decompiler.flash.action.swf5.ActionTypeOf; import com.jpexs.decompiler.flash.action.swf6.ActionGreater; import com.jpexs.decompiler.flash.action.swf6.ActionStringGreater; import com.jpexs.decompiler.flash.ecma.EcmaScript; -import com.jpexs.decompiler.graph.Graph; +import com.jpexs.decompiler.flash.helpers.SWFDecompilerListener; import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.TranslateException; -import com.jpexs.decompiler.graph.TranslateStack; -import java.io.IOException; +import com.jpexs.decompiler.graph.model.FalseItem; +import com.jpexs.decompiler.graph.model.PushItem; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; +import java.util.Stack; /** * * @author JPEXS */ -public class ActionDeobfuscator extends ActionDeobfuscatorSimple { +public class ActionDeobfuscator implements SWFDecompilerListener { - private final int executionLimit = 30000; + private final int executionLimit = 5000; @Override public void actionListParsed(ActionList actions, SWF swf) throws InterruptedException { - Map fakeFunctions = getFakeFunctionResults(actions); - removeUnreachableActions(actions); - removeObfuscationIfs(actions, fakeFunctions); - removeUnreachableActions(actions); - removeZeroJumps(actions); - ActionListReader.fixConstantPools(null, actions); - //rereadActionList(actions, swf); // this call will fix the contant pool assigments - } + FastActionList fastActions = new FastActionList(actions); + fastActions.expandPushes(); + Map fakeFunctions = getFakeFunctionResults(fastActions); + boolean changed = true; + boolean useVariables = false; + while (changed) { + changed = removeGetTimes(fastActions); + changed |= removeObfuscationIfs(fastActions, fakeFunctions, useVariables); + changed |= removeObfuscatedUnusedVariables(fastActions); - private boolean rereadActionList(ActionList actions, SWF swf) throws InterruptedException { - byte[] actionBytes = Action.actionsToBytes(actions, true, SWF.DEFAULT_VERSION); - try { - SWFInputStream rri = new SWFInputStream(swf, actionBytes); - ActionList newActions = ActionListReader.readActionList(new ArrayList<>(), rri, SWF.DEFAULT_VERSION, 0, actionBytes.length, "", -1); - actions.setActions(newActions); - } catch (IOException ex) { - Logger.getLogger(ActionDeobfuscator.class.getName()).log(Level.SEVERE, null, ex); + actions.setActions(fastActions.toActionList()); + changed |= ActionListReader.fixConstantPools(null, actions); + if (!changed && !useVariables) { + useVariables = true; + changed = true; + } } - return true; + } - private boolean removeObfuscationIfs(ActionList actions, Map fakeFunctions) throws InterruptedException { - if (actions.size() == 0) { + private boolean removeGetTimes(FastActionList actions) { + if (actions.isEmpty()) { return false; } - ActionConstantPool cPool = getConstantPool(actions); - for (int i = 0; i < actions.size(); i++) { - int idx = actions.size() - 1; - int containerIndex = actions.getContainerEndIndex(i); - if (containerIndex != -1) { - idx = Math.min(idx, containerIndex - 1); + boolean ret = false; + boolean changed = true; + int getTimeCount = 1; + while (changed && getTimeCount > 0) { + changed = false; + actions.removeUnreachableActions(); + actions.removeZeroJumps(); + getTimeCount = 0; + + // GetTime, If => Jump, assume GetTime > 0 + FastActionListIterator iterator = actions.iterator(); + while (iterator.hasNext()) { + Action a = iterator.next().action; + ActionItem a2Item = iterator.peek(0); + Action a2 = a2Item.action; + boolean isGetTime = a instanceof ActionGetTime; + if (isGetTime) { + getTimeCount++; + } + + if (isGetTime && a2 instanceof ActionIf) { + ActionJump jump = new ActionJump(0); + ActionItem jumpItem = new ActionItem(jump); + jumpItem.setJumpTarget(a2Item.getJumpTarget()); + iterator.remove(); // GetTime + iterator.next(); + iterator.remove(); // If + iterator.add(jumpItem); // replace If with Jump + changed = true; + ret = true; + getTimeCount--; + } } - ExecutionResult result = new ExecutionResult(); + if (!changed && getTimeCount > 0) { + // GetTime, Increment If => Jump + iterator = actions.iterator(); + while (iterator.hasNext()) { + Action a = iterator.next().action; + Action a1 = iterator.peek(0).action; + ActionItem a2Item = iterator.peek(1); + Action a2 = a2Item.action; + if (a instanceof ActionGetTime && a1 instanceof ActionIncrement && a2 instanceof ActionIf) { + ActionJump jump = new ActionJump(0); + ActionItem jumpItem = new ActionItem(jump); + jumpItem.setJumpTarget(a2Item.getJumpTarget()); + iterator.remove(); // GetTime + iterator.next(); + iterator.remove(); // Increment + iterator.next(); + iterator.remove(); // If + iterator.add(jumpItem); // replace If with Jump + changed = true; + ret = true; + } + } + } + } - // allow uninitialized variables only when the code is execuded from the first line - executeActions(actions, i, idx, cPool, result, fakeFunctions, i == 0); + return ret; + } - if (result.idx != -1 && result.resultValue == null) { - int newIstructionCount = 1; // jump + private boolean removeObfuscationIfs(FastActionList actions, Map fakeFunctions, boolean useVariables) throws InterruptedException { + if (actions.isEmpty()) { + return false; + } + + boolean ret = false; + actions.removeUnreachableActions(); + actions.removeZeroJumps(); + + ActionConstantPool cPool = getConstantPool(actions); + LocalDataArea localData = new LocalDataArea(); + localData.stack = new FixItemCounterStack(); + ExecutionResult result = new ExecutionResult(); + FastActionListIterator iterator = actions.iterator(); + boolean first = true; + while (iterator.hasNext()) { + ActionItem actionItem = iterator.next(); + result.clear(); + localData.clear(); + executeActions(actionItem, localData, cPool, result, fakeFunctions, useVariables, first); + + if (result.item != null && result.resultValue == null) { + int newIstructionCount = 1 /*jump */ + result.stack.size(); if (result.constantPool != null) { newIstructionCount++; } - newIstructionCount += result.stack.size(); - newIstructionCount += 3 * result.variables.size(); /* 2x Push + Set or Define */ boolean allValueValid = true; @@ -157,67 +225,128 @@ public class ActionDeobfuscator extends ActionDeobfuscatorSimple { } } - List unreachable = actions.getUnreachableActions(i, result.idx); - int unreachableCount = getActionCount(unreachable); + int unreachableCount = actions.getUnreachableActionCount(actionItem, result.item); - if (allValueValid && newIstructionCount + 2 < unreachableCount) { - Action target = actions.get(result.idx); - Action prevAction = actions.get(i); - - if (result.constantPool != null) { - ActionConstantPool constantPool2 = new ActionConstantPool(new ArrayList<>(result.constantPool.constantPool)); - actions.addAction(i++, constantPool2); - prevAction = constantPool2; - } - - for (String variableName : result.variables.keySet()) { - Object value = result.variables.get(variableName); - ActionPush push = new ActionPush(variableName); - push.values.add(value); - push.setAddress(prevAction.getAddress()); - actions.addAction(i++, push); - prevAction = push; - - if (result.defines.contains(variableName)) { - ActionDefineLocal defineLocal = new ActionDefineLocal(); - defineLocal.setAddress(prevAction.getAddress()); - actions.addAction(i++, defineLocal); - prevAction = defineLocal; - } else { - ActionSetVariable setVariable = new ActionSetVariable(); - setVariable.setAddress(prevAction.getAddress()); - actions.addAction(i++, setVariable); - prevAction = setVariable; + if (allValueValid && newIstructionCount < unreachableCount) { + if (result.stack.isEmpty() && result.variables.isEmpty() && result.constantPool == null && actionItem.action instanceof ActionJump) { + actionItem.setJumpTarget(result.item); + } else { + ActionItem prevActionItem = actionItem.prev; + if (result.constantPool != null) { + ActionConstantPool constantPool2 = new ActionConstantPool(new ArrayList<>(result.constantPool.constantPool)); + ActionItem constantPoolItem = new ActionItem(constantPool2); + iterator.addBefore(constantPoolItem); } - } - if (!result.stack.isEmpty()) { - ActionPush push = new ActionPush(0); - push.values.clear(); - for (GraphTargetItem graphTargetItem : result.stack) { - push.values.add(graphTargetItem.getResult()); + for (String variableName : result.variables.keySet()) { + Object value = result.variables.get(variableName); + ActionPush push = new ActionPush(variableName); + ActionItem pushItem = new ActionItem(push); + iterator.addBefore(pushItem); + push = new ActionPush(value); + pushItem = new ActionItem(push); + iterator.addBefore(pushItem); + + if (result.defines.contains(variableName)) { + ActionDefineLocal defineLocal = new ActionDefineLocal(); + ActionItem defineLocalItem = new ActionItem(defineLocal); + iterator.addBefore(defineLocalItem); + } else { + ActionSetVariable setVariable = new ActionSetVariable(); + ActionItem setVariableItem = new ActionItem(setVariable); + iterator.addBefore(setVariableItem); + } } - push.setAddress(prevAction.getAddress()); - actions.addAction(i++, push); - prevAction = push; + + if (!result.stack.isEmpty()) { + for (Object obj : result.stack) { + ActionPush push = new ActionPush(obj); + ActionItem pushItem = new ActionItem(push); + iterator.addBefore(pushItem); + } + } + + ActionJump jump = new ActionJump(0); + ActionItem jumpItem = new ActionItem(jump); + jumpItem.setJumpTarget(result.item); + iterator.addBefore(jumpItem); + + actions.replaceJumpTargets(actionItem, prevActionItem.next); } - ActionJump jump = new ActionJump(0); - jump.setAddress(prevAction.getAddress()); - jump.setJumpOffset((int) (target.getAddress() - jump.getAddress() - jump.getTotalActionLength())); - actions.addAction(i++, jump); + ActionItem prevItem = actionItem.prev; - return true; + actions.removeUnreachableActions(); + actions.removeZeroJumps(); + + iterator.setCurrent(prevItem.next.next); + ret = true; + } + } + + first = false; + } + + return ret; + } + + private boolean removeObfuscatedUnusedVariables(FastActionList actions) throws InterruptedException { + if (actions.isEmpty()) { + return false; + } + + Map pushValues = getPushValues(actions); + + boolean ret = false; + + // Push, Push DefineLocal => remove when first pushed value is obfuscated and never used + FastActionListIterator iterator = actions.iterator(); + while (iterator.hasNext()) { + Action a = iterator.next().action; + Action a1 = iterator.peek(0).action; + Action a2 = iterator.peek(1).action; + if (a instanceof ActionPush && a1 instanceof ActionPush && a2 instanceof ActionDefineLocal) { + ActionPush pushName = (ActionPush) a; + ActionPush pushValue = (ActionPush) a1; + if (pushName.values.size() == 1 && pushValue.values.size() == 1) { + String strName = EcmaScript.toString(pushName.values.get(0), pushName.constantPool); + if (isFakeName(strName) && pushValues.get(strName) == 1) { + iterator.remove(); // Push name + iterator.next(); + iterator.remove(); // Push value + iterator.next(); + iterator.remove(); // DefineLocal + ret = true; + } } } } - return false; + return ret; } - private ActionConstantPool getConstantPool(ActionList actions) { + private Map getPushValues(FastActionList actions) { + Map ret = new HashMap<>(); + for (ActionItem actionItem : actions) { + Action action = actionItem.action; + if (action instanceof ActionPush) { + ActionPush push = (ActionPush) action; + for (int i = 0; i < push.values.size(); i++) { + String str = EcmaScript.toString(push.values.get(i), push.constantPool); + Integer cnt = ret.get(str); + cnt = cnt == null ? 1 : cnt + 1; + ret.put(str, cnt); + } + } + } + + return ret; + } + + private ActionConstantPool getConstantPool(FastActionList actions) { ActionConstantPool cPool = null; - for (Action action : actions) { + for (ActionItem actionItem : actions) { + Action action = actionItem.action; if (action instanceof ActionConstantPool) { if (cPool != null) { // there are multiple constant pools @@ -229,29 +358,85 @@ public class ActionDeobfuscator extends ActionDeobfuscatorSimple { return cPool; } - private void executeActions(ActionList actions, int idx, int endIdx, ActionConstantPool constantPool, ExecutionResult result, Map fakeFunctions, boolean allowGetUninitializedVariables) throws InterruptedException { - List output = new ArrayList<>(); - ActionLocalData localData = new ActionLocalData(); - FixItemCounterTranslateStack stack = new FixItemCounterTranslateStack(""); + private Map getFakeFunctionResults(FastActionList actions) throws InterruptedException { + /* + DefineFunction "fakeName" 0 { + Push 1777 + Return + } + */ + + Map results = new HashMap<>(); + + LocalDataArea localData = new LocalDataArea(); + localData.stack = new FixItemCounterStack(); + ExecutionResult result = new ExecutionResult(); + for (ActionItem actionItem : actions) { + Action action = actionItem.action; + if (action instanceof ActionDefineFunction) { + ActionDefineFunction def = (ActionDefineFunction) action; + if (def.paramNames.isEmpty() && def.functionName.length() > 0) { + // remove funcion only when the function name contains only non printable characters + if (!isFakeName(def.functionName)) { + continue; + } + + result.clear(); + ActionItem lastActionItem = actionItem.getContainerLastActions().get(0); + // has at least 1 inner item + if (lastActionItem != actionItem) { + actions.setExcludedFlags(true); + ActionItem actionItem2 = actionItem; + do { + actionItem2.excluded = false; + actionItem2 = actionItem2.next; + } while (actionItem2 != lastActionItem && actionItem2 != actions.last()); + actionItem2.excluded = false; + localData.clear(); + executeActions(actionItem.next, localData, null, result, null, true, false); + if (result.resultValue != null) { + results.put(def.functionName, result.resultValue); + actions.removeIncludedActions(); + } + } + } + } + } + + actions.setExcludedFlags(false); + return results; + } + + protected boolean isFakeName(String name) { + for (char ch : name.toCharArray()) { + if (ch > 31) { + return false; + } + } + + return true; + } + + private void executeActions(ActionItem item, LocalDataArea localData, ActionConstantPool constantPool, ExecutionResult result, Map fakeFunctions, boolean useVariables, boolean allowGetUninitializedVariables) throws InterruptedException { + FixItemCounterStack stack = (FixItemCounterStack) localData.stack; int instructionsProcessed = 0; ActionConstantPool lastConstantPool = null; while (true) { + if (item.isExcluded()) { + break; + } + if (Thread.currentThread().isInterrupted()) { throw new InterruptedException(); } - if (idx > endIdx) { - break; - } - - Action action = actions.get(idx); - instructionsProcessed++; - if (instructionsProcessed > executionLimit) { break; } + Action action = item.action; + /*System.out.print(action.getASMSource(actions, new ArrayList(), ScriptExportMode.PCODE)); for (int j = 0; j < stack.size(); j++) { System.out.print(" '" + stack.get(j).getResult() + "'"); @@ -263,26 +448,20 @@ public class ActionDeobfuscator extends ActionDeobfuscatorSimple { if (action instanceof ActionDefineLocal) { if (stack.size() < 2) { - return; + break; } - String variableName = stack.peek(2).getResult().toString(); + String variableName = EcmaScript.toString(stack.peek(2)); result.defines.add(variableName); } if (action instanceof ActionGetVariable) { if (stack.isEmpty()) { - return; - } - - GraphTargetItem variableNameObj = stack.peek(); - if (!(variableNameObj instanceof DirectValueActionItem)) { - // avoid dynamic variable names, for example: eval("item" add i); break; } - String variableName = variableNameObj.getResult().toString(); - if (!localData.variables.containsKey(variableName) + String variableName = stack.peek().toString(); + if (!localData.localVariables.containsKey(variableName) && (!allowGetUninitializedVariables || !isFakeName(variableName))) { break; } @@ -290,25 +469,20 @@ public class ActionDeobfuscator extends ActionDeobfuscatorSimple { if (action instanceof ActionSetVariable) { if (stack.size() < 2) { - return; - } - - if (!(stack.peek(2) instanceof DirectValueActionItem)) { - // avoid dynamic variable names, for example: set("item" add i, 1); break; } } if (action instanceof ActionCallFunction) { if (stack.size() < 2) { - return; + break; } - String functionName = stack.pop().getResult().toString(); - long numArgs = EcmaScript.toUint32(stack.pop().getResult()); + String functionName = stack.pop().toString(); + long numArgs = EcmaScript.toUint32(stack.pop()); if (numArgs == 0) { if (fakeFunctions != null && fakeFunctions.containsKey(functionName)) { - stack.push(new DirectValueActionItem(fakeFunctions.get(functionName))); + stack.push(fakeFunctions.get(functionName)); } else { break; } @@ -316,17 +490,24 @@ public class ActionDeobfuscator extends ActionDeobfuscatorSimple { break; } } else { - // do not throw EmptyStackException, much faster - int requiredStackSize = action.getStackPopCount(localData, stack); - if (stack.size() < requiredStackSize) { - return; + if (!action.execute(localData)) { + break; } + } - action.translate(localData, stack, output, Graph.SOP_USE_STATIC, ""); + if (!useVariables && (action instanceof ActionDefineLocal + || action instanceof ActionGetVariable + || action instanceof ActionSetVariable + || action instanceof ActionConstantPool + || action instanceof ActionCallFunction + || action instanceof ActionReturn + || action instanceof ActionEnd)) { + break; } if (!(action instanceof ActionPush || action instanceof ActionPushDuplicate + //|| action instanceof ActionPop || action instanceof ActionAsciiToChar || action instanceof ActionCharToAscii || action instanceof ActionDecrement @@ -353,7 +534,7 @@ public class ActionDeobfuscator extends ActionDeobfuscatorSimple { || action instanceof ActionEquals2 || action instanceof ActionGreater || action instanceof ActionLess - || action instanceof ActionLess2 + || action instanceof ActionLess2 // todo: fix (tz.swf/frame_6/DoAction: _loc3_.icon.gotoAndStop((Number(item.cost) || 0) >= 0?1:2) || action instanceof ActionModulo || action instanceof ActionMultiply || action instanceof ActionOr @@ -362,11 +543,11 @@ public class ActionDeobfuscator extends ActionDeobfuscatorSimple { || action instanceof ActionStringGreater || action instanceof ActionStringLess || action instanceof ActionSubtract - || action instanceof ActionDefineLocal + || action instanceof ActionIf || action instanceof ActionJump + || action instanceof ActionDefineLocal || action instanceof ActionGetVariable || action instanceof ActionSetVariable - || action instanceof ActionIf || action instanceof ActionConstantPool || action instanceof ActionCallFunction || action instanceof ActionReturn @@ -377,6 +558,7 @@ public class ActionDeobfuscator extends ActionDeobfuscatorSimple { if (action instanceof ActionPush) { ActionPush push = (ActionPush) action; boolean ok = true; + instructionsProcessed += push.values.size() - 1; for (Object value : push.values) { if ((constantPool == null && value instanceof ConstantIndex) || value instanceof RegisterNumber) { ok = false; @@ -388,48 +570,32 @@ public class ActionDeobfuscator extends ActionDeobfuscatorSimple { } } - /*for (String variable : localData.variables.keySet()) { - System.out.println(Helper.byteArrToString(variable.getBytes())); - }*/ - idx++; - + ActionItem prevItem = item; if (action instanceof ActionJump) { - ActionJump jump = (ActionJump) action; - long address = jump.getTargetAddress(); - idx = actions.getIndexByAddress(address); - if (idx == -1) { - throw new TranslateException("Jump target not found: " + address); - } - } - - if (action instanceof ActionIf) { - ActionIf aif = (ActionIf) action; + item = item.getJumpTarget(); + } else if (action instanceof ActionIf) { if (stack.isEmpty()) { - return; + break; } - if (EcmaScript.toBoolean(stack.pop().getResult())) { - long address = aif.getTargetAddress(); - idx = actions.getIndexByAddress(address); - if (idx == -1) { - throw new TranslateException("If target not found: " + address); - } + if (EcmaScript.toBoolean(stack.pop())) { + item = item.getJumpTarget(); + } else { + item = item.next; } + } else { + item = item.next; } - if (action instanceof ActionDefineFunction) { - List lastActions = actions.getContainerLastActions(action); - int lastActionIdx = actions.getIndexByAction(lastActions.get(0)); - idx = lastActionIdx != -1 ? lastActionIdx + 1 : -1; - } + instructionsProcessed++; - if (/*localData.variables.size() == 1 && */(stack.allItemsFixed() || action instanceof ActionEnd) && !(action instanceof ActionPush)) { - result.idx = idx == actions.size() ? idx - 1 : idx; + if ((stack.allItemsFixed() || action instanceof ActionEnd) && !(action instanceof ActionPush)) { + result.item = item; result.instructionsProcessed = instructionsProcessed; result.constantPool = lastConstantPool; result.variables.clear(); - for (String variableName : localData.variables.keySet()) { - Object value = localData.variables.get(variableName).getResult(); + for (String variableName : localData.localVariables.keySet()) { + Object value = localData.localVariables.get(variableName); result.variables.put(variableName, value); } result.stack.clear(); @@ -437,50 +603,23 @@ public class ActionDeobfuscator extends ActionDeobfuscatorSimple { } if (action instanceof ActionReturn) { - if (output.size() > 0) { - ReturnActionItem ret = (ReturnActionItem) output.get(output.size() - 1); - result.resultValue = ret.value.getResult(); - } + result.resultValue = localData.returnValue; + break; + } else if (action instanceof ActionEnd) { + result.item = prevItem; break; } } } - private Map getFakeFunctionResults(ActionList actions) throws InterruptedException { - /* - DefineFunction "fakeName" 0 { - Push 1777 - Return - } - */ - - Map results = new HashMap<>(); - - for (int i = 0; i < actions.size(); i++) { - Action action = actions.get(i); - if (action instanceof ActionDefineFunction) { - ActionDefineFunction def = (ActionDefineFunction) action; - if (def.paramNames.isEmpty()) { - // remove funcion only when the function name contains only non printable characters - if (!isFakeName(def.functionName)) { - continue; - } - - ExecutionResult result = new ExecutionResult(); - List lastActions = actions.getContainerLastActions(action); - int lastActionIdx = actions.getIndexByAction(lastActions.get(0)); - executeActions(actions, i + 1, lastActionIdx, null, result, null, false); - if (result.resultValue != null) { - results.put(def.functionName, result.resultValue); - for (int j = i; j <= lastActionIdx; j++) { - actions.removeAction(i); - } - } - } + @Override + public void actionTreeCreated(List tree, SWF swf) { + if (tree.size() > 0) { + GraphTargetItem firstItem = tree.get(0); + if (firstItem instanceof PushItem && firstItem.value instanceof FalseItem) { + tree.remove(0); } } - - return results; } @Override @@ -500,20 +639,34 @@ public class ActionDeobfuscator extends ActionDeobfuscatorSimple { public void methodBodyParsed(MethodBody body, SWF swf) { } + @Override + public void avm2CodeRemoveTraps(String path, int classIndex, boolean isStatic, int scriptIndex, ABC abc, Trait trait, int methodInfo, MethodBody body) throws InterruptedException { + } + class ExecutionResult { - public int idx = -1; + public ActionItem item; public int instructionsProcessed = -1; + public Stack stack = new Stack<>(); + + public Object resultValue; + public ActionConstantPool constantPool; - public Map variables = new HashMap<>(); + public Map variables = new LinkedHashMap<>(); public Set defines = new HashSet<>(); - public TranslateStack stack = new TranslateStack("?"); - - public Object resultValue; + public void clear() { + item = null; + instructionsProcessed = -1; + stack.clear(); + resultValue = null; + constantPool = null; + variables.clear(); + defines.clear(); + } } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/ActionDeobfuscatorOld.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/ActionDeobfuscatorOld.java new file mode 100644 index 000000000..6ed9441a8 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/ActionDeobfuscatorOld.java @@ -0,0 +1,519 @@ +/* + * Copyright (C) 2010-2015 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.deobfuscation; + +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.SWFInputStream; +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.ActionList; +import com.jpexs.decompiler.flash.action.ActionListReader; +import com.jpexs.decompiler.flash.action.ActionLocalData; +import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; +import com.jpexs.decompiler.flash.action.model.ReturnActionItem; +import com.jpexs.decompiler.flash.action.special.ActionEnd; +import com.jpexs.decompiler.flash.action.swf4.ActionAdd; +import com.jpexs.decompiler.flash.action.swf4.ActionAnd; +import com.jpexs.decompiler.flash.action.swf4.ActionAsciiToChar; +import com.jpexs.decompiler.flash.action.swf4.ActionCharToAscii; +import com.jpexs.decompiler.flash.action.swf4.ActionDivide; +import com.jpexs.decompiler.flash.action.swf4.ActionEquals; +import com.jpexs.decompiler.flash.action.swf4.ActionGetVariable; +import com.jpexs.decompiler.flash.action.swf4.ActionIf; +import com.jpexs.decompiler.flash.action.swf4.ActionJump; +import com.jpexs.decompiler.flash.action.swf4.ActionLess; +import com.jpexs.decompiler.flash.action.swf4.ActionMBAsciiToChar; +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.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable; +import com.jpexs.decompiler.flash.action.swf4.ActionStringAdd; +import com.jpexs.decompiler.flash.action.swf4.ActionStringEquals; +import com.jpexs.decompiler.flash.action.swf4.ActionStringLength; +import com.jpexs.decompiler.flash.action.swf4.ActionStringLess; +import com.jpexs.decompiler.flash.action.swf4.ActionSubtract; +import com.jpexs.decompiler.flash.action.swf4.ActionToInteger; +import com.jpexs.decompiler.flash.action.swf4.ConstantIndex; +import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionAdd2; +import com.jpexs.decompiler.flash.action.swf5.ActionBitAnd; +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.ActionBitURShift; +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.ActionLess2; +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.swf5.ActionToNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionToString; +import com.jpexs.decompiler.flash.action.swf5.ActionTypeOf; +import com.jpexs.decompiler.flash.action.swf6.ActionGreater; +import com.jpexs.decompiler.flash.action.swf6.ActionStringGreater; +import com.jpexs.decompiler.flash.ecma.EcmaScript; +import com.jpexs.decompiler.graph.Graph; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.TranslateException; +import com.jpexs.decompiler.graph.TranslateStack; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author JPEXS + */ +public class ActionDeobfuscatorOld extends ActionDeobfuscatorSimpleOld { + + private final int executionLimit = 30000; + + @Override + public void actionListParsed(ActionList actions, SWF swf) throws InterruptedException { + Map fakeFunctions = getFakeFunctionResults(actions); + removeUnreachableActions(actions); + removeObfuscationIfs(actions, fakeFunctions); + removeUnreachableActions(actions); + removeZeroJumps(actions); + ActionListReader.fixConstantPools(null, actions); + //rereadActionList(actions, swf); // this call will fix the contant pool assigments + } + + private boolean rereadActionList(ActionList actions, SWF swf) throws InterruptedException { + byte[] actionBytes = Action.actionsToBytes(actions, true, SWF.DEFAULT_VERSION); + try { + SWFInputStream rri = new SWFInputStream(swf, actionBytes); + ActionList newActions = ActionListReader.readActionList(new ArrayList<>(), rri, SWF.DEFAULT_VERSION, 0, actionBytes.length, "", -1); + actions.setActions(newActions); + } catch (IOException ex) { + Logger.getLogger(ActionDeobfuscatorOld.class.getName()).log(Level.SEVERE, null, ex); + } + return true; + } + + private boolean removeObfuscationIfs(ActionList actions, Map fakeFunctions) throws InterruptedException { + if (actions.size() == 0) { + return false; + } + + ActionConstantPool cPool = getConstantPool(actions); + for (int i = 0; i < actions.size(); i++) { + int idx = actions.size() - 1; + int containerIndex = actions.getContainerEndIndex(i); + if (containerIndex != -1) { + idx = Math.min(idx, containerIndex - 1); + } + + ExecutionResult result = new ExecutionResult(); + + // allow uninitialized variables only when the code is execuded from the first line + executeActions(actions, i, idx, cPool, result, fakeFunctions, i == 0); + + if (result.idx != -1 && result.resultValue == null) { + int newIstructionCount = 1; // jump + if (result.constantPool != null) { + newIstructionCount++; + } + + newIstructionCount += result.stack.size(); + + newIstructionCount += 3 * result.variables.size(); /* 2x Push + Set or Define */ + + boolean allValueValid = true; + for (Object value : result.variables.values()) { + if (!ActionPush.isValidValue(value)) { + allValueValid = false; + break; + } + } + + List unreachable = actions.getUnreachableActions(i, result.idx); + int unreachableCount = getActionCount(unreachable); + + if (allValueValid && newIstructionCount + 2 < unreachableCount) { + Action target = actions.get(result.idx); + Action prevAction = actions.get(i); + + if (result.constantPool != null) { + ActionConstantPool constantPool2 = new ActionConstantPool(new ArrayList<>(result.constantPool.constantPool)); + actions.addAction(i++, constantPool2); + prevAction = constantPool2; + } + + for (String variableName : result.variables.keySet()) { + Object value = result.variables.get(variableName); + ActionPush push = new ActionPush(variableName); + push.values.add(value); + push.setAddress(prevAction.getAddress()); + actions.addAction(i++, push); + prevAction = push; + + if (result.defines.contains(variableName)) { + ActionDefineLocal defineLocal = new ActionDefineLocal(); + defineLocal.setAddress(prevAction.getAddress()); + actions.addAction(i++, defineLocal); + prevAction = defineLocal; + } else { + ActionSetVariable setVariable = new ActionSetVariable(); + setVariable.setAddress(prevAction.getAddress()); + actions.addAction(i++, setVariable); + prevAction = setVariable; + } + } + + if (!result.stack.isEmpty()) { + ActionPush push = new ActionPush(0); + push.values.clear(); + for (GraphTargetItem graphTargetItem : result.stack) { + push.values.add(graphTargetItem.getResult()); + } + push.setAddress(prevAction.getAddress()); + actions.addAction(i++, push); + prevAction = push; + } + + ActionJump jump = new ActionJump(0); + jump.setAddress(prevAction.getAddress()); + jump.setJumpOffset((int) (target.getAddress() - jump.getAddress() - jump.getTotalActionLength())); + actions.addAction(i++, jump); + + return true; + } + } + } + + return false; + } + + 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 fakeFunctions, boolean allowGetUninitializedVariables) throws InterruptedException { + List output = new ArrayList<>(); + ActionLocalData localData = new ActionLocalData(); + FixItemCounterTranslateStack stack = new FixItemCounterTranslateStack(""); + int instructionsProcessed = 0; + ActionConstantPool lastConstantPool = null; + + while (true) { + if (Thread.currentThread().isInterrupted()) { + throw new InterruptedException(); + } + + if (idx > endIdx) { + break; + } + + Action action = actions.get(idx); + instructionsProcessed++; + + if (instructionsProcessed > executionLimit) { + break; + } + + /*System.out.print(action.getASMSource(actions, new ArrayList(), ScriptExportMode.PCODE)); + for (int j = 0; j < stack.size(); j++) { + System.out.print(" '" + stack.get(j).getResult() + "'"); + } + System.out.println();*/ + if (action instanceof ActionConstantPool) { + lastConstantPool = (ActionConstantPool) action; + } + + if (action instanceof ActionDefineLocal) { + if (stack.size() < 2) { + return; + } + + String variableName = stack.peek(2).getResult().toString(); + result.defines.add(variableName); + } + + if (action instanceof ActionGetVariable) { + if (stack.isEmpty()) { + return; + } + + GraphTargetItem variableNameObj = stack.peek(); + if (!(variableNameObj instanceof DirectValueActionItem)) { + // avoid dynamic variable names, for example: eval("item" add i); + break; + } + + String variableName = variableNameObj.getResult().toString(); + if (!localData.variables.containsKey(variableName) + && (!allowGetUninitializedVariables || !isFakeName(variableName))) { + break; + } + } + + if (action instanceof ActionSetVariable) { + if (stack.size() < 2) { + return; + } + + if (!(stack.peek(2) instanceof DirectValueActionItem)) { + // avoid dynamic variable names, for example: set("item" add i, 1); + break; + } + } + + if (action instanceof ActionCallFunction) { + if (stack.size() < 2) { + return; + } + + String functionName = stack.pop().getResult().toString(); + long numArgs = EcmaScript.toUint32(stack.pop().getResult()); + if (numArgs == 0) { + if (fakeFunctions != null && fakeFunctions.containsKey(functionName)) { + stack.push(new DirectValueActionItem(fakeFunctions.get(functionName))); + } else { + break; + } + } else { + break; + } + } else { + // do not throw EmptyStackException, much faster + int requiredStackSize = action.getStackPopCount(localData, stack); + if (stack.size() < requiredStackSize) { + return; + } + + action.translate(localData, stack, output, Graph.SOP_USE_STATIC, ""); + } + + if (!(action instanceof ActionPush + || action instanceof ActionPushDuplicate + || action instanceof ActionAsciiToChar + || action instanceof ActionCharToAscii + || action instanceof ActionDecrement + || action instanceof ActionIncrement + || action instanceof ActionNot + || action instanceof ActionToInteger + || action instanceof ActionToNumber + || action instanceof ActionToString + || action instanceof ActionTypeOf + || action instanceof ActionStringLength + || action instanceof ActionMBAsciiToChar + || action instanceof ActionMBStringLength + || action instanceof ActionAnd + || action instanceof ActionAdd + || action instanceof ActionAdd2 + || action instanceof ActionBitAnd + || action instanceof ActionBitLShift + || action instanceof ActionBitOr + || action instanceof ActionBitRShift + || action instanceof ActionBitURShift + || action instanceof ActionBitXor + || action instanceof ActionDivide + || action instanceof ActionEquals + || action instanceof ActionEquals2 + || action instanceof ActionGreater + || action instanceof ActionLess + || action instanceof ActionLess2 + || action instanceof ActionModulo + || action instanceof ActionMultiply + || action instanceof ActionOr + || action instanceof ActionStringAdd + || action instanceof ActionStringEquals + || action instanceof ActionStringGreater + || action instanceof ActionStringLess + || action instanceof ActionSubtract + || action instanceof ActionDefineLocal + || action instanceof ActionJump + || action instanceof ActionGetVariable + || action instanceof ActionSetVariable + || action instanceof ActionIf + || action instanceof ActionConstantPool + || action instanceof ActionCallFunction + || action instanceof ActionReturn + || action instanceof ActionEnd)) { + break; + } + + if (action instanceof ActionPush) { + ActionPush push = (ActionPush) action; + boolean ok = true; + for (Object value : push.values) { + if ((constantPool == null && value instanceof ConstantIndex) || value instanceof RegisterNumber) { + ok = false; + break; + } + } + if (!ok) { + break; + } + } + + /*for (String variable : localData.variables.keySet()) { + System.out.println(Helper.byteArrToString(variable.getBytes())); + }*/ + idx++; + + if (action instanceof ActionJump) { + ActionJump jump = (ActionJump) action; + long address = jump.getTargetAddress(); + idx = actions.getIndexByAddress(address); + if (idx == -1) { + throw new TranslateException("Jump target not found: " + address); + } + } + + if (action instanceof ActionIf) { + ActionIf aif = (ActionIf) action; + if (stack.isEmpty()) { + return; + } + + if (EcmaScript.toBoolean(stack.pop().getResult())) { + long address = aif.getTargetAddress(); + idx = actions.getIndexByAddress(address); + if (idx == -1) { + throw new TranslateException("If target not found: " + address); + } + } + } + + if (action instanceof ActionDefineFunction) { + List lastActions = actions.getContainerLastActions(action); + int lastActionIdx = actions.getIndexByAction(lastActions.get(0)); + idx = lastActionIdx != -1 ? lastActionIdx + 1 : -1; + } + + if (/*localData.variables.size() == 1 && */(stack.allItemsFixed() || action instanceof ActionEnd) && !(action instanceof ActionPush)) { + result.idx = idx == actions.size() ? idx - 1 : idx; + result.instructionsProcessed = instructionsProcessed; + result.constantPool = lastConstantPool; + result.variables.clear(); + for (String variableName : localData.variables.keySet()) { + Object value = localData.variables.get(variableName).getResult(); + result.variables.put(variableName, value); + } + result.stack.clear(); + result.stack.addAll(stack); + } + + if (action instanceof ActionReturn) { + if (output.size() > 0) { + ReturnActionItem ret = (ReturnActionItem) output.get(output.size() - 1); + result.resultValue = ret.value.getResult(); + } + break; + } + } + } + + private Map getFakeFunctionResults(ActionList actions) throws InterruptedException { + /* + DefineFunction "fakeName" 0 { + Push 1777 + Return + } + */ + + Map results = new HashMap<>(); + + for (int i = 0; i < actions.size(); i++) { + Action action = actions.get(i); + if (action instanceof ActionDefineFunction) { + ActionDefineFunction def = (ActionDefineFunction) action; + if (def.paramNames.isEmpty()) { + // remove funcion only when the function name contains only non printable characters + if (!isFakeName(def.functionName)) { + continue; + } + + ExecutionResult result = new ExecutionResult(); + List lastActions = actions.getContainerLastActions(action); + int lastActionIdx = actions.getIndexByAction(lastActions.get(0)); + executeActions(actions, i + 1, lastActionIdx, null, result, null, false); + if (result.resultValue != null) { + results.put(def.functionName, result.resultValue); + for (int j = i; j <= lastActionIdx; j++) { + actions.removeAction(i); + } + } + } + } + } + + return results; + } + + @Override + public byte[] proxyFileCatched(byte[] data) { + return null; + } + + @Override + public void swfParsed(SWF swf) { + } + + @Override + public void abcParsed(ABC abc, SWF swf) { + } + + @Override + public void methodBodyParsed(MethodBody body, SWF swf) { + } + + class ExecutionResult { + + public int idx = -1; + + public int instructionsProcessed = -1; + + public ActionConstantPool constantPool; + + public Map variables = new HashMap<>(); + + public Set defines = new HashSet<>(); + + public TranslateStack stack = new TranslateStack("?"); + + public Object resultValue; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/ActionDeobfuscatorSimpleFast.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/ActionDeobfuscatorSimpleFastOld.java similarity index 99% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/ActionDeobfuscatorSimpleFast.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/ActionDeobfuscatorSimpleFastOld.java index 52e38c36b..cd3a5c254 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/ActionDeobfuscatorSimpleFast.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/ActionDeobfuscatorSimpleFastOld.java @@ -97,7 +97,7 @@ import java.util.Set; * * @author JPEXS */ -public class ActionDeobfuscatorSimpleFast implements SWFDecompilerListener { +public class ActionDeobfuscatorSimpleFastOld implements SWFDecompilerListener { private final int executionLimit = 30000; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/ActionDeobfuscatorSimple.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/ActionDeobfuscatorSimpleOld.java similarity index 99% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/ActionDeobfuscatorSimple.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/ActionDeobfuscatorSimpleOld.java index 126b10c37..e7e679386 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/ActionDeobfuscatorSimple.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/ActionDeobfuscatorSimpleOld.java @@ -78,7 +78,7 @@ import java.util.List; * * @author JPEXS */ -public class ActionDeobfuscatorSimple implements SWFDecompilerListener { +public class ActionDeobfuscatorSimpleOld implements SWFDecompilerListener { private final int executionLimit = 30000; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/FixItemCounterStack.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/FixItemCounterStack.java new file mode 100644 index 000000000..551193696 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/deobfuscation/FixItemCounterStack.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2010-2015 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.deobfuscation; + +import java.util.Stack; + +/** + * + * @author JPEXS + */ +public class FixItemCounterStack extends Stack { + + private int fixItemCount = Integer.MAX_VALUE; + + public FixItemCounterStack() { + } + + public Object peek(int index) { + return super.get(size() - index); + } + + @Override + public Object pop() { + Object result = super.pop(); + int itemCount = size(); + if (itemCount < fixItemCount) { + fixItemCount = itemCount; + } + return result; + } + + @Override + public Object remove(int index) { + if (index < fixItemCount) { + fixItemCount = index; + } + return super.remove(index); + } + + public boolean allItemsFixed() { + return size() <= fixItemCount; + } + + public int getFixItemCount() { + return fixItemCount; + } + + @Override + public void clear() { + fixItemCount = Integer.MAX_VALUE; + super.clear(); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/AsciiToCharActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/AsciiToCharActionItem.java index 432aa92f7..1f86fbbe4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/AsciiToCharActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/AsciiToCharActionItem.java @@ -51,7 +51,16 @@ public class AsciiToCharActionItem extends ActionItem { @Override public Object getResult() { - return ActionAsciiToChar.getResult(value.getResultAsNumber()); + return getResult(value.getResultAsNumber()); + } + + public static String getResult(Double ascii) { + int res = (int) (double) ascii; + if (res == 0) { + return ""; + } + + return ((Character) (char) res).toString(); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/CharToAsciiActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/CharToAsciiActionItem.java index 85a46a521..ca5db18b1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/CharToAsciiActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/CharToAsciiActionItem.java @@ -66,12 +66,16 @@ public class CharToAsciiActionItem extends ActionItem { @Override public Object getResult() { - Object res = value.getResult(); - String s = res.toString(); + return getResult(value.getResult()); + } + + public static int getResult(Object ch) { + String s = ch.toString(); if (s.length() > 0) { char c = s.charAt(0); return (int) c; } + return 0; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/DecrementActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/DecrementActionItem.java index 6dc40165b..3e796eb4d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/DecrementActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/DecrementActionItem.java @@ -62,7 +62,11 @@ public class DecrementActionItem extends ActionItem { @Override public Object getResult() { - return object.getResultAsNumber() - 1; + return getResult(object.getResultAsNumber()); + } + + public static Double getResult(Double num) { + return num - 1; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/IncrementActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/IncrementActionItem.java index 4dca32f79..d4247ea22 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/IncrementActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/IncrementActionItem.java @@ -62,7 +62,11 @@ public class IncrementActionItem extends ActionItem { @Override public Object getResult() { - return object.getResultAsNumber() + 1; + return getResult(object.getResultAsNumber()); + } + + public static Double getResult(Double num) { + return num + 1; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/MBAsciiToCharActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/MBAsciiToCharActionItem.java index f28d44c57..9cc5f5a26 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/MBAsciiToCharActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/MBAsciiToCharActionItem.java @@ -51,7 +51,11 @@ public class MBAsciiToCharActionItem extends ActionItem { @Override public Object getResult() { - int res = (int) (double) (value.getResultAsNumber()); + return getResult(value.getResultAsNumber()); + } + + public static String getResult(Double ascii) { + int res = (int) (double) ascii; if (res == 0) { return ""; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/MBCharToAsciiActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/MBCharToAsciiActionItem.java index bc4160941..85ccda54a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/MBCharToAsciiActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/MBCharToAsciiActionItem.java @@ -49,6 +49,21 @@ public class MBCharToAsciiActionItem extends ActionItem { return ret; } + @Override + public Object getResult() { + return getResult(value.getResult()); + } + + public static int getResult(Object ch) { + String s = ch.toString(); + if (s.length() > 0) { + char c = s.charAt(0); + return (int) c; + } + + return 0; + } + @Override public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { return toSourceMerge(localData, generator, value, new ActionMBCharToAscii()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/MBStringLengthActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/MBStringLengthActionItem.java index 974d9ccba..f6b13e42a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/MBStringLengthActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/MBStringLengthActionItem.java @@ -59,7 +59,11 @@ public class MBStringLengthActionItem extends ActionItem { @Override public Object getResult() { - return EcmaScript.toNumber(EcmaScript.toString(value.getResult()).length()); + return getResult(value.getResult()); + } + + public static Double getResult(Object obj) { + return EcmaScript.toNumber(EcmaScript.toString(obj).length()); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/StringLengthActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/StringLengthActionItem.java index 9a9b98b2b..2f43332a3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/StringLengthActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/StringLengthActionItem.java @@ -51,7 +51,11 @@ public class StringLengthActionItem extends ActionItem { @Override public Object getResult() { - return EcmaScript.toNumber(EcmaScript.toString(value.getResult()).length()); + return getResult(value.getResult()); + } + + public static Double getResult(Object obj) { + return EcmaScript.toNumber(EcmaScript.toString(obj).length()); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToIntegerActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToIntegerActionItem.java index 0fcbf53fd..f388dbe8d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToIntegerActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToIntegerActionItem.java @@ -51,7 +51,11 @@ public class ToIntegerActionItem extends ActionItem { @Override public Object getResult() { - return Math.round(value.getResultAsNumber()); + return getResult(value.getResultAsNumber()); + } + + public static long getResult(Double num) { + return Math.round(num); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToNumberActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToNumberActionItem.java index 3ab026823..9adbe287e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToNumberActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToNumberActionItem.java @@ -51,7 +51,11 @@ public class ToNumberActionItem extends ActionItem { @Override public Object getResult() { - return value.getResultAsNumber(); + return getResult(value.getResultAsNumber()); + } + + public static Double getResult(Double num) { + return num; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToStringActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToStringActionItem.java index 2ab1a02ee..e48080148 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToStringActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToStringActionItem.java @@ -52,7 +52,11 @@ public class ToStringActionItem extends ActionItem { @Override public Object getResult() { - return EcmaScript.toString(value.getResult()); + return getResult(value.getResult()); + } + + public static String getResult(Object obj) { + return EcmaScript.toString(obj); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/TypeOfActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/TypeOfActionItem.java index 3da1f4038..0e50d38a0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/TypeOfActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/TypeOfActionItem.java @@ -18,6 +18,8 @@ package com.jpexs.decompiler.flash.action.model; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.action.swf5.ActionTypeOf; +import com.jpexs.decompiler.flash.ecma.EcmaScript; +import com.jpexs.decompiler.flash.ecma.EcmaType; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; @@ -51,7 +53,28 @@ public class TypeOfActionItem extends ActionItem { @Override public Object getResult() { - return ActionTypeOf.getResult(value.getResult()); + return getResult(value.getResult()); + } + + public static String getResult(Object obj) { + Object res = obj; + EcmaType type = EcmaScript.type(res); + switch (type) { + case STRING: + return "string"; + case BOOLEAN: + return "boolean"; + case NUMBER: + return "number"; + case OBJECT: + return "object"; + case UNDEFINED: + return "undefined"; + case NULL: + return "null"; + } + //TODO: function,movieclip + return "object"; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/AddActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/AddActionItem.java index fb74d9eaf..030246a1e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/AddActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/AddActionItem.java @@ -63,15 +63,17 @@ public class AddActionItem extends BinaryOpItem { @Override public Object getResult() { + return getResult(rightSide.getResult(), leftSide.getResult(), version2); + } + + public static Object getResult(Object rightResult, Object leftResult, boolean version2) { if (version2) { - Object leftResult = leftSide.getResult(); - Object rightResult = rightSide.getResult(); if (EcmaScript.type(leftResult) == EcmaType.STRING || EcmaScript.type(rightResult) == EcmaType.STRING) { return EcmaScript.toString(leftResult) + EcmaScript.toString(rightResult); } return EcmaScript.toNumber(leftResult) + EcmaScript.toNumber(rightResult); } else { - return Action.toFloatPoint(leftSide.getResult()) + Action.toFloatPoint(rightSide.getResult()); + return Action.toFloatPoint(leftResult) + Action.toFloatPoint(rightResult); } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/AndActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/AndActionItem.java index bc2fbfaa9..65fa9476e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/AndActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/AndActionItem.java @@ -1,18 +1,19 @@ /* * Copyright (C) 2010-2015 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. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.action.model.operations; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; @@ -34,7 +35,11 @@ public class AndActionItem extends BinaryOpItem { @Override public Object getResult() { - return EcmaScript.toBoolean(leftSide.getResult()) && EcmaScript.toBoolean(rightSide.getResult()); + return getResult(rightSide.getResult(), leftSide.getResult()); + } + + public static Boolean getResult(Object rightResult, Object leftResult) { + return EcmaScript.toBoolean(leftResult) && EcmaScript.toBoolean(rightResult); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/BitAndActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/BitAndActionItem.java index ec7ec4b89..db1c0abf9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/BitAndActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/BitAndActionItem.java @@ -34,7 +34,11 @@ public class BitAndActionItem extends BinaryOpItem { @Override public Object getResult() { - return ((long) (double) leftSide.getResultAsNumber()) & ((long) (double) rightSide.getResultAsNumber()); + return getResult(rightSide.getResultAsNumber(), leftSide.getResultAsNumber()); + } + + public static long getResult(Double rightResult, Double leftResult) { + return ((long) (double) leftResult) & ((long) (double) rightResult); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/BitOrActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/BitOrActionItem.java index eba667b5c..3cf79d99f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/BitOrActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/BitOrActionItem.java @@ -34,7 +34,11 @@ public class BitOrActionItem extends BinaryOpItem { @Override public Object getResult() { - return ((long) (double) leftSide.getResultAsNumber()) | ((long) (double) rightSide.getResultAsNumber()); + return getResult(rightSide.getResultAsNumber(), leftSide.getResultAsNumber()); + } + + public static long getResult(Double rightResult, Double leftResult) { + return ((long) (double) leftResult) | ((long) (double) rightResult); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/BitXorActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/BitXorActionItem.java index 1106420d6..85cb6b293 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/BitXorActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/BitXorActionItem.java @@ -37,7 +37,11 @@ public class BitXorActionItem extends BinaryOpItem { @Override public Object getResult() { - return ((long) (double) leftSide.getResultAsNumber()) ^ ((long) (double) rightSide.getResultAsNumber()); + return getResult(rightSide.getResultAsNumber(), leftSide.getResultAsNumber()); + } + + public static long getResult(Double rightResult, Double leftResult) { + return ((long) (double) leftResult) ^ ((long) (double) rightResult); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/DivideActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/DivideActionItem.java index 45d6dbad9..8ed3d7bc2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/DivideActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/DivideActionItem.java @@ -34,12 +34,15 @@ public class DivideActionItem extends BinaryOpItem { @Override public Object getResult() { - Double leftResult = leftSide.getResultAsNumber(); - Double rightResult = rightSide.getResultAsNumber(); + return getResult(rightSide.getResultAsNumber(), leftSide.getResultAsNumber()); + } + + public static Double getResult(Double rightResult, Double leftResult) { if (Double.compare(rightResult, 0) == 0) { return leftResult < 0 ? Double.NEGATIVE_INFINITY : leftResult > 0 ? Double.POSITIVE_INFINITY : Double.NaN; } + return leftResult / rightResult; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/EqActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/EqActionItem.java index e36f54aa7..4127b5891 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/EqActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/EqActionItem.java @@ -41,11 +41,15 @@ public class EqActionItem extends BinaryOpItem implements LogicalOpItem, EqualsT @Override public Object getResult() { + return getResult(rightSide.getResult(), leftSide.getResult(), version2); + } + + public static Boolean getResult(Object rightResult, Object leftResult, boolean version2) { if (version2) { - return EcmaScript.equals(leftSide.getResult(), rightSide.getResult()); + return EcmaScript.equals(leftResult, rightResult); } else { //For SWF 4 and older, it should return 1 or 0 - return (Action.toFloatPoint(leftSide.getResult()) == Action.toFloatPoint(rightSide.getResult())); + return (Action.toFloatPoint(leftResult) == Action.toFloatPoint(rightResult)); } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/GtActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/GtActionItem.java index 8ce7abb27..7af539b62 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/GtActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/GtActionItem.java @@ -39,7 +39,11 @@ public class GtActionItem extends BinaryOpItem implements LogicalOpItem { @Override public Object getResult() { - return EcmaScript.compare(rightSide.getResult(), leftSide.getResult()); + return getResult(rightSide.getResult(), leftSide.getResult()); + } + + public static Object getResult(Object rightResult, Object leftResult) { + return EcmaScript.compare(rightResult, leftResult); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/LShiftActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/LShiftActionItem.java index f2f40ac39..9e22bbb57 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/LShiftActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/LShiftActionItem.java @@ -34,7 +34,11 @@ public class LShiftActionItem extends BinaryOpItem { @Override public Object getResult() { - return ((int) (double) leftSide.getResultAsNumber()) << ((int) (double) rightSide.getResultAsNumber()); + return getResult(rightSide.getResultAsNumber(), leftSide.getResultAsNumber()); + } + + public static int getResult(Double rightResult, Double leftResult) { + return ((int) (double) leftResult) << ((int) (double) rightResult); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/LtActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/LtActionItem.java index 44283582d..71f6cbac6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/LtActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/LtActionItem.java @@ -42,11 +42,15 @@ public class LtActionItem extends BinaryOpItem implements LogicalOpItem { @Override public Object getResult() { + return getResult(rightSide.getResult(), leftSide.getResult(), version2); + } + + public static Object getResult(Object rightResult, Object leftResult, boolean version2) { if (version2) { - return EcmaScript.compare(leftSide.getResult(), rightSide.getResult()); + return EcmaScript.compare(leftResult, rightResult); } else { //For SWF 4 and older, it should return 1 or 0 - return Action.toFloatPoint(leftSide.getResult()) < Action.toFloatPoint(rightSide.getResult()); + return Action.toFloatPoint(leftResult) < Action.toFloatPoint(rightResult); } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/ModuloActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/ModuloActionItem.java index 4d841a834..a8f205883 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/ModuloActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/ModuloActionItem.java @@ -34,11 +34,14 @@ public class ModuloActionItem extends BinaryOpItem { @Override public Object getResult() { - Double rightResult = rightSide.getResultAsNumber(); + return getResult(rightSide.getResultAsNumber(), leftSide.getResultAsNumber()); + } + + public static Number getResult(Double rightResult, Double leftResult) { if (Double.isNaN(rightResult) || Double.compare(rightResult, 0) == 0) { return Double.NaN; } - return ((long) (double) leftSide.getResultAsNumber()) % ((long) (double) rightResult); + return ((long) (double) leftResult) % ((long) (double) rightResult); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/MultiplyActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/MultiplyActionItem.java index cedd1b070..d53b0fe46 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/MultiplyActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/MultiplyActionItem.java @@ -34,7 +34,11 @@ public class MultiplyActionItem extends BinaryOpItem { @Override public Object getResult() { - return leftSide.getResultAsNumber() * rightSide.getResultAsNumber(); + return getResult(rightSide.getResultAsNumber(), leftSide.getResultAsNumber()); + } + + public static Double getResult(Double rightResult, Double leftResult) { + return leftResult * rightResult; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/OrActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/OrActionItem.java index c38b622a2..334d774bd 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/OrActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/OrActionItem.java @@ -1,18 +1,19 @@ /* * Copyright (C) 2010-2015 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. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.action.model.operations; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; @@ -34,7 +35,11 @@ public class OrActionItem extends BinaryOpItem { @Override public Object getResult() { - return EcmaScript.toBoolean(leftSide.getResult()) || EcmaScript.toBoolean(rightSide.getResult()); + return getResult(rightSide.getResult(), leftSide.getResult()); + } + + public static Boolean getResult(Object rightResult, Object leftResult) { + return EcmaScript.toBoolean(leftResult) || EcmaScript.toBoolean(rightResult); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/RShiftActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/RShiftActionItem.java index d14d2fcfe..1b8cca908 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/RShiftActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/RShiftActionItem.java @@ -34,8 +34,12 @@ public class RShiftActionItem extends BinaryOpItem { @Override public Object getResult() { - long rightResult = ((long) (double) rightSide.getResultAsNumber()) & 0x1f; - return ((long) (double) leftSide.getResultAsNumber()) >> rightResult; + return getResult(rightSide.getResultAsNumber(), leftSide.getResultAsNumber()); + } + + public static long getResult(Double rightResult, Double leftResult) { + long rightResult2 = ((long) (double) rightResult) & 0x1f; + return ((long) (double) leftResult) >> rightResult2; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StrictEqActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StrictEqActionItem.java index 638f82e08..455c4bbed 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StrictEqActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StrictEqActionItem.java @@ -37,8 +37,12 @@ public class StrictEqActionItem extends BinaryOpItem implements LogicalOpItem, I @Override public Object getResult() { - Object x = leftSide.getResult(); - Object y = rightSide.getResult(); + return getResult(rightSide.getResult(), leftSide.getResult()); + } + + public static boolean getResult(Object rightResult, Object leftResult) { + Object x = leftResult; + Object y = rightResult; return EcmaScript.type(x) == EcmaScript.type(y) && EcmaScript.equals(x, y); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringAddActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringAddActionItem.java index 6f9ed0c96..652d1c9f1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringAddActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringAddActionItem.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.model.operations; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.action.swf4.ActionStringAdd; +import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; @@ -40,7 +41,11 @@ public class StringAddActionItem extends BinaryOpItem { @Override public Object getResult() { - return ActionStringAdd.getResult(leftSide.getResult(), rightSide.getResult()); + return getResult(rightSide.getResult(), leftSide.getResult()); + } + + public static String getResult(Object rightResult, Object leftResult) { + return EcmaScript.toString(leftResult) + EcmaScript.toString(rightResult); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringEqActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringEqActionItem.java index 2383bc1d2..31076c0e2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringEqActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringEqActionItem.java @@ -41,7 +41,11 @@ public class StringEqActionItem extends BinaryOpItem implements Inverted { @Override public Object getResult() { - return EcmaScript.toString(leftSide.getResult()).equals(EcmaScript.toString(rightSide.getResult())); + return getResult(rightSide.getResult(), leftSide.getResult()); + } + + public static Boolean getResult(Object rightResult, Object leftResult) { + return EcmaScript.toString(leftResult).equals(EcmaScript.toString(rightResult)); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringGtActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringGtActionItem.java index 2b9124abf..652d081be 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringGtActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringGtActionItem.java @@ -43,7 +43,11 @@ public class StringGtActionItem extends BinaryOpItem implements Inverted { @Override public Object getResult() { - return EcmaScript.toString(leftSide.getResult()).compareTo(EcmaScript.toString(rightSide.getResult())) > 0; + return getResult(rightSide.getResult(), leftSide.getResult()); + } + + public static boolean getResult(Object rightResult, Object leftResult) { + return EcmaScript.toString(leftResult).compareTo(EcmaScript.toString(rightResult)) > 0; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringLtActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringLtActionItem.java index cf1abc409..f4b10246c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringLtActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringLtActionItem.java @@ -41,7 +41,11 @@ public class StringLtActionItem extends BinaryOpItem implements Inverted { @Override public Object getResult() { - return EcmaScript.toString(leftSide.getResult()).compareTo(EcmaScript.toString(rightSide.getResult())) < 0; + return getResult(rightSide.getResult(), leftSide.getResult()); + } + + public static boolean getResult(Object rightResult, Object leftResult) { + return EcmaScript.toString(leftResult).compareTo(EcmaScript.toString(rightResult)) < 0; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/SubtractActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/SubtractActionItem.java index 097975a94..e1ff63ff9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/SubtractActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/SubtractActionItem.java @@ -37,7 +37,11 @@ public class SubtractActionItem extends BinaryOpItem { @Override public Object getResult() { - return leftSide.getResultAsNumber() - rightSide.getResultAsNumber(); + return getResult(rightSide.getResultAsNumber(), leftSide.getResultAsNumber()); + } + + public static Double getResult(Double rightResult, Double leftResult) { + return leftResult - rightResult; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/URShiftActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/URShiftActionItem.java index 41c8b75db..21799fb90 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/URShiftActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/URShiftActionItem.java @@ -34,9 +34,13 @@ public class URShiftActionItem extends BinaryOpItem { @Override public Object getResult() { - long leftResult = ((long) (double) leftSide.getResultAsNumber()) & 0xffffffffL; - long rightResult = ((long) (double) rightSide.getResultAsNumber()) & 0x1f; - return leftResult >>> rightResult; + return getResult(rightSide.getResultAsNumber(), leftSide.getResultAsNumber()); + } + + public static long getResult(Double rightResult, Double leftResult) { + long leftResult2 = ((long) (double) leftResult) & 0xffffffffL; + long rightResult2 = ((long) (double) rightResult) & 0x1f; + return leftResult2 >>> rightResult2; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/special/ActionEnd.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/special/ActionEnd.java index 7869a4b3a..69061c38f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/special/ActionEnd.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/special/ActionEnd.java @@ -1,21 +1,23 @@ /* * Copyright (C) 2010-2015 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. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.action.special; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; import java.util.HashMap; @@ -38,6 +40,11 @@ public class ActionEnd extends Action { return true; } + @Override + public boolean execute(LocalDataArea lda) { + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { //output.add(new SimpleActionTreeItem(this, "end()")); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionAdd.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionAdd.java index a01bc2a99..ee31e09e5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionAdd.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionAdd.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.AddActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionAdd extends Action { return "Add"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(AddActionItem.getResult(lda.pop(), lda.pop(), false)); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionAnd.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionAnd.java index ebf84766a..913ff3316 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionAnd.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionAnd.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.AndActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionAnd extends Action { return "And"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(AndActionItem.getResult(lda.pop(), lda.pop())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionAsciiToChar.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionAsciiToChar.java index 7e877dfc8..56e3ec8d6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionAsciiToChar.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionAsciiToChar.java @@ -42,19 +42,10 @@ public class ActionAsciiToChar extends Action { return false; } - lda.stack.push(getResult(lda.popAsNumber())); + lda.stack.push(AsciiToCharActionItem.getResult(lda.popAsNumber())); return true; } - public static String getResult(Double ascii) { - int res = (int) (double) ascii; - if (res == 0) { - return ""; - } - - return ((Character) (char) res).toString(); - } - @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionCharToAscii.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionCharToAscii.java index 8191b9c90..889dc7ba3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionCharToAscii.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionCharToAscii.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.CharToAsciiActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionCharToAscii extends Action { return "CharToAscii"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() == 0) { + return false; + } + + lda.stack.push(CharToAsciiActionItem.getResult(lda.pop())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionDivide.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionDivide.java index 60a5aa79c..b00985e80 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionDivide.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionDivide.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.DivideActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionDivide extends Action { return "Divide"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(DivideActionItem.getResult(lda.popAsNumber(), lda.popAsNumber())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionEquals.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionEquals.java index 1af100205..5f0e9d11d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionEquals.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionEquals.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.EqActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionEquals extends Action { return "Equals"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(EqActionItem.getResult(lda.pop(), lda.pop(), false)); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionGetVariable.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionGetVariable.java index 4a53d0381..b1beafe9f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionGetVariable.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionGetVariable.java @@ -18,11 +18,13 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; import com.jpexs.decompiler.flash.action.model.EvalActionItem; import com.jpexs.decompiler.flash.action.model.GetVariableActionItem; import com.jpexs.decompiler.flash.action.model.GetVersionActionItem; import com.jpexs.decompiler.flash.ecma.EcmaScript; +import com.jpexs.decompiler.flash.ecma.Undefined; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; import com.jpexs.decompiler.graph.model.LocalData; @@ -40,6 +42,21 @@ public class ActionGetVariable extends Action { return "GetVariable"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() == 0) { + return false; + } + + Object value = lda.localVariables.get(EcmaScript.toString(lda.pop())); + if (value == null) { + value = Undefined.INSTANCE; + } + + lda.stack.push(value); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem name = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionIf.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionIf.java index e92c8da89..166111d02 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionIf.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionIf.java @@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.ActionList; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.parser.ActionParseException; import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; @@ -100,6 +101,11 @@ public class ActionIf extends Action { return "ActionIf " + offset; } + @Override + public boolean execute(LocalDataArea lda) { + return true; + } + @Override public boolean isBranch() { return true; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionJump.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionJump.java index 8c7888ead..f244411b9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionJump.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionJump.java @@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.ActionList; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.parser.ActionParseException; import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; @@ -100,6 +101,11 @@ public class ActionJump extends Action { return "Jump " + offset; } + @Override + public boolean execute(LocalDataArea lda) { + return true; + } + @Override public boolean isJump() { return true; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionLess.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionLess.java index d52262e83..bca7b11e8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionLess.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionLess.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.LtActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionLess extends Action { return "Less"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(LtActionItem.getResult(lda.pop(), lda.pop(), false)); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionMBAsciiToChar.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionMBAsciiToChar.java index 22d710389..98ca56a7f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionMBAsciiToChar.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionMBAsciiToChar.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.MBAsciiToCharActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionMBAsciiToChar extends Action { return "MBAsciiToChar"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() == 0) { + return false; + } + + lda.stack.push(MBAsciiToCharActionItem.getResult(lda.popAsNumber())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionMBCharToAscii.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionMBCharToAscii.java index 7afb9f510..8a5cf65e2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionMBCharToAscii.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionMBCharToAscii.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.MBCharToAsciiActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionMBCharToAscii extends Action { return "MBCharToAscii"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() == 0) { + return false; + } + + lda.stack.push(MBCharToAsciiActionItem.getResult(lda.pop())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionMBStringLength.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionMBStringLength.java index 781fb8cbf..389e8bf15 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionMBStringLength.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionMBStringLength.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.MBStringLengthActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionMBStringLength extends Action { return "MBStringLength"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() == 0) { + return false; + } + + lda.stack.push(MBStringLengthActionItem.getResult(lda.pop())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionMultiply.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionMultiply.java index 677bc408d..450fe406a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionMultiply.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionMultiply.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.MultiplyActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionMultiply extends Action { return "Multiply"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(MultiplyActionItem.getResult(lda.popAsNumber(), lda.popAsNumber())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionNot.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionNot.java index 81d28f19e..ce2844e25 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionNot.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionNot.java @@ -18,8 +18,10 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.model.NotItem; import java.util.HashMap; import java.util.List; @@ -34,6 +36,16 @@ public class ActionNot extends Action { return "Not"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() == 0) { + return false; + } + + lda.stack.push(NotItem.getResult(lda.pop())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionOr.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionOr.java index f6a049648..c659f14cb 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionOr.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionOr.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.OrActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionOr extends Action { return "Or"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(OrActionItem.getResult(lda.pop(), lda.pop())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java index 86a0945ae..c3c42fcb9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java @@ -320,7 +320,7 @@ public class ActionPush extends Action { String ret; Object value = values.get(i); if (value instanceof ConstantIndex) { - ret = ((ConstantIndex) value).toStringNoQ(constantPool); + ret = ((ConstantIndex) value).toStringNoQ(constantPool, Configuration.resolveConstants.get()); } else if (value instanceof String) { ret = (String) value; } else if (value instanceof RegisterNumber) { @@ -335,7 +335,7 @@ public class ActionPush extends Action { String ret; Object value = values.get(i); if (value instanceof ConstantIndex) { - ret = ((ConstantIndex) value).toString(constantPool); + ret = ((ConstantIndex) value).toString(constantPool, Configuration.resolveConstants.get()); } else if (value instanceof String) { ret = "\"" + Helper.escapeActionScriptString((String) value) + "\""; } else if (value instanceof RegisterNumber) { @@ -377,7 +377,13 @@ public class ActionPush extends Action { @Override public boolean execute(LocalDataArea lda) { for (Object value : values) { - lda.stack.push(value); + if (value instanceof ConstantIndex) { + ConstantIndex constantIndex = (ConstantIndex) value; + List cPool = lda.constantPool != null ? lda.constantPool : constantPool; + lda.stack.push(constantIndex.toStringNoQ(cPool, true)); + } else { + lda.stack.push(value); + } } return true; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionSetVariable.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionSetVariable.java index 3ad7db214..43b12788e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionSetVariable.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionSetVariable.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.StoreTypeAction; import com.jpexs.decompiler.flash.action.model.ConstantPool; import com.jpexs.decompiler.flash.action.model.DecrementActionItem; @@ -49,6 +50,17 @@ public class ActionSetVariable extends Action implements StoreTypeAction { return "SetVariable"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + Object value = lda.pop(); + lda.localVariables.put(EcmaScript.toString(lda.pop()), value); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem value = stack.pop().getThroughDuplicate(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionStringAdd.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionStringAdd.java index 016f0d216..0eadf896e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionStringAdd.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionStringAdd.java @@ -20,7 +20,6 @@ import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.StringAddActionItem; -import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; import java.util.HashMap; @@ -43,14 +42,10 @@ public class ActionStringAdd extends Action { return false; } - lda.stack.push(getResult(lda.pop(), lda.pop())); + lda.stack.push(StringAddActionItem.getResult(lda.pop(), lda.pop())); return true; } - public static String getResult(Object obj1, Object obj2) { - return EcmaScript.toString(obj1) + EcmaScript.toString(obj2); - } - @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionStringEquals.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionStringEquals.java index 990d1322c..b6393fad8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionStringEquals.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionStringEquals.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.StringEqActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionStringEquals extends Action { return "StringEquals"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(StringEqActionItem.getResult(lda.pop(), lda.pop())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionStringLength.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionStringLength.java index 7931857b7..386387687 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionStringLength.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionStringLength.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.StringLengthActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionStringLength extends Action { return "StringLength"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() == 0) { + return false; + } + + lda.stack.push(StringLengthActionItem.getResult(lda.pop())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionStringLess.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionStringLess.java index 0b6d6cb63..bf168eaa4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionStringLess.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionStringLess.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.StringLtActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionStringLess extends Action { return "StringLess"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(StringLtActionItem.getResult(lda.pop(), lda.pop())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionSubtract.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionSubtract.java index 319bc5786..9a52c6ffe 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionSubtract.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionSubtract.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.SubtractActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionSubtract extends Action { return "Subtract"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(SubtractActionItem.getResult(lda.popAsNumber(), lda.popAsNumber())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionToInteger.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionToInteger.java index 3a81c76bc..0ba7e2b88 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionToInteger.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionToInteger.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.ToIntegerActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionToInteger extends Action { return "ToInteger"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() == 0) { + return false; + } + + lda.stack.push(ToIntegerActionItem.getResult(lda.popAsNumber())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ConstantIndex.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ConstantIndex.java index 257b0591f..3a8c29f7d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ConstantIndex.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ConstantIndex.java @@ -16,7 +16,6 @@ */ package com.jpexs.decompiler.flash.action.swf4; -import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.helpers.Helper; import java.io.Serializable; import java.util.List; @@ -29,8 +28,8 @@ public class ConstantIndex implements Serializable { this.index = index; } - public String toStringNoQ(List constantPool) { - if (Configuration.resolveConstants.get()) { + public String toStringNoQ(List constantPool, boolean resolve) { + if (resolve) { if (constantPool != null && index < constantPool.size()) { return constantPool.get(index); } @@ -39,8 +38,8 @@ public class ConstantIndex implements Serializable { return "constant" + index; } - public String toString(List constantPool) { - if (Configuration.resolveConstants.get()) { + public String toString(List constantPool, boolean resolve) { + if (resolve) { if (constantPool != null && index < constantPool.size()) { return "\"" + Helper.escapeActionScriptString(constantPool.get(index)) + "\""; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionAdd2.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionAdd2.java index 1f0bc0c17..5ec52d5fe 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionAdd2.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionAdd2.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf5; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.AddActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionAdd2 extends Action { return "Add2"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(AddActionItem.getResult(lda.pop(), lda.pop(), true)); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitAnd.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitAnd.java index 2b712b644..ecd7e71c4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitAnd.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitAnd.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf5; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.BitAndActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionBitAnd extends Action { return "BitAnd"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(BitAndActionItem.getResult(lda.popAsNumber(), lda.popAsNumber())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitLShift.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitLShift.java index 165445f22..b7f164bb9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitLShift.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitLShift.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf5; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.LShiftActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionBitLShift extends Action { return "BitLShift"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(LShiftActionItem.getResult(lda.popAsNumber(), lda.popAsNumber())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitOr.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitOr.java index 420abc0ca..9c5f68fed 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitOr.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitOr.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf5; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.BitOrActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionBitOr extends Action { return "BitOr"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(BitOrActionItem.getResult(lda.popAsNumber(), lda.popAsNumber())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitRShift.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitRShift.java index c278a9cd6..068db14eb 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitRShift.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitRShift.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf5; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.RShiftActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionBitRShift extends Action { return "BitRShift"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(RShiftActionItem.getResult(lda.popAsNumber(), lda.popAsNumber())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitURShift.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitURShift.java index e2ddb9bf6..657564b73 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitURShift.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitURShift.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf5; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.URShiftActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionBitURShift extends Action { return "BitURShift"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(URShiftActionItem.getResult(lda.popAsNumber(), lda.popAsNumber())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitXor.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitXor.java index ec08f1249..e1a34cfe6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitXor.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionBitXor.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf5; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.BitXorActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionBitXor extends Action { return "BitXor"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(BitXorActionItem.getResult(lda.popAsNumber(), lda.popAsNumber())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionCallFunction.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionCallFunction.java index 9fc0db7d7..30affc49f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionCallFunction.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionCallFunction.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf5; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.CallFunctionActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -37,6 +38,11 @@ public class ActionCallFunction extends Action { return "CallFunction"; } + @Override + public boolean execute(LocalDataArea lda) { + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem functionName = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionConstantPool.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionConstantPool.java index fbd571b8c..74da4e976 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionConstantPool.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionConstantPool.java @@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.action.swf5; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.parser.ActionParseException; import com.jpexs.decompiler.flash.action.parser.pcode.ASMParsedSymbol; import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer; @@ -103,6 +104,11 @@ public class ActionConstantPool extends Action { return ret.toString(); } + @Override + public boolean execute(LocalDataArea lda) { + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionDecrement.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionDecrement.java index d3ad096eb..51cd9ceb4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionDecrement.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionDecrement.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf5; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.DecrementActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionDecrement extends Action { return "Decrement"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() == 0) { + return false; + } + + lda.stack.push(DecrementActionItem.getResult(lda.popAsNumber())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionDefineLocal.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionDefineLocal.java index 051628e47..63bdf88cf 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionDefineLocal.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionDefineLocal.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf5; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.DefineLocalActionItem; import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; import com.jpexs.decompiler.flash.ecma.EcmaScript; @@ -38,6 +39,17 @@ public class ActionDefineLocal extends Action { return "DefineLocal"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + Object value = lda.pop(); + lda.localVariables.put(EcmaScript.toString(lda.pop()), value); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem value = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionEquals2.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionEquals2.java index f66f2e1cb..cfc0afbe2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionEquals2.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionEquals2.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf5; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.EqActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionEquals2 extends Action { return "Equals2"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(EqActionItem.getResult(lda.pop(), lda.pop(), true)); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionIncrement.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionIncrement.java index e8bfb2153..a6045d2f4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionIncrement.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionIncrement.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf5; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.IncrementActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionIncrement extends Action { return "Increment"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() == 0) { + return false; + } + + lda.stack.push(IncrementActionItem.getResult(lda.popAsNumber())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionLess2.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionLess2.java index b33fbce96..362a60d5e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionLess2.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionLess2.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf5; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.LtActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionLess2 extends Action { return "Less2"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(LtActionItem.getResult(lda.pop(), lda.pop(), true)); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionModulo.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionModulo.java index 174525c25..4a7dc8ecf 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionModulo.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionModulo.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf5; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.ModuloActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionModulo extends Action { return "Modulo"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(ModuloActionItem.getResult(lda.popAsNumber(), lda.popAsNumber())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionReturn.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionReturn.java index 5e3d2fa13..2227be8a1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionReturn.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionReturn.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf5; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.ReturnActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,18 @@ public class ActionReturn extends Action { return "Return"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() == 0) { + //lda.returnValue = Undefined.INSTANCE; + return false; + } else { + lda.returnValue = lda.stack.pop(); + } + + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem value = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionToNumber.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionToNumber.java index 4db13e82b..4e31c6fe5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionToNumber.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionToNumber.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf5; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.ToNumberActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionToNumber extends Action { return "ToNumber"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() == 0) { + return false; + } + + lda.stack.push(ToNumberActionItem.getResult(lda.popAsNumber())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem object = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionToString.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionToString.java index 1ce28f627..b6a39fce0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionToString.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionToString.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf5; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.ToStringActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionToString extends Action { return "ToString"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() == 0) { + return false; + } + + lda.stack.push(ToStringActionItem.getResult(lda.pop())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem object = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionTypeOf.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionTypeOf.java index 031be737f..4b64cc9f0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionTypeOf.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionTypeOf.java @@ -20,8 +20,6 @@ import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.TypeOfActionItem; -import com.jpexs.decompiler.flash.ecma.EcmaScript; -import com.jpexs.decompiler.flash.ecma.EcmaType; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; import java.util.HashMap; @@ -44,31 +42,10 @@ public class ActionTypeOf extends Action { return false; } - lda.stack.push(getResult(lda.pop())); + lda.stack.push(TypeOfActionItem.getResult(lda.pop())); return true; } - public static String getResult(Object obj) { - Object res = obj; - EcmaType type = EcmaScript.type(res); - switch (type) { - case STRING: - return "string"; - case BOOLEAN: - return "boolean"; - case NUMBER: - return "number"; - case OBJECT: - return "object"; - case UNDEFINED: - return "undefined"; - case NULL: - return "null"; - } - //TODO: function,movieclip - return "object"; - } - @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem object = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf6/ActionGreater.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf6/ActionGreater.java index 19240c716..5a1ebcb12 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf6/ActionGreater.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf6/ActionGreater.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf6; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.GtActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionGreater extends Action { return "Greater"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(GtActionItem.getResult(lda.pop(), lda.pop())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf6/ActionStrictEquals.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf6/ActionStrictEquals.java index 46259c31f..eb4830ab9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf6/ActionStrictEquals.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf6/ActionStrictEquals.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf6; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.StrictEqActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionStrictEquals extends Action { return "StrictEquals"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(StrictEqActionItem.getResult(lda.pop(), lda.pop())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf6/ActionStringGreater.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf6/ActionStringGreater.java index c80293138..5bad8c646 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf6/ActionStringGreater.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf6/ActionStringGreater.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.swf6; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.LocalDataArea; import com.jpexs.decompiler.flash.action.model.operations.StringGtActionItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -35,6 +36,16 @@ public class ActionStringGreater extends Action { return "StringGreater"; } + @Override + public boolean execute(LocalDataArea lda) { + if (lda.stack.size() < 2) { + return false; + } + + lda.stack.push(StringGtActionItem.getResult(lda.pop(), lda.pop())); + return true; + } + @Override public void translate(TranslateStack stack, List output, HashMap regNames, HashMap variables, HashMap functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/NotItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/NotItem.java index 3459e515a..e29a7e10c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/NotItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/NotItem.java @@ -39,7 +39,11 @@ public class NotItem extends UnaryOpItem implements LogicalOpItem, Inverted { @Override public Object getResult() { - boolean ret = EcmaScript.toBoolean(value.getResult()); + return getResult(value.getResult()); + } + + public static Boolean getResult(Object obj) { + boolean ret = EcmaScript.toBoolean(obj); if (ret) { return Boolean.FALSE; } else { diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java index df3c6b821..62af73636 100644 --- a/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/src/com/jpexs/decompiler/flash/gui/Main.java @@ -20,7 +20,6 @@ import com.jpexs.decompiler.flash.ApplicationInfo; import com.jpexs.decompiler.flash.EventListener; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFBundle; -import com.jpexs.decompiler.flash.SWFCompression; import com.jpexs.decompiler.flash.SWFSourceInfo; import com.jpexs.decompiler.flash.SearchMode; import com.jpexs.decompiler.flash.SwfOpenException; @@ -36,13 +35,8 @@ import com.jpexs.decompiler.flash.gui.debugger.DebuggerTools; import com.jpexs.decompiler.flash.gui.pipes.FirstInstance; import com.jpexs.decompiler.flash.gui.proxy.ProxyFrame; import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin; -import com.jpexs.decompiler.flash.tags.EndTag; -import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag; -import com.jpexs.decompiler.flash.tags.ShowFrameTag; import com.jpexs.decompiler.flash.tags.base.FontTag; import com.jpexs.decompiler.flash.treeitems.SWFList; -import com.jpexs.decompiler.flash.types.RECT; -import com.jpexs.decompiler.flash.types.RGB; import com.jpexs.helpers.Cache; import com.jpexs.helpers.CancellableWorker; import com.jpexs.helpers.Helper; @@ -55,7 +49,6 @@ import com.sun.jna.platform.win32.Advapi32Util; import com.sun.jna.platform.win32.Kernel32; import com.sun.jna.platform.win32.WinReg; import java.awt.AWTException; -import java.awt.Color; import java.awt.Frame; import java.awt.GraphicsEnvironment; import java.awt.MenuItem; @@ -69,7 +62,6 @@ import java.awt.event.MouseEvent; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -87,11 +79,9 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; -import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map.Entry; -import java.util.Set; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.logging.ConsoleHandler; @@ -1284,7 +1274,8 @@ public class Main { } SWFSourceInfo[] sourceInfos = new SWFSourceInfo[exfiles.size()]; for (int i = 0; i < exfiles.size(); i++) { - sourceInfos[i] = new SWFSourceInfo(null, exfiles.get(i), extitles.get(i).isEmpty() ? null : extitles.get(i)); + String extitle = extitles.get(i); + sourceInfos[i] = new SWFSourceInfo(null, exfiles.get(i), extitle == null || extitle.isEmpty() ? null : extitle); } if (sourceInfos.length > 0) { openFile(sourceInfos, () -> { diff --git a/test/com/jpexs/decompiler/flash/gui/FlashPlayerTest.java b/test/com/jpexs/decompiler/flash/gui/FlashPlayerTest.java index 2dfaf037b..0c4d8d623 100644 --- a/test/com/jpexs/decompiler/flash/gui/FlashPlayerTest.java +++ b/test/com/jpexs/decompiler/flash/gui/FlashPlayerTest.java @@ -35,6 +35,7 @@ import com.jpexs.decompiler.flash.action.swf4.ActionDivide; import com.jpexs.decompiler.flash.action.swf4.ActionEquals; import com.jpexs.decompiler.flash.action.swf4.ActionLess; import com.jpexs.decompiler.flash.action.swf4.ActionMBAsciiToChar; +import com.jpexs.decompiler.flash.action.swf4.ActionMBCharToAscii; import com.jpexs.decompiler.flash.action.swf4.ActionMBStringExtract; import com.jpexs.decompiler.flash.action.swf4.ActionMBStringLength; import com.jpexs.decompiler.flash.action.swf4.ActionMultiply; @@ -209,7 +210,7 @@ public class FlashPlayerTest { File f = new File("libsrc/ffdec_lib/testdata/run_as2/run_as2.swf"); for (int i = 0; i < 15; i++) { - for (int j = 0; j < 12 + 23; j++) { + for (int j = 0; j < 13 + 23; j++) { File f2 = new File("run_test_" + new Date().getTime() + "_" + i + "_" + j + ".swf"); f2.deleteOnExit(); @@ -226,7 +227,7 @@ public class FlashPlayerTest { Action opAction = getOpAction(j); - if (j >= 12) { + if (j >= 13) { newActions.add(new ActionPush(r1)); } @@ -332,12 +333,12 @@ public class FlashPlayerTest { private Action getOpAction(int idx) { Action result; - if (idx < 12) { + if (idx < 13) { result = getUnaryOpAction(idx); Assert.assertEquals(1, result.getStackPopCount(null, null)); Assert.assertEquals(1, result.getStackPushCount(null, null)); } else { - result = getBinaryOpAction(idx - 12); + result = getBinaryOpAction(idx - 13); Assert.assertEquals(2, result.getStackPopCount(null, null)); Assert.assertEquals(1, result.getStackPushCount(null, null)); } @@ -370,6 +371,8 @@ public class FlashPlayerTest { case 10: return new ActionMBAsciiToChar(); case 11: + return new ActionMBCharToAscii(); + case 12: return new ActionMBStringLength(); }