diff --git a/src/com/jpexs/decompiler/flash/SWFOutputStream.java b/src/com/jpexs/decompiler/flash/SWFOutputStream.java index 22a6848e9..951e620ae 100644 --- a/src/com/jpexs/decompiler/flash/SWFOutputStream.java +++ b/src/com/jpexs/decompiler/flash/SWFOutputStream.java @@ -123,6 +123,13 @@ public class SWFOutputStream extends OutputStream { pos++; } + @Override + public void write(byte[] b) throws IOException { + alignByte(); + os.write(b); + pos += b.length; + } + private void alignByte() throws IOException { if (bitPos > 0) { bitPos = 0; diff --git a/src/com/jpexs/decompiler/flash/action/Action.java b/src/com/jpexs/decompiler/flash/action/Action.java index 614c7bacd..41e2468d5 100644 --- a/src/com/jpexs/decompiler/flash/action/Action.java +++ b/src/com/jpexs/decompiler/flash/action/Action.java @@ -498,14 +498,15 @@ public class Action implements GraphSourceItem { } else { //if (!(a instanceof ActionNop)) { String add = ""; - if (a instanceof ActionIf) { + // honfika: commented out the following lines, because it makes no sense + /*if (a instanceof ActionIf) { add = " change: " + ((ActionIf) a).getJumpOffset(); } if (a instanceof ActionJump) { add = " change: " + ((ActionJump) a).getJumpOffset(); } add = "; ofs" + Helper.formatAddress(offset) + add; - add = ""; + add = "";*/ if ((a instanceof ActionPush) && lastPush) { writer.appendNoHilight(" "); ((ActionPush) a).paramsToStringReplaced(list, importantOffsets, constantPool, version, exportMode, writer); @@ -552,7 +553,7 @@ public class Action implements GraphSourceItem { } //} } - offset += a.getBytes(version).length; + offset += a.getTotalActionLength(); } if (lastPush) { writer.newLine(); @@ -1184,14 +1185,10 @@ public class Action implements GraphSourceItem { public static List removeNops(long address, List actions, int version, String path) { List ret = actions; - if (true) { - //return ret; - } - String s = null; try { HilightedTextWriter writer = new HilightedTextWriter(Configuration.getCodeFormatting(), false); Action.actionsToString(new ArrayList(), address, ret, version, ScriptExportMode.PCODE, writer, path); - s = writer.toString(); + String s = writer.toString(); ret = ASMParser.parse(address, true, s, SWF.DEFAULT_VERSION, false); } catch (IOException | ParseException ex) { Logger.getLogger(SWFInputStream.class.getName()).log(Level.SEVERE, "parsing error. path: " + path, ex); diff --git a/src/com/jpexs/decompiler/flash/action/ActionListReader.java b/src/com/jpexs/decompiler/flash/action/ActionListReader.java index 56b2bef64..7e4e956da 100644 --- a/src/com/jpexs/decompiler/flash/action/ActionListReader.java +++ b/src/com/jpexs/decompiler/flash/action/ActionListReader.java @@ -55,6 +55,7 @@ import java.util.Map; import java.util.Queue; import java.util.Scanner; import java.util.Stack; +import java.util.TreeMap; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -125,20 +126,24 @@ public class ActionListReader { private static List readActionList(List listeners, SWFInputStream sis, int version, int ip, int endIp, String path) throws IOException, InterruptedException { ConstantPool cpool = new ConstantPool(); - // List of the actions. N. item contains the action which starts in offset N. - List actionMap = new ArrayList<>(); - List nextOffsets = new ArrayList<>(); + // Map of the actions. Use TreeMap to sort the keys in ascending order + Map actionMap = new TreeMap<>(); + Map nextOffsets = new HashMap<>(); Action entryAction = readActionListAtPos(listeners, cpool, sis, actionMap, nextOffsets, ip, ip, endIp, version, path, false, new ArrayList()); - Map> containerLastActions = new HashMap<>(); - getContainerLastActions(actionMap, containerLastActions); - List actions = new ArrayList<>(); + if (actionMap.isEmpty()) { + return actions; + } + + Map> containerLastActions = new HashMap<>(); + List addresses = new ArrayList<>(actionMap.keySet()); + getContainerLastActions(actionMap, addresses, containerLastActions); // jump to the entry action when it is diffrent from the first action in the map - int index = getNextNotNullIndex(actionMap, 0); + long index = addresses.get(0); if (index != -1 && entryAction != actionMap.get(index)) { ActionJump jump = new ActionJump(0); int size = jump.getTotalActionLength(); @@ -147,11 +152,11 @@ public class ActionListReader { } // remove nulls - index = getNextNotNullIndex(actionMap, index); + index = getNextAddress(addresses, index); while (index > -1) { Action action = actionMap.get(index); long nextOffset = nextOffsets.get(index); - int nextIndex = getNextNotNullIndex(actionMap, index + 1); + long nextIndex = getNextAddress(addresses, index + 1); actions.add(action); if (nextIndex != -1 && nextOffset != nextIndex) { if (!action.isExit() && !(action instanceof ActionJump)) { @@ -170,7 +175,7 @@ public class ActionListReader { Map jumps = new HashMap<>(); getJumps(actions, jumps); - long endAddress = updateAddresses(actions, ip, version); + long endAddress = updateAddresses(actions, 0, version); // add end action Action lastAction = actions.get(actions.size() - 1); @@ -189,7 +194,7 @@ public class ActionListReader { if (Configuration.autoDeobfuscate.get()) { try { - actions = deobfuscateActionList(listeners, actions, version, ip, path); + actions = deobfuscateActionList(listeners, actions, version, 0, path); updateActionLengths(actions, version); removeZeroJumps(actions, version); } catch (OutOfMemoryError | StackOverflowError | TranslateException ex) { @@ -222,7 +227,7 @@ public class ActionListReader { Action lastAction = actions.get(actions.size() - 1); int endIp = (int) lastAction.getAddress(); - List retdups = new ArrayList<>(); + List retdups = new ArrayList<>(endIp); for (int i = 0; i < endIp; i++) { Action a = new ActionNop(); a.setAddress(i, version); @@ -257,11 +262,6 @@ public class ActionListReader { deobfustaceActionListAtPosRecursive(listeners, new ArrayList(), new HashMap>(), localData, stack, cpool, actionMap, ip, retdups, ip, endIp, path, new HashMap(), false, new HashMap>(), version, 0, maxRecursionLevel); - if (!retdups.isEmpty()) { - for (int i = 0; i < ip; i++) { - retdups.remove(0); - } - } List ret = new ArrayList<>(); Action last = null; for (Action a : retdups) { @@ -280,25 +280,42 @@ public class ActionListReader { return reta; } - private static int getPrevNotNullIndex(List actionMap, int startIndex) { - startIndex = Math.min(startIndex, actionMap.size() - 1); - for (int i = startIndex; i >= 0; i--) { - if (actionMap.get(i) != null) { - return i; - } + private static long getNextAddress(List addresses, long address) { + int min = 0; + int max = addresses.size() - 1; + + while (max >= min) { + int mid = (min + max) / 2; + long midValue = addresses.get(mid); + if(midValue == address) + return address; + else if (midValue < address) + min = mid + 1; + else + max = mid - 1; } - return -1; + + return min < addresses.size() ? addresses.get(min) : -1; } - - private static int getNextNotNullIndex(List actionMap, int startIndex) { - for (int i = startIndex; i < actionMap.size(); i++) { - if (actionMap.get(i) != null) { - return i; - } + + private static long getPrevAddress(List addresses, long address) { + int min = 0; + int max = addresses.size() - 1; + + while (max >= min) { + int mid = (min + max) / 2; + long midValue = addresses.get(mid); + if(midValue == address) + return address; + else if (midValue < address) + min = mid + 1; + else + max = mid - 1; } - return -1; + + return max > 0 ? addresses.get(max) : -1; } - + private static Map actionListToMap(List actions) { Map map = new HashMap<>(actions.size()); for (Action a : actions) { @@ -343,12 +360,9 @@ public class ActionListReader { } } - private static void getContainerLastActions(List actionMap, Map> lastActions) { - for (int i = 0; i < actionMap.size(); i++) { - Action a = actionMap.get(i); - if (a == null) { - continue; - } + private static void getContainerLastActions(Map actionMap, List addresses, Map> lastActions) { + for (Long address : actionMap.keySet()) { + Action a = actionMap.get(address); if (a instanceof GraphSourceItemContainer) { GraphSourceItemContainer container = (GraphSourceItemContainer) a; @@ -357,7 +371,7 @@ public class ActionListReader { List lasts = new ArrayList<>(sizes.size()); for (long size : sizes) { endAddress += size; - int lastActionIndex = getPrevNotNullIndex(actionMap, (int) (endAddress - 1)); + long lastActionIndex = getPrevAddress(addresses, endAddress); Action lastAction = null; if (lastActionIndex != -1) { lastAction = actionMap.get(lastActionIndex); @@ -519,19 +533,16 @@ public class ActionListReader { long startIp = actions.get(0).getAddress(); Action lastAction = actions.get(actions.size() - 1); - int lastIdx = (int) lastAction.getAddress(); long endAddress = lastAction.getAddress() + lastAction.getTotalActionLength(); - List actionMap = new ArrayList<>(lastIdx); - for (int i = 0; i <= lastIdx; i++) { - actionMap.add(null); - } + Map actionMap = new TreeMap<>(); for (Action a : actions) { - actionMap.set((int) a.getAddress(), a); + actionMap.put(a.getAddress(), a); } + List addresses = new ArrayList<>(actionMap.keySet()); Map> containerLastActions = new HashMap<>(); - getContainerLastActions(actionMap, containerLastActions); + getContainerLastActions(actionMap, addresses, containerLastActions); Map jumps = new HashMap<>(); getJumps(actions, jumps); @@ -575,7 +586,7 @@ public class ActionListReader { } private static Action readActionListAtPos(List listeners, ConstantPool cpool, - SWFInputStream sis, List actions, List nextOffsets, + SWFInputStream sis, Map actions, Map nextOffsets, long ip, long startIp, long endIp, int version, String path, boolean indeterminate, List visitedContainers) throws IOException { Action entryAction = null; @@ -589,7 +600,7 @@ public class ActionListReader { jumpQueue.add(ip); while (!jumpQueue.isEmpty()) { ip = jumpQueue.remove(); - while ((endIp == -1) || (endIp > ip)) { + while (endIp == -1 || endIp > ip) { sis.seek((int) ip); Action a; @@ -613,15 +624,13 @@ public class ActionListReader { entryAction = a; } - ensureCapacity(actions, nextOffsets, ip); - - Action existingAction = actions.get((int) ip); + Action existingAction = actions.get(ip); if (existingAction != null) { break; } - actions.set((int) ip, a); - nextOffsets.set((int) ip, ip + actionLengthWithHeader); + actions.put(ip, a); + nextOffsets.put(ip, ip + actionLengthWithHeader); long pos = sis.getPos(); long length = pos + sis.available(); @@ -677,13 +686,6 @@ public class ActionListReader { return entryAction; } - private static void ensureCapacity(List actions, List nextOffsets, long index) { - while (actions.size() <= index) { - actions.add(null); - nextOffsets.add(-1L); - } - } - private static void deobfustaceActionListAtPosRecursive(List listeners, List output, HashMap> containers, ActionLocalData localData, Stack 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/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java b/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java index c3cf29e34..fd4c1876d 100644 --- a/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java +++ b/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java @@ -170,7 +170,7 @@ public class ASMParser { containers.pop(); } } else if (symb.type == ASMParsedSymbol.TYPE_INSTRUCTION_NAME) { - String instructionName = ((String) symb.value).toLowerCase(); + String instructionName = (String) symb.value; Action a = parseAction(instructionName, lexer, constantPool, version); if (ignoreNops && a instanceof ActionNop) { a = null; @@ -202,211 +202,211 @@ public class ASMParser { private static Action parseAction(String instructionName, FlasmLexer lexer, List constantPool, int version) throws IOException, ParseException { Action a = null; - if (instructionName.equals("GetURL".toLowerCase())) { + if (instructionName.compareToIgnoreCase("GetURL") == 0) { a = new ActionGetURL(lexer); - } else if (instructionName.equals("GoToLabel".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("GoToLabel") == 0) { a = (new ActionGoToLabel(lexer)); - } else if (instructionName.equals("GotoFrame".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("GotoFrame") == 0) { a = (new ActionGotoFrame(lexer)); - } else if (instructionName.equals("NextFrame".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("NextFrame") == 0) { a = (new ActionNextFrame()); - } else if (instructionName.equals("Play".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Play") == 0) { a = (new ActionPlay()); - } else if (instructionName.equals("PrevFrame".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("PrevFrame") == 0) { a = (new ActionPrevFrame()); - } else if (instructionName.equals("SetTarget".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("SetTarget") == 0) { a = (new ActionSetTarget(lexer)); - } else if (instructionName.equals("Stop".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Stop") == 0) { a = (new ActionStop()); - } else if (instructionName.equals("StopSounds".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("StopSounds") == 0) { a = (new ActionStopSounds()); - } else if (instructionName.equals("ToggleQuality".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("ToggleQuality") == 0) { a = (new ActionToggleQuality()); - } else if (instructionName.equals("WaitForFrame".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("WaitForFrame") == 0) { a = (new ActionWaitForFrame(lexer)); - } else if (instructionName.equals("Add".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Add") == 0) { a = (new ActionAdd()); - } else if (instructionName.equals("And".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("And") == 0) { a = (new ActionAnd()); - } else if (instructionName.equals("AsciiToChar".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("AsciiToChar") == 0) { a = (new ActionAsciiToChar()); - } else if (instructionName.equals("Call".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Call") == 0) { a = (new ActionCall()); - } else if (instructionName.equals("CharToAscii".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("CharToAscii") == 0) { a = (new ActionCharToAscii()); - } else if (instructionName.equals("CloneSprite".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("CloneSprite") == 0) { a = (new ActionCloneSprite()); - } else if (instructionName.equals("Divide".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Divide") == 0) { a = (new ActionDivide()); - } else if (instructionName.equals("EndDrag".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("EndDrag") == 0) { a = (new ActionEndDrag()); - } else if (instructionName.equals("Equals".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Equals") == 0) { a = (new ActionEquals()); - } else if (instructionName.equals("GetProperty".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("GetProperty") == 0) { a = (new ActionGetProperty()); - } else if (instructionName.equals("GetTime".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("GetTime") == 0) { a = (new ActionGetTime()); - } else if (instructionName.equals("GetURL2".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("GetURL2") == 0) { a = (new ActionGetURL2(lexer)); - } else if (instructionName.equals("GetVariable".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("GetVariable") == 0) { a = (new ActionGetVariable()); - } else if (instructionName.equals("GotoFrame2".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("GotoFrame2") == 0) { a = (new ActionGotoFrame2(lexer)); - } else if (instructionName.equals("If".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("If") == 0) { a = (new ActionIf(lexer)); - } else if (instructionName.equals("Jump".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Jump") == 0) { a = (new ActionJump(lexer)); - } else if (instructionName.equals("Less".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Less") == 0) { a = (new ActionLess()); - } else if (instructionName.equals("MBAsciiToChar".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("MBAsciiToChar") == 0) { a = (new ActionMBAsciiToChar()); - } else if (instructionName.equals("MBCharToAscii".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("MBCharToAscii") == 0) { a = (new ActionMBCharToAscii()); - } else if (instructionName.equals("MBStringExtract".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("MBStringExtract") == 0) { a = (new ActionMBStringExtract()); - } else if (instructionName.equals("MBStringLength".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("MBStringLength") == 0) { a = (new ActionMBStringLength()); - } else if (instructionName.equals("Multiply".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Multiply") == 0) { a = (new ActionMultiply()); - } else if (instructionName.equals("Not".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Not") == 0) { a = (new ActionNot()); - } else if (instructionName.equals("Or".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Or") == 0) { a = (new ActionOr()); - } else if (instructionName.equals("Pop".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Pop") == 0) { a = (new ActionPop()); - } else if (instructionName.equals("Push".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Push") == 0) { a = (new ActionPush(lexer, constantPool)); - } else if (instructionName.equals("RandomNumber".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("RandomNumber") == 0) { a = (new ActionRandomNumber()); - } else if (instructionName.equals("RemoveSprite".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("RemoveSprite") == 0) { a = (new ActionRemoveSprite()); - } else if (instructionName.equals("SetProperty".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("SetProperty") == 0) { a = (new ActionSetProperty()); - } else if (instructionName.equals("SetTarget2".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("SetTarget2") == 0) { a = (new ActionSetTarget2()); - } else if (instructionName.equals("SetVariable".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("SetVariable") == 0) { a = (new ActionSetVariable()); - } else if (instructionName.equals("StartDrag".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("StartDrag") == 0) { a = (new ActionStartDrag()); - } else if (instructionName.equals("StringAdd".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("StringAdd") == 0) { a = (new ActionStringAdd()); - } else if (instructionName.equals("StringEquals".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("StringEquals") == 0) { a = (new ActionStringEquals()); - } else if (instructionName.equals("StringExtract".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("StringExtract") == 0) { a = (new ActionStringExtract()); - } else if (instructionName.equals("StringLength".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("StringLength") == 0) { a = (new ActionStringLength()); - } else if (instructionName.equals("StringLess".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("StringLess") == 0) { a = (new ActionStringLess()); - } else if (instructionName.equals("Subtract".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Subtract") == 0) { a = (new ActionSubtract()); - } else if (instructionName.equals("ToInteger".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("ToInteger") == 0) { a = (new ActionToInteger()); - } else if (instructionName.equals("Trace".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Trace") == 0) { a = (new ActionTrace()); - } else if (instructionName.equals("WaitForFrame2".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("WaitForFrame2") == 0) { a = (new ActionWaitForFrame2(lexer)); - } else if (instructionName.equals("Add2".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Add2") == 0) { a = (new ActionAdd2()); - } else if (instructionName.equals("BitAnd".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("BitAnd") == 0) { a = (new ActionBitAnd()); - } else if (instructionName.equals("BitLShift".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("BitLShift") == 0) { a = (new ActionBitLShift()); - } else if (instructionName.equals("BitOr".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("BitOr") == 0) { a = (new ActionBitOr()); - } else if (instructionName.equals("BitRShift".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("BitRShift") == 0) { a = (new ActionBitRShift()); - } else if (instructionName.equals("BitURShift".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("BitURShift") == 0) { a = (new ActionBitURShift()); - } else if (instructionName.equals("BitXor".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("BitXor") == 0) { a = (new ActionBitXor()); - } else if (instructionName.equals("CallFunction".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("CallFunction") == 0) { a = (new ActionCallFunction()); - } else if (instructionName.equals("CallMethod".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("CallMethod") == 0) { a = (new ActionCallMethod()); - } else if (instructionName.equals("ConstantPool".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("ConstantPool") == 0) { a = new ActionConstantPool(lexer); - } else if (instructionName.equals("Decrement".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Decrement") == 0) { a = (new ActionDecrement()); - } else if (instructionName.equals("DefineFunction".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("DefineFunction") == 0) { a = (new ActionDefineFunction(lexer)); - } else if (instructionName.equals("DefineLocal".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("DefineLocal") == 0) { a = (new ActionDefineLocal()); - } else if (instructionName.equals("DefineLocal2".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("DefineLocal2") == 0) { a = (new ActionDefineLocal2()); - } else if (instructionName.equals("Delete".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Delete") == 0) { a = (new ActionDelete()); - } else if (instructionName.equals("Delete2".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Delete2") == 0) { a = (new ActionDelete2()); - } else if (instructionName.equals("Enumerate".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Enumerate") == 0) { a = (new ActionEnumerate()); - } else if (instructionName.equals("Equals2".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Equals2") == 0) { a = (new ActionEquals2()); - } else if (instructionName.equals("GetMember".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("GetMember") == 0) { a = (new ActionGetMember()); - } else if (instructionName.equals("Increment".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Increment") == 0) { a = (new ActionIncrement()); - } else if (instructionName.equals("InitArray".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("InitArray") == 0) { a = (new ActionInitArray()); - } else if (instructionName.equals("InitObject".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("InitObject") == 0) { a = (new ActionInitObject()); - } else if (instructionName.equals("Less2".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Less2") == 0) { a = (new ActionLess2()); - } else if (instructionName.equals("Modulo".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Modulo") == 0) { a = (new ActionModulo()); - } else if (instructionName.equals("NewMethod".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("NewMethod") == 0) { a = (new ActionNewMethod()); - } else if (instructionName.equals("NewObject".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("NewObject") == 0) { a = (new ActionNewObject()); - } else if (instructionName.equals("PushDuplicate".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("PushDuplicate") == 0) { a = (new ActionPushDuplicate()); - } else if (instructionName.equals("Return".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Return") == 0) { a = (new ActionReturn()); - } else if (instructionName.equals("SetMember".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("SetMember") == 0) { a = (new ActionSetMember()); - } else if (instructionName.equals("StackSwap".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("StackSwap") == 0) { a = (new ActionStackSwap()); - } else if (instructionName.equals("StoreRegister".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("StoreRegister") == 0) { a = (new ActionStoreRegister(lexer)); - } else if (instructionName.equals("TargetPath".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("TargetPath") == 0) { a = (new ActionTargetPath()); - } else if (instructionName.equals("ToNumber".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("ToNumber") == 0) { a = (new ActionToNumber()); - } else if (instructionName.equals("ToString".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("ToString") == 0) { a = (new ActionToString()); - } else if (instructionName.equals("TypeOf".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("TypeOf") == 0) { a = (new ActionTypeOf()); - } else if (instructionName.equals("With".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("With") == 0) { a = (new ActionWith(lexer)); - } else if (instructionName.equals("Enumerate2".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Enumerate2") == 0) { a = (new ActionEnumerate2()); - } else if (instructionName.equals("Greater".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Greater") == 0) { a = (new ActionGreater()); - } else if (instructionName.equals("InstanceOf".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("InstanceOf") == 0) { a = (new ActionInstanceOf()); - } else if (instructionName.equals("StrictEquals".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("StrictEquals") == 0) { a = (new ActionStrictEquals()); - } else if (instructionName.equals("StringGreater".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("StringGreater") == 0) { a = (new ActionStringGreater()); - } else if (instructionName.equals("CastOp".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("CastOp") == 0) { a = (new ActionCastOp()); - } else if (instructionName.equals("DefineFunction2".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("DefineFunction2") == 0) { a = (new ActionDefineFunction2(lexer)); - } else if (instructionName.equals("Extends".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Extends") == 0) { a = (new ActionExtends()); - } else if (instructionName.equals("ImplementsOp".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("ImplementsOp") == 0) { a = (new ActionImplementsOp()); - } else if (instructionName.equals("Throw".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Throw") == 0) { a = (new ActionThrow()); - } else if (instructionName.equals("Try".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Try") == 0) { a = (new ActionTry(lexer, version)); - } else if (instructionName.equals("FSCommand2".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("FSCommand2") == 0) { a = (new ActionFSCommand2()); - } else if (instructionName.equals("StrictMode".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("StrictMode") == 0) { a = (new ActionStrictMode(lexer)); - } else if (instructionName.equals("Nop".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("Nop") == 0) { a = (new ActionNop()); - } else if (instructionName.equals("FFDec_DeobfuscatePop".toLowerCase())) { + } else if (instructionName.compareToIgnoreCase("FFDec_DeobfuscatePop") == 0) { a = (new ActionDeobfuscatePop()); } else { throw new ParseException("Unknown instruction name :" + instructionName, lexer.yyline()); @@ -429,7 +429,7 @@ public class ASMParser { containers.pop(); } } else if (symb.type == ASMParsedSymbol.TYPE_INSTRUCTION_NAME) { - String instructionName = ((String) symb.value).toLowerCase(); + String instructionName = (String) symb.value; Action a = parseAction(instructionName, lexer, emptyList, version); if (a instanceof GraphSourceItemContainer) { containers.push((GraphSourceItemContainer) a); diff --git a/src/com/jpexs/decompiler/flash/action/swf5/ActionDefineFunction.java b/src/com/jpexs/decompiler/flash/action/swf5/ActionDefineFunction.java index 65d708030..a93fd5b42 100644 --- a/src/com/jpexs/decompiler/flash/action/swf5/ActionDefineFunction.java +++ b/src/com/jpexs/decompiler/flash/action/swf5/ActionDefineFunction.java @@ -155,10 +155,9 @@ public class ActionDefineFunction extends Action implements GraphSourceItemConta @Override public String getASMSource(List container, List knownAddreses, List constantPool, int version, ScriptExportMode exportMode) { - String paramStr = ""; + StringBuilder paramStr = new StringBuilder(); for (int i = 0; i < paramNames.size(); i++) { - paramStr += "\"" + Helper.escapeString(paramNames.get(i)) + "\""; - paramStr += " "; + paramStr.append("\"").append(Helper.escapeString(paramNames.get(i))).append("\" "); } return "DefineFunction \"" + Helper.escapeString(functionName) + "\" " + paramNames.size() + " " + paramStr + " {" + (codeSize == 0 ? "\r\n}" : "");// + "\r\n" +Action.actionsToString(getAddress() + getHeaderLength(),getItems(container) , knownAddreses, constantPool, version, hex, getFileAddress() + hdrSize) + "}"; diff --git a/src/com/jpexs/decompiler/flash/action/swf7/ActionDefineFunction2.java b/src/com/jpexs/decompiler/flash/action/swf7/ActionDefineFunction2.java index 898e54f0d..5444ed511 100644 --- a/src/com/jpexs/decompiler/flash/action/swf7/ActionDefineFunction2.java +++ b/src/com/jpexs/decompiler/flash/action/swf7/ActionDefineFunction2.java @@ -253,10 +253,9 @@ public class ActionDefineFunction2 extends Action implements GraphSourceItemCont @Override public String getASMSource(List container, List knownAddreses, List constantPool, int version, ScriptExportMode exportMode) { - String paramStr = ""; + StringBuilder paramStr = new StringBuilder(); for (int i = 0; i < paramNames.size(); i++) { - paramStr += paramRegisters.get(i) + " \"" + Helper.escapeString(paramNames.get(i)) + "\""; - paramStr += " "; + paramStr.append(paramRegisters.get(i)).append(" \"").append(Helper.escapeString(paramNames.get(i))).append("\" "); } return ("DefineFunction2 \"" + Helper.escapeString(functionName) + "\" " + paramRegisters.size() + " " + registerCount diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java index ee20ba6d1..5af9610df 100644 --- a/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/src/com/jpexs/decompiler/flash/gui/Main.java @@ -69,7 +69,9 @@ import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Map.Entry; +import java.util.TreeMap; import java.util.logging.ConsoleHandler; import java.util.logging.FileHandler; import java.util.logging.Formatter; diff --git a/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java b/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java index 979def550..1921eb2e8 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java @@ -172,7 +172,7 @@ public class DefineButtonTag extends ButtonTag implements ASMSource { if (prevLength != 0) { rri.seek(prevLength); } - List list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, -1, toString()/*FIXME?*/); + List list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, prevLength + actionBytes.length, toString()/*FIXME?*/); return list; } catch (InterruptedException ex) { throw ex; diff --git a/src/com/jpexs/decompiler/flash/tags/DoActionTag.java b/src/com/jpexs/decompiler/flash/tags/DoActionTag.java index e818947c8..5f124c036 100644 --- a/src/com/jpexs/decompiler/flash/tags/DoActionTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DoActionTag.java @@ -126,7 +126,7 @@ public class DoActionTag extends Tag implements ASMSource { if (prevLength != 0) { rri.seek(prevLength); } - List list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, -1, toString()/*FIXME?*/); + List list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, prevLength + actionBytes.length, toString()/*FIXME?*/); return list; } catch (InterruptedException ex) { throw ex; diff --git a/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java b/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java index 9c01341c2..52177af43 100644 --- a/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java @@ -120,7 +120,7 @@ public class DoInitActionTag extends CharacterIdTag implements ASMSource { if (prevLength != 0) { rri.seek(prevLength); } - List list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, -1, toString()/*FIXME?*/); + List list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, prevLength + actionBytes.length, toString()/*FIXME?*/); return list; } catch (InterruptedException ex) { throw ex; diff --git a/src/com/jpexs/helpers/Helper.java b/src/com/jpexs/helpers/Helper.java index e5335c088..cd09a543f 100644 --- a/src/com/jpexs/helpers/Helper.java +++ b/src/com/jpexs/helpers/Helper.java @@ -149,33 +149,33 @@ public class Helper { * @return Escaped string */ public static String escapeString(String s) { - String ret = ""; + StringBuilder ret = new StringBuilder(s.length()); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c == '\n') { - ret += "\\n"; + ret.append("\\n"); } else if (c == '\r') { - ret += "\\r"; + ret.append("\\r"); } else if (c == '\t') { - ret += "\\t"; + ret.append("\\t"); } else if (c == '\b') { - ret += "\\b"; + ret.append("\\b"); } else if (c == '\t') { - ret += "\\t"; + ret.append("\\t"); } else if (c == '\f') { - ret += "\\f"; + ret.append("\\f"); } else if (c == '\\') { - ret += "\\\\"; + ret.append("\\\\"); } else if (c == '"') { - ret += "\\\""; + ret.append("\\\""); } else if (c == '\'') { - ret += "\\'"; + ret.append("\\'"); } else { - ret += c; + ret.append(c); } - } - return ret; + + return ret.toString(); } public static String getValidHtmlId(String text) {