diff --git a/src/com/jpexs/decompiler/flash/SWF.java b/src/com/jpexs/decompiler/flash/SWF.java index 805c23303..f9a50e94f 100644 --- a/src/com/jpexs/decompiler/flash/SWF.java +++ b/src/com/jpexs/decompiler/flash/SWF.java @@ -540,9 +540,7 @@ public final class SWF implements TreeItem, Timelined { SWFInputStream sis = new SWFInputStream(this, uncompressedData); dumpInfo = new DumpInfoSwfNode(this, "rootswf", "", null, 0, 0); - if (Configuration.dumpInfoCollecting.get()) { - sis.dumpInfo = dumpInfo; - } + sis.dumpInfo = dumpInfo; sis.readBytesEx(3, "signature"); // skip siganture version = sis.readUI8("version"); fileSize = sis.readUI32("fileSize"); @@ -556,7 +554,7 @@ public final class SWF implements TreeItem, Timelined { sis.readUI8("tmpFirstByetOfFrameRate"); //tmpFirstByetOfFrameRate frameRate = sis.readUI8("frameRate"); frameCount = sis.readUI16("frameCount"); - List tags = sis.readTagList(this, 0, parallelRead, true, !checkOnly, gfx); + List tags = sis.readTagList(this, 0, parallelRead, true, !checkOnly); if (tags.get(tags.size() - 1).getId() == EndTag.ID) { hasEndTag = true; tags.remove(tags.size() - 1); diff --git a/src/com/jpexs/decompiler/flash/SWFInputStream.java b/src/com/jpexs/decompiler/flash/SWFInputStream.java index 5a1826177..2fa125693 100644 --- a/src/com/jpexs/decompiler/flash/SWFInputStream.java +++ b/src/com/jpexs/decompiler/flash/SWFInputStream.java @@ -964,22 +964,20 @@ public class SWFInputStream implements AutoCloseable { private final int level; private final boolean parallel; private final boolean skipUnusualTags; - private final boolean gfx; - public TagResolutionTask(TagStub tag, DumpInfo dumpInfo, int level, boolean parallel, boolean skipUnusualTags, boolean gfx) { + public TagResolutionTask(TagStub tag, DumpInfo dumpInfo, int level, boolean parallel, boolean skipUnusualTags) { this.tag = tag; this.dumpInfo = dumpInfo; this.level = level; this.parallel = parallel; this.skipUnusualTags = skipUnusualTags; - this.gfx = gfx; } @Override public Tag call() throws Exception { DumpInfo di = dumpInfo; try { - Tag t = resolveTag(tag, level, parallel, skipUnusualTags, gfx); + Tag t = resolveTag(tag, level, parallel, skipUnusualTags); if (dumpInfo != null && t != null) { dumpInfo.name = t.getName(); } @@ -1001,12 +999,11 @@ public class SWFInputStream implements AutoCloseable { * @param parallel * @param skipUnusualTags * @param parseTags - * @param gfx * @return List of tags * @throws IOException * @throws java.lang.InterruptedException */ - public List readTagList(Timelined timelined, int level, boolean parallel, boolean skipUnusualTags, boolean parseTags, boolean gfx) throws IOException, InterruptedException { + public List readTagList(Timelined timelined, int level, boolean parallel, boolean skipUnusualTags, boolean parseTags) throws IOException, InterruptedException { ExecutorService executor = null; List> futureResults = new ArrayList<>(); if (parallel) { @@ -1020,7 +1017,7 @@ public class SWFInputStream implements AutoCloseable { long pos = getPos(); newDumpLevel(null, "TAG"); try { - tag = readTag(timelined, level, pos, parseTags && !parallel, parallel, skipUnusualTags, gfx); + tag = readTag(timelined, level, pos, parseTags && !parallel, parallel, skipUnusualTags); } catch (EOFException | EndOfStreamException ex) { tag = null; } @@ -1048,7 +1045,7 @@ public class SWFInputStream implements AutoCloseable { switch (tag.getId()) { case FileAttributesTag.ID: //FileAttributes if (tag instanceof TagStub) { - tag = resolveTag((TagStub) tag, level, parallel, skipUnusualTags, gfx); + tag = resolveTag((TagStub) tag, level, parallel, skipUnusualTags); } FileAttributesTag fileAttributes = (FileAttributesTag) tag; if (fileAttributes.actionScript3) { @@ -1091,7 +1088,7 @@ public class SWFInputStream implements AutoCloseable { } if (parseTags && doParse && tag instanceof TagStub) { if (parallel) { - Future future = executor.submit(new TagResolutionTask((TagStub) tag, di, level, parallel, skipUnusualTags, gfx)); + Future future = executor.submit(new TagResolutionTask((TagStub) tag, di, level, parallel, skipUnusualTags)); futureResults.add(future); } } @@ -1117,7 +1114,7 @@ public class SWFInputStream implements AutoCloseable { return tags; } - public static Tag resolveTag(TagStub tag, int level, boolean parallel, boolean skipUnusualTags, boolean gfx) throws InterruptedException { + public static Tag resolveTag(TagStub tag, int level, boolean parallel, boolean skipUnusualTags) throws InterruptedException { Tag ret; ByteArrayRange data = tag.getOriginalRange(); @@ -1355,7 +1352,7 @@ public class SWFInputStream implements AutoCloseable { ret = new PlaceObject4Tag(sis, data); break; default: - if (gfx) { //GFX tags only in GFX files. There may be incorrect GFX tags in non GFX files + if (swf.gfx) { //GFX tags only in GFX files. There may be incorrect GFX tags in non GFX files switch (tag.getId()) { case 1000: ret = new ExporterInfoTag(sis, data); @@ -1413,12 +1410,11 @@ public class SWFInputStream implements AutoCloseable { * @param resolve * @param parallel * @param skipUnusualTags - * @param gfx * @return Tag or null when End tag * @throws IOException * @throws java.lang.InterruptedException */ - public Tag readTag(Timelined timelined, int level, long pos, boolean resolve, boolean parallel, boolean skipUnusualTags, boolean gfx) throws IOException, InterruptedException { + public Tag readTag(Timelined timelined, int level, long pos, boolean resolve, boolean parallel, boolean skipUnusualTags) throws IOException, InterruptedException { int tagIDTagLength = readUI16("tagIDTagLength"); int tagID = (tagIDTagLength) >> 6; @@ -1438,15 +1434,20 @@ public class SWFInputStream implements AutoCloseable { } ByteArrayRange dataRange = new ByteArrayRange(swf.uncompressedData, (int) pos, (int) (tagLength + headerLength)); + skipBytes((int) tagLength); + TagStub tagStub = new TagStub(swf, tagID, "Unresolved", dataRange, tagDataStream); tagStub.forceWriteAsLong = readLong; Tag ret = tagStub; - skipBytes((int) tagLength); + if (tagDataStream.dumpInfo == null && dumpInfo != null) { + dumpInfo.tagToResolve = tagStub; + } + if (resolve) { DumpInfo di = dumpInfo; try { - ret = resolveTag(tagStub, level, parallel, skipUnusualTags, gfx); + ret = resolveTag(tagStub, level, parallel, skipUnusualTags); } catch (EndOfStreamException ex) { tagDataStream.endDumpLevelUntil(di); logger.log(Level.SEVERE, "Problem in " + timelined.toString(), ex); @@ -3287,7 +3288,9 @@ public class SWFInputStream implements AutoCloseable { public SWFInputStream getLimitedStream(int limit) throws IOException { SWFInputStream sis = new SWFInputStream(swf, is.getAllRead(), startingPos, (int) (is.getPos() + limit)); - sis.dumpInfo = dumpInfo; + if (Configuration.lazyDumpInfoCollecting.get()) { + sis.dumpInfo = dumpInfo; + } sis.seek(is.getPos() + startingPos); return sis; } diff --git a/src/com/jpexs/decompiler/flash/action/Action.java b/src/com/jpexs/decompiler/flash/action/Action.java index ea49d292b..614c7bacd 100644 --- a/src/com/jpexs/decompiler/flash/action/Action.java +++ b/src/com/jpexs/decompiler/flash/action/Action.java @@ -97,7 +97,6 @@ import java.util.logging.Logger; */ public class Action implements GraphSourceItem { - public Action replaceWith; private boolean ignored = false; /** * Action type identifier @@ -184,29 +183,9 @@ public class Action implements GraphSourceItem { /** * Gets all addresses which are referenced from this action and/or * subactions - * - * @param version SWF version - * @return List of addresses + * @param refs list of addresses */ - public List getAllRefs(int version) { - List ret = new ArrayList<>(); - return ret; - } - - /** - * Gets all ActionIf or ActionJump actions from list of actions - * - * @param list List of actions - * @return List of actions - */ - public static List getActionsAllIfsOrJumps(List list) { - List ret = new ArrayList<>(); - for (Action a : list) { - if (a instanceof ActionIf || a instanceof ActionJump) { - ret.add(a); - } - } - return ret; + public void getRef(List refs) { } /** @@ -219,16 +198,15 @@ public class Action implements GraphSourceItem { public static List getActionsAllRefs(List list, int version) { List ret = new ArrayList<>(); for (Action a : list) { - if (a.replaceWith != null) { - a.replaceWith.setAddress(a.getAddress(), version, false); - ret.addAll(a.replaceWith.getAllRefs(version)); - } - List part = a.getAllRefs(version); - ret.addAll(part); + a.getRef(ret); } return ret; } + public int getTotalActionLength() { + return actionLength + 1 + ((actionCode >= 0x80) ? 2 : 0); + } + /** * Sets address of this instruction * @@ -408,15 +386,14 @@ public class Action implements GraphSourceItem { * @param listeners * @param address * @param list List of actions - * @param importantOffsets List of important offsets to mark as labels * @param version SWF version * @param exportMode PCode or hex? * @param writer * @param path * @return HilightedTextWriter */ - public static GraphTextWriter actionsToString(List listeners, long address, List list, List importantOffsets, int version, ScriptExportMode exportMode, GraphTextWriter writer, String path) { - return actionsToString(listeners, address, list, importantOffsets, new ArrayList(), version, exportMode, writer, path); + public static GraphTextWriter actionsToString(List listeners, long address, List list, int version, ScriptExportMode exportMode, GraphTextWriter writer, String path) { + return actionsToString(listeners, address, list, new ArrayList(), version, exportMode, writer, path); } /** @@ -432,12 +409,9 @@ public class Action implements GraphSourceItem { * @param path * @return HilightedTextWriter */ - private static GraphTextWriter actionsToString(List listeners, long address, List list, List importantOffsets, List constantPool, int version, ScriptExportMode exportMode, GraphTextWriter writer, String path) { + private static GraphTextWriter actionsToString(List listeners, long address, List list, List constantPool, int version, ScriptExportMode exportMode, GraphTextWriter writer, String path) { long offset; - if (importantOffsets == null) { - //setActionsAddresses(list, 0, version); - importantOffsets = getActionsAllRefs(list, version); - } + List importantOffsets = getActionsAllRefs(list, version); /*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)); @@ -505,15 +479,7 @@ public class Action implements GraphSourceItem { writer.appendNoHilight(":"); } - if (a.replaceWith != null) { - if (lastPush) { - writer.newLine(); - lastPush = false; - } - writer.append("", offset); - writer.appendNoHilight(a.replaceWith.getASMSource(list, importantOffsets, constantPool, version, exportMode)); - writer.newLine(); - } else if (a.isIgnored()) { + if (a.isIgnored()) { if (lastPush) { writer.newLine(); lastPush = false; @@ -1224,7 +1190,7 @@ public class Action implements GraphSourceItem { String s = null; try { HilightedTextWriter writer = new HilightedTextWriter(Configuration.getCodeFormatting(), false); - Action.actionsToString(new ArrayList(), address, ret, null, version, ScriptExportMode.PCODE, writer, path); + Action.actionsToString(new ArrayList(), address, ret, version, ScriptExportMode.PCODE, writer, path); s = writer.toString(); ret = ASMParser.parse(address, true, s, SWF.DEFAULT_VERSION, false); } catch (IOException | ParseException ex) { diff --git a/src/com/jpexs/decompiler/flash/action/ActionListReader.java b/src/com/jpexs/decompiler/flash/action/ActionListReader.java index cdf6e5d74..56b2bef64 100644 --- a/src/com/jpexs/decompiler/flash/action/ActionListReader.java +++ b/src/com/jpexs/decompiler/flash/action/ActionListReader.java @@ -141,7 +141,7 @@ public class ActionListReader { int index = getNextNotNullIndex(actionMap, 0); if (index != -1 && entryAction != actionMap.get(index)) { ActionJump jump = new ActionJump(0); - int size = getTotalActionLength(jump); + int size = jump.getTotalActionLength(); jump.setJumpOffset((int) (entryAction.getAddress() - size)); actions.add(jump); } @@ -157,7 +157,7 @@ public class ActionListReader { if (!action.isExit() && !(action instanceof ActionJump)) { ActionJump jump = new ActionJump(0); jump.setAddress(action.getAddress(), version); - int size = getTotalActionLength(jump); + int size = jump.getTotalActionLength(); jump.setJumpOffset((int) (nextOffset - action.getAddress() - size)); actions.add(jump); } @@ -179,7 +179,7 @@ public class ActionListReader { aEnd.setAddress(endAddress, version); actions.add(aEnd); } else { - endAddress -= getTotalActionLength(aEnd); + endAddress -= aEnd.getTotalActionLength(); } updateJumps(actions, jumps, containerLastActions, endAddress, version); @@ -270,17 +270,6 @@ public class ActionListReader { } last = a; } - for (int i = 0; i < retdups.size(); i++) { - Action a = retdups.get(i); - if (a instanceof ActionEnd) { - if (i < retdups.size() - 1) { - ActionJump jmp = new ActionJump(0); - jmp.setJumpOffset(retdups.size() - i - jmp.getBytes(version).length); - a.replaceWith = jmp; - } - } - } - ret = Action.removeNops(0, ret, version, path); List reta = new ArrayList<>(); for (Object o : ret) { @@ -329,17 +318,17 @@ public class ActionListReader { long target = -1; if (a instanceof ActionIf) { ActionIf aIf = (ActionIf) a; - target = aIf.getAddress() + getTotalActionLength(a) + aIf.getJumpOffset(); + target = aIf.getAddress() + a.getTotalActionLength() + aIf.getJumpOffset(); } else if (a instanceof ActionJump) { ActionJump aJump = (ActionJump) a; - target = aJump.getAddress() + getTotalActionLength(a) + aJump.getJumpOffset(); + target = aJump.getAddress() + a.getTotalActionLength() + aJump.getJumpOffset(); } else if (a instanceof ActionStore) { ActionStore aStore = (ActionStore) a; int storeSize = aStore.getStoreSize(); // skip storeSize + 1 actions (+1 is the current action) Action targetAction = a; for (int i = 0; i <= storeSize; i++) { - long address = targetAction.getAddress() + getTotalActionLength(targetAction); + long address = targetAction.getAddress() + targetAction.getTotalActionLength(); targetAction = actionMap.get(address); if (targetAction == null) { break; @@ -387,7 +376,7 @@ public class ActionListReader { int length = a.getBytes(version).length; if ((i != actions.size() - 1) && (a instanceof ActionEnd)) { // placeholder for jump action - length = getTotalActionLength(new ActionJump(0)); + length = new ActionJump(0).getTotalActionLength(); } address += length; } @@ -412,7 +401,7 @@ public class ActionListReader { Action a1 = a; List store = new ArrayList<>(); while (true) { - long address = a1.getAddress() + getTotalActionLength(a1); + long address = a1.getAddress() + a1.getTotalActionLength(); a1 = actionMap.get(address); if (a1 == null || a1 == nextActionAfterStore) { break; @@ -433,7 +422,7 @@ public class ActionListReader { long startAddress = a.getAddress() + container.getHeaderSize(); for (int j = 0; j < lastActions.size(); j++) { Action lastAction = lastActions.get(j); - int length = (int) (lastAction.getAddress() + getTotalActionLength(lastAction) - startAddress); + int length = (int) (lastAction.getAddress() + lastAction.getTotalActionLength() - startAddress); container.setContainerSize(j, length); startAddress += length; } @@ -469,7 +458,7 @@ public class ActionListReader { Action a = actions.get(i); if ((i != actions.size() - 1) && (a instanceof ActionEnd)) { ActionJump aJump = new ActionJump(0); - aJump.setJumpOffset((int) (endAddress - a.getAddress() - getTotalActionLength(aJump))); + aJump.setJumpOffset((int) (endAddress - a.getAddress() - aJump.getTotalActionLength())); aJump.setAddress(a.getAddress(), version); replaceJumpTargets(jumps, a, aJump); replaceContainerLastActions(containerLastActions, a, aJump); @@ -480,9 +469,9 @@ public class ActionListReader { Action target = jumps.get(a); long offset; if (target != null) { - offset = target.getAddress() - a.getAddress() - getTotalActionLength(a); + offset = target.getAddress() - a.getAddress() - a.getTotalActionLength(); } else { - offset = endAddress - a.getAddress() - getTotalActionLength(a); + offset = endAddress - a.getAddress() - a.getTotalActionLength(); } aIf.setJumpOffset((int) offset); } else if (a instanceof ActionJump) { @@ -490,9 +479,9 @@ public class ActionListReader { Action target = jumps.get(a); long offset; if (target != null) { - offset = target.getAddress() - a.getAddress() - getTotalActionLength(a); + offset = target.getAddress() - a.getAddress() - a.getTotalActionLength(); } else { - offset = endAddress - a.getAddress() - getTotalActionLength(a); + offset = endAddress - a.getAddress() - a.getTotalActionLength(); } aJump.setJumpOffset((int) offset); } @@ -531,7 +520,7 @@ 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() + getTotalActionLength(lastAction); + long endAddress = lastAction.getAddress() + lastAction.getTotalActionLength(); List actionMap = new ArrayList<>(lastIdx); for (int i = 0; i <= lastIdx; i++) { @@ -608,16 +597,16 @@ public class ActionListReader { break; } - int actionLengthWithHeader = getTotalActionLength(a); + int actionLengthWithHeader = a.getTotalActionLength(); // unknown action, replace with jump if (a instanceof ActionNop) { ActionJump aJump = new ActionJump(0); - int jumpLength = getTotalActionLength(aJump); + int jumpLength = aJump.getTotalActionLength(); aJump.setAddress(a.getAddress(), version); aJump.setJumpOffset(actionLengthWithHeader - jumpLength); a = aJump; - actionLengthWithHeader = getTotalActionLength(a); + actionLengthWithHeader = a.getTotalActionLength(); } if (entryAction == null) { @@ -688,10 +677,6 @@ public class ActionListReader { return entryAction; } - private static int getTotalActionLength(Action action) { - return action.actionLength + 1 + ((action.actionCode >= 0x80) ? 2 : 0); - } - private static void ensureCapacity(List actions, List nextOffsets, long index) { while (actions.size() <= index) { actions.add(null); @@ -715,7 +700,7 @@ public class ActionListReader { throw new InterruptedException(); } - int actionLen = getTotalActionLength(a); + int actionLen = a.getTotalActionLength(); if (!visited.containsKey(ip)) { visited.put(ip, 0); } @@ -725,7 +710,7 @@ public class ActionListReader { for (int i = 0; i < listeners.size(); i++) { listeners.get(i).progress(AppStrings.translate("disassemblingProgress.deobfuscating"), ip, actions.size()); } - int info = a.actionLength + 1 + ((a.actionCode >= 0x80) ? 2 : 0); + int info = a.getTotalActionLength(); if (a instanceof ActionPush) { if (cpool != null) { 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 4fabeb816..c3cf29e34 100644 --- a/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java +++ b/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java @@ -457,9 +457,12 @@ public class ASMParser { lexer = new FlasmLexer(new StringReader(source)); List