diff --git a/trunk/src/com/jpexs/decompiler/flash/Configuration.java b/trunk/src/com/jpexs/decompiler/flash/Configuration.java index 556ca641f..e18c4be2c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/Configuration.java +++ b/trunk/src/com/jpexs/decompiler/flash/Configuration.java @@ -84,6 +84,7 @@ public class Configuration { put("gui.window.maximized.horizontal", false); put("gui.window.maximized.vertical", false); put("lastRenameType", 1); + put("removeNops", true); }}; /** diff --git a/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java b/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java index cbb344a8a..fcfbbf2af 100644 --- a/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java +++ b/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java @@ -537,163 +537,163 @@ public class SWFInputStream extends InputStream { return ret; } - public List readActionList(List listeners, long address, long containerSWFOffset, String path) throws IOException { + public List readActionList(List listeners, long containerSWFOffset, String path) throws IOException { ReReadableInputStream rri = new ReReadableInputStream(this); - return readActionList(listeners, address, containerSWFOffset, rri, version, 0, -1, path); + return readActionList(listeners, containerSWFOffset, rri, version, 0, -1, path); } - public List readActionList(List listeners, long address, long containerSWFOffset, ReReadableInputStream rri, int maxlen, String path) throws IOException { - return readActionList(listeners, address, containerSWFOffset, rri, version, rri.getPos(), rri.getPos() + maxlen, path); + public List readActionList(List listeners, long containerSWFOffset, ReReadableInputStream rri, int maxlen, String path) throws IOException { + return readActionList(listeners, containerSWFOffset, rri, version, rri.getPos(), rri.getPos() + maxlen, path); } - @SuppressWarnings("unchecked") - private static void getConstantPool(List listeners, ConstantPool cpool, List localData, Stack stack, List output, ActionGraphSource code, int ip, List constantPools, List visited, int version, int endIp, String path) { - boolean debugMode = false; - boolean deobfuscate = Configuration.getConfig("autoDeobfuscate", true); - while (((endIp == -1) || (endIp > ip)) && (ip > -1) && ip < code.size()) { - if (visited.contains(ip)) { - break; - } - for (int i = 0; i < listeners.size(); i++) { - listeners.get(i).progress("constantpool", ip + 1, code.size()); - } - GraphSourceItem ins = code.get(ip); - if (ins.isIgnored()) { - if (ins.isExit()) { - break; - } - ip++; - continue; - } - - if (ins instanceof GraphSourceItemContainer) { - GraphSourceItemContainer cnt = (GraphSourceItemContainer) ins; - String cntName = cnt.getName(); - if (ins instanceof Action) { - List> output2s = new ArrayList<>(); - long endAddr = ((Action) ins).getAddress() + cnt.getHeaderSize(); - for (long size : cnt.getContainerSizes()) { - if (size == 0) { - output2s.add(new ArrayList()); - continue; - } - List localData2 = Helper.toList(new HashMap(), new HashMap(), new HashMap()); - List output2 = new ArrayList<>(); - output2s.add(output2); - getConstantPool(listeners, cpool, localData2, new Stack(), output2, code, code.adr2pos(endAddr), constantPools, visited, version, code.adr2pos(endAddr + size), path + (cntName == null ? "" : "/" + cntName)); - endAddr += size; - } - if (deobfuscate) { - cnt.translateContainer(output2s, stack, output, (HashMap) localData.get(0), (HashMap) localData.get(1), (HashMap) localData.get(2)); - } - ip = code.adr2pos(endAddr); - continue; - } - } - if (ins instanceof ActionPush) { - if (cpool != null) { - ((ActionPush) ins).constantPool = cpool.constants; - cpool.count++; - } - } - if (ins instanceof ActionDefineFunction) { - if (cpool != null) { - //((ActionDefineFunction) ins).setConstantPool(cpool.constants,code.getActions()); - cpool.count++; - } - } - if (ins instanceof ActionDefineFunction2) { - if (cpool != null) { - //((ActionDefineFunction2) ins).setConstantPool(cpool.constants,code.getActions()); - cpool.count++; - } - } - if (debugMode) { - String add = ""; - if (ins instanceof ActionIf) { - add += " change:" + ((ActionIf) ins).getJumpOffset(); - } - if (ins instanceof ActionJump) { - add += " change:" + (((ActionJump) ins).getJumpOffset()); - } - System.err.println("getConstantPool ip " + ip + ", addr " + Helper.formatAddress(((Action) ins).getAddress()) + ": " + ((Action) ins).getASMSource(new ArrayList(), new ArrayList(), cpool == null ? null : cpool.constants, version, false) + add + " stack:" + Helper.stackToString(stack, Helper.toList(cpool))); - } - if (ins instanceof ActionConstantPool) { - constantPools.add(new ConstantPool(((ActionConstantPool) ins).constantPool)); - if (cpool == null) { - cpool = new ConstantPool(); - } - cpool.setNew(((ActionConstantPool) ins).constantPool); - } - - //for..in return - if (deobfuscate) { - if (((ins instanceof ActionEquals) || (ins instanceof ActionEquals2)) && (stack.size() == 1) && (stack.peek() instanceof DirectValueActionItem)) { - stack.push(new DirectValueActionItem(null, 0, new Null(), new ArrayList())); - } - try { - ins.translate(localData, stack, output, Graph.SOP_USE_STATIC/*Graph.SOP_SKIP_STATIC*/, null); - } catch (Exception ex) { - Logger.getLogger(SWFInputStream.class.getName()).log(Level.SEVERE, "Error during getting constantpool", ex); - } - } - if (ins.isExit()) { - break; - } - - if (ins.isBranch() || ins.isJump()) { - - if (deobfuscate && (ins instanceof ActionIf) && !stack.isEmpty() && (stack.peek().isCompileTime() && (!stack.peek().hasSideEffect()))) { - boolean condition = EcmaScript.toBoolean(stack.peek().getResult()); - if (debugMode) { - if (condition) { - System.err.println("JUMP"); - } else { - System.err.println("SKIP"); - } - } - stack.pop(); - getConstantPool(listeners, cpool, localData, stack, output, code, condition ? (code.adr2pos(((ActionIf) ins).getAddress() + ((ActionIf) ins).getBytes(code.version).length + ((ActionIf) ins).getJumpOffset())) : ip + 1, constantPools, visited, version, endIp, path); - } else { - if (deobfuscate && ins instanceof ActionIf) { - stack.pop(); - } - visited.add(ip); - List branches = ins.getBranches(code); - for (int b : branches) { - @SuppressWarnings("unchecked") - Stack brStack = (Stack) stack.clone(); - if (b >= 0) { - getConstantPool(listeners, cpool, prepareLocalBranch(localData), brStack, output, code, b, constantPools, visited, version, endIp, path); - } else { - if (debugMode) { - System.out.println("Negative branch:" + b); - } - } - } - } - break; - } - ip++; - }; - if (ip < 0) { - System.out.println("Visited Negative: " + ip); - } - for (DisassemblyListener listener : listeners) { - listener.progress("constantpool", ip + 1, code.size()); - } - } - - public static List getConstantPool(List listeners, ActionGraphSource code, int addr, int version, String path) { - List ret = new ArrayList<>(); - List localData = Helper.toList(new HashMap(), new HashMap(), new HashMap()); - try { - getConstantPool(listeners, null, localData, new Stack(), new ArrayList(), code, code.adr2pos(addr), ret, new ArrayList(), version, -1, path); - } catch (Exception ex) { - log.log(Level.SEVERE, "Error during getting constantpool", ex); - } - return ret; - } +// @SuppressWarnings("unchecked") +// private static void getConstantPool(List listeners, ConstantPool cpool, List localData, Stack stack, List output, ActionGraphSource code, int ip, List constantPools, List visited, int version, int endIp, String path) { +// boolean debugMode = false; +// boolean deobfuscate = Configuration.getConfig("autoDeobfuscate", true); +// while (((endIp == -1) || (endIp > ip)) && (ip > -1) && ip < code.size()) { +// if (visited.contains(ip)) { +// break; +// } +// for (int i = 0; i < listeners.size(); i++) { +// listeners.get(i).progress("constantpool", ip + 1, code.size()); +// } +// GraphSourceItem ins = code.get(ip); +// if (ins.isIgnored()) { +// if (ins.isExit()) { +// break; +// } +// ip++; +// continue; +// } +// +// if (ins instanceof GraphSourceItemContainer) { +// GraphSourceItemContainer cnt = (GraphSourceItemContainer) ins; +// String cntName = cnt.getName(); +// if (ins instanceof Action) { +// List> output2s = new ArrayList<>(); +// long endAddr = ((Action) ins).getAddress() + cnt.getHeaderSize(); +// for (long size : cnt.getContainerSizes()) { +// if (size == 0) { +// output2s.add(new ArrayList()); +// continue; +// } +// List localData2 = Helper.toList(new HashMap(), new HashMap(), new HashMap()); +// List output2 = new ArrayList<>(); +// output2s.add(output2); +// getConstantPool(listeners, cpool, localData2, new Stack(), output2, code, code.adr2pos(endAddr), constantPools, visited, version, code.adr2pos(endAddr + size), path + (cntName == null ? "" : "/" + cntName)); +// endAddr += size; +// } +// if (deobfuscate) { +// cnt.translateContainer(output2s, stack, output, (HashMap) localData.get(0), (HashMap) localData.get(1), (HashMap) localData.get(2)); +// } +// ip = code.adr2pos(endAddr); +// continue; +// } +// } +// if (ins instanceof ActionPush) { +// if (cpool != null) { +// ((ActionPush) ins).constantPool = cpool.constants; +// cpool.count++; +// } +// } +// if (ins instanceof ActionDefineFunction) { +// if (cpool != null) { +// //((ActionDefineFunction) ins).setConstantPool(cpool.constants,code.getActions()); +// cpool.count++; +// } +// } +// if (ins instanceof ActionDefineFunction2) { +// if (cpool != null) { +// //((ActionDefineFunction2) ins).setConstantPool(cpool.constants,code.getActions()); +// cpool.count++; +// } +// } +// if (debugMode) { +// String add = ""; +// if (ins instanceof ActionIf) { +// add += " change:" + ((ActionIf) ins).getJumpOffset(); +// } +// if (ins instanceof ActionJump) { +// add += " change:" + (((ActionJump) ins).getJumpOffset()); +// } +// System.err.println("getConstantPool ip " + ip + ", addr " + Helper.formatAddress(((Action) ins).getAddress()) + ": " + ((Action) ins).getASMSource(new ArrayList(), new ArrayList(), cpool == null ? null : cpool.constants, version, false) + add + " stack:" + Helper.stackToString(stack, Helper.toList(cpool))); +// } +// if (ins instanceof ActionConstantPool) { +// constantPools.add(new ConstantPool(((ActionConstantPool) ins).constantPool)); +// if (cpool == null) { +// cpool = new ConstantPool(); +// } +// cpool.setNew(((ActionConstantPool) ins).constantPool); +// } +// +// //for..in return +// if (deobfuscate) { +// if (((ins instanceof ActionEquals) || (ins instanceof ActionEquals2)) && (stack.size() == 1) && (stack.peek() instanceof DirectValueActionItem)) { +// stack.push(new DirectValueActionItem(null, 0, new Null(), new ArrayList())); +// } +// try { +// ins.translate(localData, stack, output, Graph.SOP_USE_STATIC/*Graph.SOP_SKIP_STATIC*/, null); +// } catch (Exception ex) { +// Logger.getLogger(SWFInputStream.class.getName()).log(Level.SEVERE, "Error during getting constantpool", ex); +// } +// } +// if (ins.isExit()) { +// break; +// } +// +// if (ins.isBranch() || ins.isJump()) { +// +// if (deobfuscate && (ins instanceof ActionIf) && !stack.isEmpty() && (stack.peek().isCompileTime() && (!stack.peek().hasSideEffect()))) { +// boolean condition = EcmaScript.toBoolean(stack.peek().getResult()); +// if (debugMode) { +// if (condition) { +// System.err.println("JUMP"); +// } else { +// System.err.println("SKIP"); +// } +// } +// stack.pop(); +// getConstantPool(listeners, cpool, localData, stack, output, code, condition ? (code.adr2pos(((ActionIf) ins).getAddress() + ((ActionIf) ins).getBytes(code.version).length + ((ActionIf) ins).getJumpOffset())) : ip + 1, constantPools, visited, version, endIp, path); +// } else { +// if (deobfuscate && ins instanceof ActionIf) { +// stack.pop(); +// } +// visited.add(ip); +// List branches = ins.getBranches(code); +// for (int b : branches) { +// @SuppressWarnings("unchecked") +// Stack brStack = (Stack) stack.clone(); +// if (b >= 0) { +// getConstantPool(listeners, cpool, prepareLocalBranch(localData), brStack, output, code, b, constantPools, visited, version, endIp, path); +// } else { +// if (debugMode) { +// System.out.println("Negative branch:" + b); +// } +// } +// } +// } +// break; +// } +// ip++; +// }; +// if (ip < 0) { +// System.out.println("Visited Negative: " + ip); +// } +// for (DisassemblyListener listener : listeners) { +// listener.progress("constantpool", ip + 1, code.size()); +// } +// } +// +// public static List getConstantPool(List listeners, ActionGraphSource code, int addr, int version, String path) { +// List ret = new ArrayList<>(); +// List localData = Helper.toList(new HashMap(), new HashMap(), new HashMap()); +// try { +// getConstantPool(listeners, null, localData, new Stack(), new ArrayList(), code, code.adr2pos(addr), ret, new ArrayList(), version, -1, path); +// } catch (Exception ex) { +// log.log(Level.SEVERE, "Error during getting constantpool", ex); +// } +// return ret; +// } private static List prepareLocalBranch(List localData) { @SuppressWarnings("unchecked") @@ -724,7 +724,7 @@ public class SWFInputStream extends InputStream { * @return List of actions * @throws IOException */ - public static List readActionList(List listeners, long address, long containerSWFOffset, ReReadableInputStream rri, int version, int ip, int endip, String path) throws IOException { + public static List readActionList(List listeners, long containerSWFOffset, ReReadableInputStream rri, int version, int ip, int endip, String path) throws IOException { List retdups = new ArrayList<>(); ConstantPool cpool = new ConstantPool(); @@ -742,7 +742,7 @@ public class SWFInputStream extends InputStream { method = 2; goesPrev = readActionListAtPos(true, localData, stack, cpool, sis, rri, ip, retdups, ip); }*/ - goesPrev = readActionListAtPos(listeners, new ArrayList(), new HashMap>(), address, containerSWFOffset, localData, stack, cpool, sis, rri, ip, retdups, ip, endip, path, new HashMap(), false, new HashMap>()); + goesPrev = readActionListAtPos(listeners, new ArrayList(), new HashMap>(), containerSWFOffset, localData, stack, cpool, sis, rri, ip, retdups, ip, endip, path, new HashMap(), false, new HashMap>()); if (goesPrev) { } else { @@ -771,13 +771,15 @@ public class SWFInputStream extends InputStream { } } - List pools; - ret = Action.removeNops(0, ret, version, 0, path); - pools = getConstantPool(listeners, new ActionGraphSource(ret, version, new HashMap(), new HashMap(), new HashMap()), 0, version, path); - - if (pools.size() == 1) { - Action.setConstantPool(ret, pools.get(0)); + //List pools; + if (Configuration.getConfig("removeNops", true)) { + ret = Action.removeNops(0, ret, version, 0, path); } + //pools = getConstantPool(listeners, new ActionGraphSource(ret, version, new HashMap(), new HashMap(), new HashMap()), 0, version, path); + + /*if (pools.size() == 1) { + Action.setConstantPool(ret, pools.get(0)); + }*/ if (goesPrev && (!DEOBFUSCATION_ALL_CODE_IN_PREVIOUS_TAG)) { ActionJump aj = new ActionJump(ip); int skip = aj.getBytes(version).length; @@ -801,7 +803,7 @@ public class SWFInputStream extends InputStream { } @SuppressWarnings("unchecked") - private static boolean readActionListAtPos(List listeners, List output, HashMap> containers, long address, long containerSWFOffset, List localData, Stack stack, ConstantPool cpool, SWFInputStream sis, ReReadableInputStream rri, int ip, List ret, int startIp, int endip, String path, Map visited, boolean indeterminate, Map> decisionStates) throws IOException { + private static boolean readActionListAtPos(List listeners, List output, HashMap> containers, long containerSWFOffset, List localData, Stack stack, ConstantPool cpool, SWFInputStream sis, ReReadableInputStream rri, int ip, List ret, int startIp, int endip, String path, Map visited, boolean indeterminate, Map> decisionStates) throws IOException { boolean debugMode = false; boolean decideBranch = false; @@ -813,7 +815,7 @@ public class SWFInputStream extends InputStream { Scanner sc = new Scanner(System.in, "utf-8"); int prevIp = ip; loopip: - while (((endip == -1) || (endip > ip)) && (a = sis.readAction(rri)) != null) { + while (((endip == -1) || (endip > ip)) && (a = sis.readAction(rri, cpool)) != null) { if (!visited.containsKey(ip)) { visited.put(ip, 0); } @@ -853,7 +855,7 @@ public class SWFInputStream extends InputStream { /*if(a instanceof ActionConstantPool){ throw new IllegalArgumentException("CP found"); - } */ + } */ if (a instanceof ActionPush) { if (cpool != null) { ((ActionPush) a).constantPool = cpool.constants; @@ -1041,7 +1043,7 @@ public class SWFInputStream extends InputStream { } else { localData2 = localData; } - readActionListAtPos(listeners, output2, containers, address, containerSWFOffset, localData2, new Stack(), cpool, sis, rri, (int) endAddr, ret, startIp, (int) (endAddr + size), path + (cntName == null ? "" : "/" + cntName), visited, indeterminate, decisionStates); + readActionListAtPos(listeners, output2, containers, containerSWFOffset, localData2, new Stack(), cpool, sis, rri, (int) endAddr, ret, startIp, (int) (endAddr + size), path + (cntName == null ? "" : "/" + cntName), visited, indeterminate, decisionStates); output2s.add(output2); endAddr += size; } @@ -1118,7 +1120,7 @@ public class SWFInputStream extends InputStream { int oldPos = rri.getPos(); @SuppressWarnings("unchecked") Stack substack = (Stack) stack.clone(); - if (readActionListAtPos(listeners, output, containers, address, containerSWFOffset, prepareLocalBranch(localData), substack, cpool, sis, rri, rri.getPos() + aif.getJumpOffset(), ret, startIp, endip, path, visited, indeterminate, decisionStates)) { + if (readActionListAtPos(listeners, output, containers, containerSWFOffset, prepareLocalBranch(localData), substack, cpool, sis, rri, rri.getPos() + aif.getJumpOffset(), ret, startIp, endip, path, visited, indeterminate, decisionStates)) { retv = true; } rri.setPos(oldPos); @@ -1659,8 +1661,8 @@ public class SWFInputStream extends InputStream { return ret; } - public Action readAction() throws IOException { - return readAction(new ReReadableInputStream(this)); + public Action readAction(ConstantPool cpool) throws IOException { + return readAction(new ReReadableInputStream(this), cpool); } /** @@ -1670,7 +1672,7 @@ public class SWFInputStream extends InputStream { * @return Action or null when ActionEndFlag or end of the stream * @throws IOException */ - public Action readAction(ReReadableInputStream rri) throws IOException { + public Action readAction(ReReadableInputStream rri, ConstantPool cpool) throws IOException { { int actionCode = -1; @@ -1708,7 +1710,7 @@ public class SWFInputStream extends InputStream { case 0x09: return new ActionStopSounds(); case 0x8A: - return new ActionWaitForFrame(this); + return new ActionWaitForFrame(this, cpool); case 0x8B: return new ActionSetTarget(actionLength, this, version); case 0x8C: @@ -1789,7 +1791,7 @@ public class SWFInputStream extends InputStream { case 0x28: return new ActionEndDrag(); case 0x8D: - return new ActionWaitForFrame2(this); + return new ActionWaitForFrame2(this, cpool); case 0x26: return new ActionTrace(); case 0x34: diff --git a/trunk/src/com/jpexs/decompiler/flash/action/Action.java b/trunk/src/com/jpexs/decompiler/flash/action/Action.java index 264b0df3c..330eb41b2 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/Action.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/Action.java @@ -418,10 +418,10 @@ public class Action implements GraphSourceItem { //setActionsAddresses(list, 0, version); importantOffsets = getActionsAllRefs(list, version); } - List cps = SWFInputStream.getConstantPool(new ArrayList(), new ActionGraphSource(list, version, new HashMap(), new HashMap(), new HashMap()), 0, version, path); + /*List cps = SWFInputStream.getConstantPool(new ArrayList(), new ActionGraphSource(list, version, new HashMap(), new HashMap(), new HashMap()), 0, version, path); if (!cps.isEmpty()) { setConstantPool(list, cps.get(cps.size() - 1)); - } + }*/ HashMap> containers = new HashMap<>(); HashMap containersPos = new HashMap<>(); offset = address; @@ -1199,7 +1199,7 @@ public class Action implements GraphSourceItem { String s = null; try { s = Action.actionsToString(new ArrayList(), address, ret, null, version, false, false, swfPos, path); - ret = ASMParser.parse(address, swfPos, true, new StringReader(s), SWF.DEFAULT_VERSION); + ret = ASMParser.parse(address, swfPos, true, s, SWF.DEFAULT_VERSION); } catch (Exception ex) { Logger.getLogger(SWFInputStream.class.getName()).log(Level.SEVERE, "parsing error", ex); } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java b/trunk/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java index c66e9c1cc..e620e964d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java @@ -32,6 +32,7 @@ import com.jpexs.decompiler.graph.GraphSourceItemContainer; import com.jpexs.helpers.Helper; import java.io.IOException; import java.io.Reader; +import java.io.StringReader; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -44,10 +45,16 @@ public class ASMParser { public static List parse(long containerSWFOffset, boolean ignoreNops, List