From dba9a8b162d525f06a76f181b1f7d888f2dfee6d Mon Sep 17 00:00:00 2001 From: "honfika@gmail.com" Date: Sat, 26 Sep 2015 22:31:08 +0200 Subject: [PATCH] action deobfuscator improved again --- .../jpexs/decompiler/flash/action/Action.java | 9 +-- .../decompiler/flash/action/ActionList.java | 12 ++-- .../flash/action/ActionListReader.java | 34 ++++----- .../flash/action/FastActionList.java | 69 +++++++++++++++++++ .../ActionDeobfuscatorSimple.java | 5 ++ .../flash/action/parser/pcode/ASMParser.java | 2 +- .../flash/action/swf4/ActionJump.java | 4 +- .../flash/action/swf4/ActionPush.java | 3 +- .../action/swf5/ActionDefineFunction.java | 2 +- .../flash/action/swf5/ActionWith.java | 2 +- .../action/swf7/ActionDefineFunction2.java | 2 +- .../flash/action/swf7/ActionTry.java | 2 +- 12 files changed, 105 insertions(+), 41 deletions(-) create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/FastActionList.java 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 eb0e01b22..5f2e4e1d0 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 @@ -321,10 +321,9 @@ public abstract class Action implements GraphSourceItem { /** * Gets the length of action converted to bytes * - * @param version SWF version * @return Length */ - public final int getBytesLength(int version) { + public final int getBytesLength() { return getContentBytesLength() + (actionCode >= 0x80 ? 3 : 1); } @@ -334,11 +333,9 @@ public abstract class Action implements GraphSourceItem { /** * Updates the action length to the length calculated from action bytes - * - * @param version SWF version */ - public void updateLength(int version) { - int length = getBytesLength(version); + public void updateLength() { + int length = getBytesLength(); actionLength = length - 1 - (actionCode >= 0x80 ? 2 : 0); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionList.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionList.java index 68033a8c5..a5a866943 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionList.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionList.java @@ -57,11 +57,11 @@ public class ActionList extends ArrayList { } public void removeAction(int index) { - ActionListReader.removeAction(this, index, SWF.DEFAULT_VERSION, true); + ActionListReader.removeAction(this, index, true); } public void removeActions(List actionsToRemove) { - ActionListReader.removeActions(this, actionsToRemove, SWF.DEFAULT_VERSION, true); + ActionListReader.removeActions(this, actionsToRemove, true); } public void removeAction(int index, int count) { @@ -71,20 +71,20 @@ public class ActionList extends ArrayList { } for (int i = 0; i < count; i++) { - ActionListReader.removeAction(this, index, SWF.DEFAULT_VERSION, true); + ActionListReader.removeAction(this, index, true); } } public void addAction(int index, Action action) { - ActionListReader.addAction(this, index, action, SWF.DEFAULT_VERSION, false, false); + ActionListReader.addAction(this, index, action, false, false); } public void addActions(int index, List actions) { - ActionListReader.addActions(this, index, actions, SWF.DEFAULT_VERSION); + ActionListReader.addActions(this, index, actions); } public void fixActionList() { - ActionListReader.fixActionList(this, null, SWF.DEFAULT_VERSION); + ActionListReader.fixActionList(this, null); } public List getContainerLastActions(Action action) { 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 87faa133b..2b3e06d10 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 @@ -156,7 +156,7 @@ public class ActionListReader { nextOffsets.put(endAddress, endAddress + 1); } - ActionList actions = fixActionList(new ActionList(actionMap.values()), nextOffsets, version); + ActionList actions = fixActionList(new ActionList(actionMap.values()), nextOffsets); // jump to the entry action when it is diffrent from the first action in the map if (entryAction != actions.get(0)) { @@ -166,13 +166,13 @@ public class ActionListReader { } if (SWFDecompilerPlugin.fireActionListParsed(actions, sis.getSwf())) { - actions = fixActionList(actions, null, version); + actions = fixActionList(actions, null); } if (deobfuscationMode == 0) { try { actions = deobfuscateActionListOld(listeners, actions, version, 0, path); - updateActionLengths(actions, version); + updateActionLengths(actions); } catch (OutOfMemoryError | StackOverflowError | TranslateException ex) { // keep orignal (not deobfuscated) actions logger.log(Level.SEVERE, null, ex); @@ -192,7 +192,7 @@ public class ActionListReader { return actions; } - public static ActionList fixActionList(ActionList actions, Map nextOffsets, int version) { + public static ActionList fixActionList(ActionList actions, Map nextOffsets) { Map> containerLastActions = new HashMap<>(); getContainerLastActions(actions, containerLastActions); @@ -226,7 +226,7 @@ public class ActionListReader { Map jumps = new HashMap<>(); getJumps(ret, jumps); - updateActionLengths(ret, version); + updateActionLengths(ret); updateAddresses(ret, 0); long endAddress = ret.get(ret.size() - 1).getAddress(); @@ -427,9 +427,9 @@ public class ActionListReader { return address; } - private static void updateActionLengths(List actions, int version) { + private static void updateActionLengths(List actions) { for (int i = 0; i < actions.size(); i++) { - actions.get(i).updateLength(version); + actions.get(i).updateLength(); } } @@ -537,11 +537,10 @@ public class ActionListReader { * * @param actions * @param index - * @param version * @param removeWhenLast * @return */ - public static boolean removeAction(ActionList actions, int index, int version, boolean removeWhenLast) { + public static boolean removeAction(ActionList actions, int index, boolean removeWhenLast) { if (index < 0 || actions.size() <= index) { return false; @@ -586,7 +585,7 @@ public class ActionListReader { actions.remove(index); - updateActionLengths(actions, version); + updateActionLengths(actions); updateAddresses(actions, startIp); updateJumps(actions, jumps, containerLastActions, endAddress); updateActionStores(actions, jumps); @@ -603,11 +602,10 @@ public class ActionListReader { * * @param actions * @param actionsToRemove - * @param version * @param removeWhenLast * @return */ - public static boolean removeActions(ActionList actions, List actionsToRemove, int version, boolean removeWhenLast) { + public static boolean removeActions(ActionList actions, List actionsToRemove, boolean removeWhenLast) { long startIp = actions.get(0).getAddress(); Action lastAction = actions.get(actions.size() - 1); @@ -651,7 +649,7 @@ public class ActionListReader { actions.remove(index); } - updateActionLengths(actions, version); + updateActionLengths(actions); updateAddresses(actions, startIp); updateJumps(actions, jumps, containerLastActions, endAddress); updateActionStores(actions, jumps); @@ -667,13 +665,12 @@ public class ActionListReader { * @param actions * @param index * @param action - * @param version * @param addToContainer * @param replaceJump * @return */ public static boolean addAction(ActionList actions, int index, Action action, - int version, boolean addToContainer, boolean replaceJump) { + boolean addToContainer, boolean replaceJump) { if (index < 0 || actions.size() < index) { return false; @@ -721,7 +718,7 @@ public class ActionListReader { actions.add(index, action); - updateActionLengths(actions, version); + updateActionLengths(actions); updateAddresses(actions, startIp); updateJumps(actions, jumps, containerLastActions, endAddress); updateActionStores(actions, jumps); @@ -737,10 +734,9 @@ public class ActionListReader { * @param actions * @param index * @param newActions - * @param version * @return */ - public static boolean addActions(ActionList actions, int index, List newActions, int version) { + public static boolean addActions(ActionList actions, int index, List newActions) { if (index < 0 || actions.size() < index) { return false; @@ -767,7 +763,7 @@ public class ActionListReader { actions.addAll(index, newActions); - updateActionLengths(actions, version); + updateActionLengths(actions); updateAddresses(actions, startIp); updateJumps(actions, jumps, containerLastActions, endAddress); updateActionStores(actions, jumps); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/FastActionList.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/FastActionList.java new file mode 100644 index 000000000..8ac34c5ac --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/FastActionList.java @@ -0,0 +1,69 @@ +/* + * 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; + +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; + +/** + * + * @author JPEXS + */ +public class FastActionList { + + private LinkedList actions; + + public FastActionList(List actions) { + this.actions = new LinkedList<>(actions); + } + + public void expandPushes() { + ListIterator iterator = actions.listIterator(); + while (iterator.hasNext()) { + Action action = iterator.next(); + if (action instanceof ActionPush) { + ActionPush push = (ActionPush) action; + if (push.values.size() > 1) { + for (int i = 1; i < push.values.size(); i++) { + Object value = push.values.get(i); + ActionPush newPush = new ActionPush(value); + newPush.constantPool = push.constantPool; + iterator.add(newPush); + } + + Object obj = push.values.get(0); + push.values.clear(); + push.values.add(obj); + } + } + } + } + + private void updateActionLengths() { + for (Action action : actions) { + action.updateLength(); + } + } + + public ActionList toActionList() { + ActionList result = new ActionList(actions); + updateActionLengths(); + return result; + } +} 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 113c2a45c..8624b0b5f 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 @@ -22,6 +22,7 @@ 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.ActionLocalData; +import com.jpexs.decompiler.flash.action.FastActionList; import com.jpexs.decompiler.flash.action.swf4.ActionAdd; import com.jpexs.decompiler.flash.action.swf4.ActionAnd; import com.jpexs.decompiler.flash.action.swf4.ActionAsciiToChar; @@ -83,6 +84,10 @@ public class ActionDeobfuscatorSimple implements SWFDecompilerListener { @Override public void actionListParsed(ActionList actions, SWF swf) throws InterruptedException { + FastActionList fastActions = new FastActionList(actions); + fastActions.expandPushes(); + actions.setActions(fastActions.toActionList()); + actions.expandPushes(); removeGetTimes(actions); removeObfuscationIfs(actions); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java index 5fa5bd6ee..1dd150a30 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java @@ -424,7 +424,7 @@ public class ASMParser { throw new ActionParseException("Unknown instruction name :" + instructionName, lexer.yyline()); } - a.updateLength(version); + a.updateLength(); return a; } 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 735a7056b..91f8d50cd 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 @@ -19,7 +19,6 @@ package com.jpexs.decompiler.flash.action.swf4; 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.ActionGraphSource; import com.jpexs.decompiler.flash.action.ActionList; import com.jpexs.decompiler.flash.action.parser.ActionParseException; import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer; @@ -105,8 +104,7 @@ public class ActionJump extends Action { @Override public List getBranches(GraphSource code) { List ret = super.getBranches(code); - int version = ((ActionGraphSource) code).version; - int length = getBytesLength(version); + int length = getBytesLength(); int ofs = code.adr2pos(getAddress() + length + offset); if (ofs == -1) { ofs = code.adr2pos(getAddress() + length); 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 a537c36f6..ed4b6379a 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 @@ -18,7 +18,6 @@ package com.jpexs.decompiler.flash.action.swf4; import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.EndOfStreamException; -import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.action.Action; @@ -248,7 +247,7 @@ public class ActionPush extends Action { super(0x96, 0); this.values = new ArrayList<>(); this.values.add(value); - updateLength(SWF.DEFAULT_VERSION); + updateLength(); } public ActionPush(FlasmLexer lexer, List constantPool) throws IOException, ActionParseException { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionDefineFunction.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionDefineFunction.java index f74e189d7..2c61c47b1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionDefineFunction.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionDefineFunction.java @@ -84,7 +84,7 @@ public class ActionDefineFunction extends Action implements GraphSourceItemConta @Override public long getHeaderSize() { - return getBytesLength(version); + return getBytesLength(); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionWith.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionWith.java index ac8bd6aa4..f7fdba4a0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionWith.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf5/ActionWith.java @@ -109,7 +109,7 @@ public class ActionWith extends Action implements GraphSourceItemContainer { @Override public long getHeaderSize() { - return getBytesLength(version); + return getBytesLength(); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf7/ActionDefineFunction2.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf7/ActionDefineFunction2.java index 0709f24db..a3f739c38 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf7/ActionDefineFunction2.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf7/ActionDefineFunction2.java @@ -143,7 +143,7 @@ public class ActionDefineFunction2 extends Action implements GraphSourceItemCont @Override public long getHeaderSize() { - return getBytesLength(version); + return getBytesLength(); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf7/ActionTry.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf7/ActionTry.java index 77b8f62c0..a5d9f1dfe 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf7/ActionTry.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf7/ActionTry.java @@ -180,7 +180,7 @@ public class ActionTry extends Action implements GraphSourceItemContainer { @Override public long getHeaderSize() { - return getBytesLength(version); + return getBytesLength(); } public long getTrySize() {