diff --git a/examples/DeobfuscatorSample.java b/examples/DeobfuscatorSample.java index 054f912ba..d64f4ce16 100644 --- a/examples/DeobfuscatorSample.java +++ b/examples/DeobfuscatorSample.java @@ -1,3 +1,4 @@ + import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.types.MethodBody; @@ -24,7 +25,7 @@ public class DeobfuscatorSample implements SWFDecompilerListener { @Override public void swfParsed(SWF swf) { System.out.println("swfParsed"); - Map asms = swf.getASMs(); + Map asms = swf.getASMs(true); for (ASMSource asm : asms.values()) { try { asm.getActions(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java index 876a649f7..b9e4cd4fb 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -261,16 +261,16 @@ public final class SWF implements SWFContainerItem, Timelined { private String fileTitle; @Internal - private Map characters; + private volatile Map characters; @Internal - private Map> dependentCharacters; + private volatile Map> dependentCharacters; @Internal - private List abcList; + private volatile List abcList; @Internal - private JPEGTablesTag jtt; + private volatile JPEGTablesTag jtt; @Internal public Map sourceFontNamesMap = new HashMap<>(); @@ -1762,11 +1762,7 @@ public final class SWF implements SWFContainerItem, Timelined { r.add(new ArrayList<>()); r.add(new ArrayList<>()); r.add(new ArrayList<>()); - try { - ((GraphSourceItemContainer) ins).translateContainer(r, stack, output, new HashMap<>(), new HashMap<>(), new HashMap<>()); - } catch (EmptyStackException ex) { - } - + ((GraphSourceItemContainer) ins).translateContainer(r, stack, output, new HashMap<>(), new HashMap<>(), new HashMap<>()); continue; } @@ -1800,12 +1796,13 @@ public final class SWF implements SWFContainerItem, Timelined { } int staticOperation = Graph.SOP_USE_STATIC; //(Boolean) Configuration.getConfig("autoDeobfuscate", true) ? Graph.SOP_SKIP_STATIC : Graph.SOP_USE_STATIC; - try { - ins.translate(localData, stack, output, staticOperation, path); - } catch (EmptyStackException ex) { + int requiredStackSize = ins.getStackPopCount(localData, stack); + if (stack.size() < requiredStackSize) { // probably obfucated code, never executed branch break; } + + ins.translate(localData, stack, output, staticOperation, path); if (ins.isExit()) { break; } @@ -1848,7 +1845,7 @@ public final class SWF implements SWFContainerItem, Timelined { break; } ip++; - }; + } } private static void getVariables(List> variables, List functions, HashMap strings, HashMap usageTypes, ActionGraphSource code, int addr, String path) throws InterruptedException { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorRegisters.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorRegisters.java index 6a48688c0..9607d3c1e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorRegisters.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorRegisters.java @@ -77,7 +77,8 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple { MethodBody body = abody.clone(); Reference assignment = new Reference<>(null); ignoredRegs.clear(); - for (int i = 0; i < body.getLocalReservedCount(); i++) { + int localReservedCount = body.getLocalReservedCount(); + for (int i = 0; i < localReservedCount; i++) { ignoredRegs.add(i); } @@ -124,7 +125,7 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple { abody.exceptions = body.exceptions; abody.setCode(body.getCode()); - removeUnreachableInstructions(body.getCode(), cpool, trait, minfo, body); + removeUnreachableInstructions(abody.getCode(), cpool, trait, minfo, abody); //System.err.println("/deo"); } @@ -305,8 +306,6 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple { } } catch (ThreadDeath | InterruptedException ex) { throw ex; - } catch (Throwable ex) { - //ignore } } return -1; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimple.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimple.java index 773d953f6..ef47a7214 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimple.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimple.java @@ -94,6 +94,10 @@ import java.util.Map; */ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener { + private static final UndefinedAVM2Item UNDEFINED_ITEM = new UndefinedAVM2Item(null); + + private static final NotCompileTimeItem NOT_COMPILE_TIME_UNDEFINED_ITEM = new NotCompileTimeItem(null, UNDEFINED_ITEM); + private final int executionLimit = 30000; @Override @@ -169,13 +173,22 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener { staticRegs.put(((GetLocalTypeIns) ins.definition).getRegisterId(ins), new UndefinedAVM2Item(ins)); } } + + AVM2LocalData localData = newLocalData(scriptIndex, abc, abc.constants, body, isStatic, classIndex); + int localReservedCount = body.getLocalReservedCount(); for (int i = 0; i < code.code.size(); i++) { if (Thread.currentThread().isInterrupted()) { throw new InterruptedException(); } + if (i > 0) { + localData.scopeStack.clear(); + localData.localRegs.clear(); + initLocalRegs(localData, localReservedCount, body.max_regs); + } + ExecutionResult result = new ExecutionResult(); - executeInstructions(staticRegs, classIndex, isStatic, body, scriptIndex, abc, code, i, code.code.size() - 1, result, inlineIns); + executeInstructions(staticRegs, classIndex, isStatic, body, scriptIndex, abc, code, localData, i, code.code.size() - 1, result, inlineIns); } return false; @@ -204,13 +217,9 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener { AVM2LocalData localData = new AVM2LocalData(); localData.isStatic = isStatic; localData.classIndex = classIndex; - localData.localRegs = new HashMap<>(); - for (int i = 0; i < body.getLocalReservedCount(); i++) { - localData.localRegs.put(i, new NotCompileTimeItem(null, new UndefinedAVM2Item(null))); - } - for (int i = body.getLocalReservedCount(); i < body.max_regs; i++) { - localData.localRegs.put(i, new UndefinedAVM2Item(null)); - } + localData.localRegs = new HashMap<>(body.max_regs); + int localReservedCount = body.getLocalReservedCount(); + initLocalRegs(localData, localReservedCount, body.max_regs); localData.scopeStack = new ScopeStack(true); localData.constants = cpool; localData.methodInfo = abc.method_info; @@ -230,9 +239,17 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener { return localData; } - private void executeInstructions(Map staticRegs, int classIndex, boolean isStatic, MethodBody body, int scriptIndex, ABC abc, AVM2Code code, int idx, int endIdx, ExecutionResult result, List inlineIns) throws InterruptedException { + protected void initLocalRegs(AVM2LocalData localData, int localReservedCount, int maxRegs) { + for (int i = 0; i < localReservedCount; i++) { + localData.localRegs.put(i, NOT_COMPILE_TIME_UNDEFINED_ITEM); + } + for (int i = localReservedCount; i < maxRegs; i++) { + localData.localRegs.put(i, UNDEFINED_ITEM); + } + } + + private void executeInstructions(Map staticRegs, int classIndex, boolean isStatic, MethodBody body, int scriptIndex, ABC abc, AVM2Code code, AVM2LocalData localData, int idx, int endIdx, ExecutionResult result, List inlineIns) throws InterruptedException { List output = new ArrayList<>(); - AVM2LocalData localData = newLocalData(scriptIndex, abc, abc.constants, body, isStatic, classIndex); FixItemCounterTranslateStack stack = new FixItemCounterTranslateStack(""); int instructionsProcessed = 0; @@ -287,53 +304,47 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener { } } - Class allowedDefs[] = new Class[]{ - PushByteIns.class, - PushShortIns.class, - PushIntIns.class, - PushDoubleIns.class, - PushStringIns.class, - PushNullIns.class, - PushUndefinedIns.class, - PushFalseIns.class, - PushTrueIns.class, - DupIns.class, - SwapIns.class, - AddIns.class, - AddIIns.class, - SubtractIns.class, - SubtractIIns.class, - ModuloIns.class, - MultiplyIns.class, - BitAndIns.class, - BitXorIns.class, - BitOrIns.class, - LShiftIns.class, - RShiftIns.class, - URShiftIns.class, - EqualsIns.class, - NotIns.class, - IfTypeIns.class, - JumpIns.class, - EqualsIns.class, - LessEqualsIns.class, - GreaterEqualsIns.class, - GreaterThanIns.class, - LessThanIns.class, - StrictEqualsIns.class, - PopIns.class, - GetLocalTypeIns.class, - NewFunctionIns.class, - CoerceOrConvertTypeIns.class - }; - boolean ok = false; - for (Class s : allowedDefs) { - if (s.isAssignableFrom(def.getClass())) { - ok = true; - break; - } + if (def instanceof PushByteIns + || def instanceof PushShortIns + || def instanceof PushIntIns + || def instanceof PushDoubleIns + || def instanceof PushStringIns + || def instanceof PushNullIns + || def instanceof PushUndefinedIns + || def instanceof PushFalseIns + || def instanceof PushTrueIns + || def instanceof DupIns + || def instanceof SwapIns + || def instanceof AddIns + || def instanceof AddIIns + || def instanceof SubtractIns + || def instanceof SubtractIIns + || def instanceof ModuloIns + || def instanceof MultiplyIns + || def instanceof BitAndIns + || def instanceof BitXorIns + || def instanceof BitOrIns + || def instanceof LShiftIns + || def instanceof RShiftIns + || def instanceof URShiftIns + || def instanceof EqualsIns + || def instanceof NotIns + || def instanceof IfTypeIns + || def instanceof JumpIns + || def instanceof EqualsIns + || def instanceof LessEqualsIns + || def instanceof GreaterEqualsIns + || def instanceof GreaterThanIns + || def instanceof LessThanIns + || def instanceof StrictEqualsIns + || def instanceof PopIns + || def instanceof GetLocalTypeIns + || def instanceof NewFunctionIns + || def instanceof CoerceOrConvertTypeIns) { + ok = true; } + if (!ok) { break; } @@ -406,8 +417,6 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener { } } catch (InterruptedException ex) { throw ex; - } catch (Exception ex) { - //ignore } } 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 32f418247..ee138f876 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 @@ -36,7 +36,6 @@ import com.jpexs.decompiler.flash.action.model.SetPropertyActionItem; import com.jpexs.decompiler.flash.action.model.SetVariableActionItem; import com.jpexs.decompiler.flash.action.model.StoreRegisterActionItem; import com.jpexs.decompiler.flash.action.model.TemporaryRegister; -import com.jpexs.decompiler.flash.action.model.UnsupportedActionItem; import com.jpexs.decompiler.flash.action.model.clauses.ClassActionItem; import com.jpexs.decompiler.flash.action.model.clauses.InterfaceActionItem; import com.jpexs.decompiler.flash.action.parser.ActionParseException; @@ -83,7 +82,6 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.EmptyStackException; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -1132,13 +1130,7 @@ public abstract class Action implements GraphSourceItem { ip = ip + 1 + store.getStoreSize() - 1/*ip++ will be next*/; } - try { - action.translate(localData, stack, output, staticOperation, path); - } catch (EmptyStackException ese) { - logger.log(Level.SEVERE, "Decompilation error in: " + path, ese); - output.add(new UnsupportedActionItem(action, "Empty stack")); - } - + action.translate(localData, stack, output, staticOperation, path); } ip++; 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 9738030c1..656821caf 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 @@ -65,7 +65,6 @@ import com.jpexs.decompiler.graph.TranslateException; import com.jpexs.decompiler.graph.TranslateStack; import java.io.IOException; import java.util.ArrayList; -import java.util.EmptyStackException; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -234,177 +233,174 @@ public class ActionDeobfuscator extends ActionDeobfuscatorSimple { int instructionsProcessed = 0; ActionConstantPool lastConstantPool = null; - try { - while (true) { - if (idx > endIdx) { + while (true) { + 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; + } + + String variableName = stack.peek().getResult().toString(); + if (!localData.variables.containsKey(variableName)) { break; } + } - Action action = actions.get(idx); - instructionsProcessed++; - - if (instructionsProcessed > executionLimit) { - break; + if (action instanceof ActionCallFunction) { + if (stack.isEmpty()) { + return; } - /*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; - } - - String variableName = stack.peek().getResult().toString(); - if (!localData.variables.containsKey(variableName)) { - break; - } - } - - if (action instanceof ActionCallFunction) { - if (stack.isEmpty()) { - 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; - } + 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 { - // 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 ActionAdd - || action instanceof ActionAdd2 - || action instanceof ActionIncrement - || action instanceof ActionDecrement - || action instanceof ActionSubtract - || action instanceof ActionModulo - || action instanceof ActionMultiply - || action instanceof ActionBitXor - || action instanceof ActionBitAnd - || action instanceof ActionBitOr - || action instanceof ActionBitLShift - || action instanceof ActionBitRShift - || action instanceof ActionDefineLocal - || action instanceof ActionJump - || action instanceof ActionGetVariable - || action instanceof ActionSetVariable - || action instanceof ActionEquals - || action instanceof ActionEquals2 - || action instanceof ActionLess - || action instanceof ActionLess2 - || action instanceof ActionGreater - || action instanceof ActionNot - || action instanceof ActionIf - || action instanceof ActionConstantPool - || action instanceof ActionCallFunction - || action instanceof ActionReturn - || action instanceof ActionEnd)) { break; } + } else { + // do not throw EmptyStackException, much faster + int requiredStackSize = action.getStackPopCount(localData, stack); + if (stack.size() < requiredStackSize) { + return; + } - 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) { + action.translate(localData, stack, output, Graph.SOP_USE_STATIC, ""); + } + + if (!(action instanceof ActionPush + || action instanceof ActionPushDuplicate + || action instanceof ActionAdd + || action instanceof ActionAdd2 + || action instanceof ActionIncrement + || action instanceof ActionDecrement + || action instanceof ActionSubtract + || action instanceof ActionModulo + || action instanceof ActionMultiply + || action instanceof ActionBitXor + || action instanceof ActionBitAnd + || action instanceof ActionBitOr + || action instanceof ActionBitLShift + || action instanceof ActionBitRShift + || action instanceof ActionDefineLocal + || action instanceof ActionJump + || action instanceof ActionGetVariable + || action instanceof ActionSetVariable + || action instanceof ActionEquals + || action instanceof ActionEquals2 + || action instanceof ActionLess + || action instanceof ActionLess2 + || action instanceof ActionGreater + || action instanceof ActionNot + || 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; } } - - /*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.getAddress() + jump.getTotalActionLength() + jump.getJumpOffset(); - idx = actions.indexOf(actions.getByAddress(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.getAddress() + aif.getTotalActionLength() + aif.getJumpOffset(); - idx = actions.indexOf(actions.getByAddress(address)); - if (idx == -1) { - throw new TranslateException("If target not found: " + address); - } - } - } - - if (action instanceof ActionDefineFunction) { - List lastActions = actions.getContainerLastActions(action); - int lastActionIdx = actions.indexOf(lastActions.get(0)); - idx = lastActionIdx != -1 ? lastActionIdx + 1 : -1; - } - - if (/*localData.variables.size() == 1 && */stack.allItemsFixed() || action instanceof ActionEnd) { - 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(); - } + if (!ok) { break; } } - } catch (EmptyStackException | TranslateException ex) { + + /*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.getAddress() + jump.getTotalActionLength() + jump.getJumpOffset(); + idx = actions.indexOf(actions.getByAddress(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.getAddress() + aif.getTotalActionLength() + aif.getJumpOffset(); + idx = actions.indexOf(actions.getByAddress(address)); + if (idx == -1) { + throw new TranslateException("If target not found: " + address); + } + } + } + + if (action instanceof ActionDefineFunction) { + List lastActions = actions.getContainerLastActions(action); + int lastActionIdx = actions.indexOf(lastActions.get(0)); + idx = lastActionIdx != -1 ? lastActionIdx + 1 : -1; + } + + if (/*localData.variables.size() == 1 && */stack.allItemsFixed() || action instanceof ActionEnd) { + 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; + } } } 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/ActionDeobfuscatorSimple.java index ae8f731b3..971e55869 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/ActionDeobfuscatorSimple.java @@ -52,7 +52,6 @@ import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateException; import com.jpexs.decompiler.graph.TranslateStack; import java.util.ArrayList; -import java.util.EmptyStackException; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -274,102 +273,99 @@ public class ActionDeobfuscatorSimple implements SWFDecompilerListener { FixItemCounterTranslateStack stack = new FixItemCounterTranslateStack(""); int instructionsProcessed = 0; - try { - while (true) { - if (idx > endIdx) { - break; - } + while (true) { + if (idx > endIdx) { + break; + } - if (instructionsProcessed > executionLimit) { - break; - } + if (instructionsProcessed > executionLimit) { + break; + } - Action action = actions.get(idx); + Action action = actions.get(idx); - /*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();*/ - // do not throw EmptyStackException, much faster - int requiredStackSize = action.getStackPopCount(localData, stack); - if (stack.size() < requiredStackSize) { - return; - } + /*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();*/ + // 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, ""); + action.translate(localData, stack, output, Graph.SOP_USE_STATIC, ""); - if (!(action instanceof ActionPush - || action instanceof ActionPushDuplicate - || action instanceof ActionCharToAscii - || action instanceof ActionAdd - || action instanceof ActionAdd2 - || action instanceof ActionSubtract - || action instanceof ActionModulo - || action instanceof ActionMultiply - || action instanceof ActionBitXor - || action instanceof ActionBitAnd - || action instanceof ActionBitOr - || action instanceof ActionBitLShift - || action instanceof ActionBitRShift - || action instanceof ActionEquals - || action instanceof ActionNot - || action instanceof ActionIf - || action instanceof ActionJump)) { - break; - } + if (!(action instanceof ActionPush + || action instanceof ActionPushDuplicate + || action instanceof ActionCharToAscii + || action instanceof ActionAdd + || action instanceof ActionAdd2 + || action instanceof ActionSubtract + || action instanceof ActionModulo + || action instanceof ActionMultiply + || action instanceof ActionBitXor + || action instanceof ActionBitAnd + || action instanceof ActionBitOr + || action instanceof ActionBitLShift + || action instanceof ActionBitRShift + || action instanceof ActionEquals + || action instanceof ActionNot + || action instanceof ActionIf + || action instanceof ActionJump)) { + break; + } - if (action instanceof ActionPush) { - ActionPush push = (ActionPush) action; - boolean ok = true; - instructionsProcessed += push.values.size() - 1; - for (Object value : push.values) { - if (value instanceof ConstantIndex || value instanceof RegisterNumber) { - ok = false; - break; - } - } - if (!ok) { + if (action instanceof ActionPush) { + ActionPush push = (ActionPush) action; + boolean ok = true; + instructionsProcessed += push.values.size() - 1; + for (Object value : push.values) { + if (value instanceof ConstantIndex || value instanceof RegisterNumber) { + ok = false; break; } } - - idx++; - - if (action instanceof ActionJump) { - ActionJump jump = (ActionJump) action; - long address = jump.getAddress() + jump.getTotalActionLength() + jump.getJumpOffset(); - idx = actions.indexOf(actions.getByAddress(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.getAddress() + aif.getTotalActionLength() + aif.getJumpOffset(); - idx = actions.indexOf(actions.getByAddress(address)); - if (idx == -1) { - throw new TranslateException("If target not found: " + address); - } - } - } - - instructionsProcessed++; - - if (stack.allItemsFixed()) { - result.idx = idx == actions.size() ? idx - 1 : idx; - result.instructionsProcessed = instructionsProcessed; - result.stack.clear(); - result.stack.addAll(stack); + if (!ok) { + break; } } - } catch (EmptyStackException | TranslateException ex) { + + idx++; + + if (action instanceof ActionJump) { + ActionJump jump = (ActionJump) action; + long address = jump.getAddress() + jump.getTotalActionLength() + jump.getJumpOffset(); + idx = actions.indexOf(actions.getByAddress(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.getAddress() + aif.getTotalActionLength() + aif.getJumpOffset(); + idx = actions.indexOf(actions.getByAddress(address)); + if (idx == -1) { + throw new TranslateException("If target not found: " + address); + } + } + } + + instructionsProcessed++; + + if (stack.allItemsFixed()) { + result.idx = idx == actions.size() ? idx - 1 : idx; + result.instructionsProcessed = instructionsProcessed; + result.stack.clear(); + result.stack.addAll(stack); + } } }