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 9fd06575e..ee94b7834 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 @@ -323,12 +323,7 @@ public abstract class Action implements GraphSourceItem { * @return Length */ public final int getBytesLength(int version) { - int contentLength = getContentBytesLength(); - if (contentLength == -1) { - return getBytes(version).length; - } - - return contentLength + 1 + (actionCode >= 0x80 ? 2 : 0); + return getContentBytesLength() + (actionCode >= 0x80 ? 3 : 1); } protected int getContentBytesLength() { 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 5a564f55f..04aae8173 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 @@ -271,7 +271,7 @@ public class ActionListReader { for (int i = 0; i < endIp; i++) { retMap.add(null); } - List actionMap = new ArrayList<>(endIp); + List actionMap = new ArrayList<>(endIp + 1); for (int i = 0; i <= endIp; i++) { actionMap.add(null); } @@ -766,6 +766,115 @@ public class ActionListReader { return entryAction; } + public static void fixConstantPools(List listeners, ActionList actions) { + Action lastAction = actions.get(actions.size() - 1); + int endIp = (int) lastAction.getAddress(); + List actionMap = new ArrayList<>(endIp); + for (int i = 0; i <= endIp; i++) { + actionMap.add(null); + } + for (Action a : actions) { + actionMap.set((int) a.getAddress(), a); + } + + try { + fixConstantPools(listeners, new ConstantPool(), actionMap, new TreeMap<>(), 0, 0, endIp, null, true, new ArrayList<>()); + } catch (IOException ex) { + // ignore + } + } + + private static void fixConstantPools(List listeners, ConstantPool cpool, + List actions, Map actionMap, + int ip, int startIp, int endIp, String path, boolean indeterminate, List visitedContainers) throws IOException { + + if (visitedContainers.contains(ip)) { + return; + } + visitedContainers.add(ip); + + Queue jumpQueue = new LinkedList<>(); + jumpQueue.add(ip); + while (!jumpQueue.isEmpty()) { + ip = jumpQueue.remove(); + if (ip < startIp) { + continue; + } + + while (endIp == -1 || endIp > ip) { + Action a; + if ((a = actions.get(ip)) == null) { + break; + } + + int actionLengthWithHeader = a.getTotalActionLength(); + + // unknown action, replace with jump + if (a instanceof ActionNop) { + ActionJump aJump = new ActionDeobfuscateJump(0); + int jumpLength = aJump.getTotalActionLength(); + aJump.setAddress(a.getAddress()); + //FIXME! This offset can be larger than SI16 value! + aJump.setJumpOffset(actionLengthWithHeader - jumpLength); + a = aJump; + actionLengthWithHeader = a.getTotalActionLength(); + } + + Action existingAction = actionMap.get(ip); + if (existingAction != null) { + break; + } + + actionMap.put(ip, a); + + if (listeners != null) { + for (int i = 0; i < listeners.size(); i++) { + listeners.get(i).progressReading(ip, actions.size()); + } + } + + a.setAddress(ip); + + if (a instanceof ActionPush && cpool != null) { + ((ActionPush) a).constantPool = cpool.constants; + } else if (a instanceof ActionConstantPool) { + cpool = new ConstantPool(((ActionConstantPool) a).constantPool); + } else if (a instanceof ActionIf) { + ActionIf aIf = (ActionIf) a; + int nIp = ip + actionLengthWithHeader + aIf.getJumpOffset(); + if (nIp >= 0) { + jumpQueue.add(nIp); + } + } else if (a instanceof ActionJump) { + ActionJump aJump = (ActionJump) a; + int nIp = ip + actionLengthWithHeader + aJump.getJumpOffset(); + if (nIp >= 0) { + jumpQueue.add(nIp); + } + break; + } else if (a instanceof GraphSourceItemContainer) { + GraphSourceItemContainer cnt = (GraphSourceItemContainer) a; + String cntName = cnt.getName(); + String newPath = path + (cntName == null ? "" : "/" + cntName); + for (long size : cnt.getContainerSizes()) { + if (size != 0) { + int ip2 = ip + actionLengthWithHeader; + int endIp2 = ip + actionLengthWithHeader + (int) size; + fixConstantPools(listeners, cpool, actions, actionMap, ip2, startIp, endIp2, newPath, indeterminate, visitedContainers); + actionLengthWithHeader += size; + } + } + } + + ip += actionLengthWithHeader; + + if (a.isExit()) { + break; + } + } + } + } + private static void deobfustaceActionListAtPosRecursive(List listeners, List output, HashMap> containers, ActionLocalData localData, TranslateStack stack, ConstantPool cpool, List actions, int ip, List ret, int startIp, int endip, String path, Map visited, boolean indeterminate, Map> decisionStates, int version, int recursionLevel, int maxRecursionLevel) throws IOException, InterruptedException { boolean debugMode = false; boolean decideBranch = false; 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 80327b018..9bbf3fd9c 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 @@ -90,7 +90,8 @@ public class ActionDeobfuscator extends ActionDeobfuscatorSimple { removeObfuscationIfs(actions, fakeFunctions); removeUnreachableActions(actions); removeZeroJumps(actions); - rereadActionList(actions, swf); // this call will fix the contant pool assigments + ActionListReader.fixConstantPools(null, actions); + //rereadActionList(actions, swf); // this call will fix the contant pool assigments } private void combinePushs(ActionList actions) {