From d68d4d22b4e538520bcbac3202a325b669798967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=F8=EDk?= Date: Sat, 27 Jul 2013 18:20:26 +0200 Subject: [PATCH] Issue #266 AS3 deobfuscation fix - switches, try clauses Fixed substance components handling --- .../decompiler/flash/abc/avm2/AVM2Code.java | 12 ++-- .../flash/abc/avm2/graph/AVM2Graph.java | 29 ++++++++- .../com/jpexs/decompiler/flash/gui/Main.java | 6 +- .../jpexs/decompiler/flash/gui/MainFrame.java | 64 ++++++++++--------- .../flash/gui/NewVersionDialog.java | 2 +- .../decompiler/flash/gui/SearchDialog.java | 2 +- .../com/jpexs/decompiler/flash/gui/View.java | 57 +++++++++++++++++ .../flash/gui/abc/ASMSourceEditorPane.java | 5 +- .../decompiler/flash/gui/abc/DetailPanel.java | 2 +- .../gui/abc/DialogMissingSymbolHandler.java | 9 +-- .../flash/gui/abc/MethodBodyParamsPanel.java | 3 +- .../flash/gui/abc/MethodInfoPanel.java | 5 +- .../gui/abc/SlotConstTraitDetailPanel.java | 3 +- .../flash/gui/action/ActionPanel.java | 8 +-- .../flash/gui/proxy/ProxyFrame.java | 4 +- .../src/com/jpexs/decompiler/graph/Graph.java | 26 ++++---- 16 files changed, 164 insertions(+), 73 deletions(-) diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java index 1149f5435..c1f5b40a8 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java @@ -82,7 +82,7 @@ import java.util.logging.Logger; public class AVM2Code implements Serializable { public static final long serialVersionUID = 1L; - private static final boolean DEBUG_MODE = true; + private static final boolean DEBUG_MODE = false; public static int toSourceLimit = -1; public ArrayList code = new ArrayList<>(); public static boolean DEBUG_REWRITE = false; @@ -1652,8 +1652,9 @@ public class AVM2Code implements Serializable { for (ABCException e : body.exceptions) { pos++; try { - visitCode(adr2pos(e.start), -pos, refs); - visitCode(adr2pos(e.target), -pos, refs); + visitCode(adr2pos(e.start), adr2pos(e.start) - 1, refs); + visitCode(adr2pos(e.start), -1, refs); + visitCode(adr2pos(e.target), adr2pos(e.end), refs); visitCode(adr2pos(e.end), -pos, refs); } catch (ConvertException ex) { Logger.getLogger(AVM2Code.class.getName()).log(Level.FINE, null, ex); @@ -2166,7 +2167,7 @@ public class AVM2Code implements Serializable { @SuppressWarnings("unchecked") private static int removeTraps(HashMap> refs, boolean secondPass, boolean useVisited, List localData, Stack stack, List output, AVM2GraphSource code, int ip, HashMap visited, HashMap> visitedStates, HashMap decisions, String path) { - boolean debugMode = true; + boolean debugMode = false; int ret = 0; iploop: while ((ip > -1) && ip < code.size()) { @@ -2224,9 +2225,6 @@ public class AVM2Code implements Serializable { ip++; continue; } - if (ip == 131) { - System.err.println("debug"); - } if (debugMode) { System.out.println((useVisited ? "useV " : "") + (secondPass ? "secondPass " : "") + "Visit " + ip + ": " + ins + " stack:" + Highlighting.stripHilights(stack.toString())); } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java index adf677bc6..404d058ce 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java @@ -30,6 +30,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushIntegerTypeIns import com.jpexs.decompiler.flash.abc.avm2.model.FilteredCheckAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.HasNextAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.InAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.NextNameAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.NextValueAVM2Item; @@ -49,6 +50,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictEqAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictNeqAVM2Item; import com.jpexs.decompiler.flash.abc.types.ABCException; import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.helpers.Helper; import com.jpexs.decompiler.graph.Graph; import com.jpexs.decompiler.graph.GraphPart; import com.jpexs.decompiler.graph.GraphPartMulti; @@ -186,8 +188,6 @@ public class AVM2Graph extends Graph { protected List check(GraphSource code, List localData, List allParts, Stack stack, GraphPart parent, GraphPart part, List stopPart, List loops, List output, Loop currentLoop, int staticOperation, String path) { List ret = null; - - @SuppressWarnings("unchecked") List parsedExceptions = (List) localData.get(DATA_PARSEDEXCEPTIONS); @SuppressWarnings("unchecked") @@ -453,7 +453,30 @@ public class AVM2Graph extends Graph { } else { reversed = true; } - caseValuesMap.put(this.code.code.get(this.code.fixIPAfterDebugLine(part.nextParts.get(reversed ? 0 : 1).start)).operands[0], tar); + GraphPart numPart = part.nextParts.get(reversed ? 0 : 1); + AVM2Instruction ins = null; + Stack sstack = new Stack<>(); + do { + for (int n = 0; n < numPart.getHeight(); n++) { + ins = this.code.code.get(numPart.getPosAt(n)); + if (ins.definition instanceof LookupSwitchIns) { + break; + } + ins.translate(localData, sstack, new ArrayList(), staticOperation, path); + } + if (numPart.nextParts.size() > 1) { + break; + } else { + numPart = numPart.nextParts.get(0); + } + } while (!(this.code.code.get(numPart.end).definition instanceof LookupSwitchIns)); + GraphTargetItem nt = sstack.peek(); + + if (!(nt instanceof IntegerValueAVM2Item)) { + throw new RuntimeException("Invalid integer value in Switch"); + } + IntegerValueAVM2Item iv = (IntegerValueAVM2Item) nt; + caseValuesMap.put((int) (long) iv.value, tar); while (this.code.code.get(part.nextParts.get(reversed ? 1 : 0).start).definition instanceof JumpIns) { reversed = false; part = part.nextParts.get(reversed ? 1 : 0); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/Main.java b/trunk/src/com/jpexs/decompiler/flash/gui/Main.java index 9f7a66a64..adccd5d06 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/Main.java @@ -253,7 +253,7 @@ public class Main { swf = parseSWF(Main.file); } catch (Exception ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); - JOptionPane.showMessageDialog(null, "Cannot load SWF file."); + View.showMessageDialog(null, "Cannot load SWF file."); loadingDialog.setVisible(false); exit(); return false; @@ -339,7 +339,7 @@ public class Main { maskURL = null; return true; } catch (IOException ex) { - JOptionPane.showMessageDialog(null, translate("error.file.write")); + View.showMessageDialog(null, translate("error.file.write")); } } return false; @@ -514,7 +514,7 @@ public class Main { boolean offered = (Boolean) Configuration.getConfig("offeredAssociation", Boolean.FALSE); if (!offered) { if (Platform.isWindows()) { - if ((!isAddedToContextMenu()) && JOptionPane.showConfirmDialog(null, "Do you want to add FFDec to context menu of SWF files?\n(Can be changed later from main menu)", "Context menu", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { + if ((!isAddedToContextMenu()) && View.showConfirmDialog(null, "Do you want to add FFDec to context menu of SWF files?\n(Can be changed later from main menu)", "Context menu", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { addToContextMenu(true); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java index 2237b125f..3f646dcac 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java @@ -286,7 +286,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel public int handle(Throwable thrown) { synchronized (MainFrame.class) { String options[] = new String[]{translate("button.abort"), translate("button.retry"), translate("button.ignore")}; - return JOptionPane.showOptionDialog(null, translate("error.occured").replace("%error%", thrown.getLocalizedMessage()), translate("error"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE, null, options, ""); + return View.showOptionDialog(null, translate("error.occured").replace("%error%", thrown.getLocalizedMessage()), translate("error"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE, null, options, ""); } } }; @@ -1419,7 +1419,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel @Override public void run() { pos++; - if ((pos % 2) == 0 || (pos>=4)) { + if ((pos % 2) == 0 || (pos >= 4)) { errorNotificationButton.setIcon(View.getIcon("error16")); } else { errorNotificationButton.setIcon(null); @@ -1478,7 +1478,13 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel if (n.tag instanceof ClassesListTreeModel) { n.tag = new ClassesListTreeModel(abcPanel.classTree.treeList, filterField.getText()); } - tagTree.updateUI(); + View.execInEventDispatch(new Runnable() { + @Override + public void run() { + tagTree.updateUI(); + } + }); + } } @@ -1817,11 +1823,11 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel public void renameIdentifier(String identifier) { String oldName = identifier; - String newName = JOptionPane.showInputDialog(translate("rename.enternew"), oldName); + String newName = View.showInputDialog(translate("rename.enternew"), oldName); if (newName != null) { if (!oldName.equals(newName)) { swf.renameAS2Identifier(oldName, newName); - JOptionPane.showMessageDialog(null, translate("rename.finished.identifier")); + View.showMessageDialog(null, translate("rename.finished.identifier")); doFilter(); reload(true); } @@ -1833,7 +1839,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel if (abcPanel.abc.constants.constant_multiname[multiNameIndex].name_index > 0) { oldName = abcPanel.abc.constants.constant_string[abcPanel.abc.constants.constant_multiname[multiNameIndex].name_index]; } - String newName = JOptionPane.showInputDialog(translate("rename.enternew"), oldName); + String newName = View.showInputDialog(translate("rename.enternew"), oldName); if (newName != null) { if (!oldName.equals(newName)) { int mulCount = 0; @@ -1851,7 +1857,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel } } } - JOptionPane.showMessageDialog(null, translate("rename.finished.multiname").replace("%count%", "" + mulCount)); + View.showMessageDialog(null, translate("rename.finished.multiname").replace("%count%", "" + mulCount)); if (abcPanel != null) { abcPanel.reload(); } @@ -2046,7 +2052,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel } public boolean confirmExperimental() { - return JOptionPane.showConfirmDialog(null, translate("message.confirm.experimental"), translate("message.warning"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.OK_OPTION; + return View.showConfirmDialog(null, translate("message.confirm.experimental"), translate("message.warning"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.OK_OPTION; } private SearchDialog searchDialog; @@ -2179,7 +2185,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel if (oldchars.indexOf((int) c) == -1) { Font font = new Font(fontSelection.getSelectedItem().toString(), f.getFontStyle(), 1024); if (!font.canDisplay(c)) { - JOptionPane.showMessageDialog(null, translate("error.font.nocharacter").replace("%char%", "" + c), translate("error"), JOptionPane.ERROR_MESSAGE); + View.showMessageDialog(null, translate("error.font.nocharacter").replace("%char%", "" + c), translate("error"), JOptionPane.ERROR_MESSAGE); return; } } @@ -2213,7 +2219,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel newLanguage = ""; } Configuration.setConfig("locale", newLanguage); - JOptionPane.showMessageDialog(null, "Changing language needs application restart.\r\nApplication will exit now, please run it again."); + View.showMessageDialog(null, "Changing language needs application restart.\r\nApplication will exit now, please run it again."); Main.exit(); } break; @@ -2250,7 +2256,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel } else { confStr += " " + translate("message.confirm.off"); } - if (JOptionPane.showConfirmDialog(null, confStr, translate("message.parallel"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) { + if (View.showConfirmDialog(null, confStr, translate("message.parallel"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) { Configuration.setConfig("paralelSpeedUp", (Boolean) miParallelSpeedUp.isSelected()); } else { miParallelSpeedUp.setSelected(!miParallelSpeedUp.isSelected()); @@ -2276,7 +2282,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel showDetail(DETAILCARDAS3NAVIGATOR); showCard(CARDACTIONSCRIPTPANEL); } else { - JOptionPane.showMessageDialog(null, translate("message.search.notfound").replace("%searchtext%", txt), translate("message.search.notfound.title"), JOptionPane.INFORMATION_MESSAGE); + View.showMessageDialog(null, translate("message.search.notfound").replace("%searchtext%", txt), translate("message.search.notfound.title"), JOptionPane.INFORMATION_MESSAGE); } } }).start(); @@ -2287,7 +2293,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel if (actionPanel.search(txt, searchDialog.ignoreCaseCheckBox.isSelected(), searchDialog.regexpCheckBox.isSelected())) { showCard(CARDACTIONSCRIPTPANEL); } else { - JOptionPane.showMessageDialog(null, translate("message.search.notfound").replace("%searchtext%", txt), translate("message.search.notfound.title"), JOptionPane.INFORMATION_MESSAGE); + View.showMessageDialog(null, translate("message.search.notfound").replace("%searchtext%", txt), translate("message.search.notfound.title"), JOptionPane.INFORMATION_MESSAGE); } } }).start(); @@ -2336,7 +2342,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel swf.clearImageCache(); } catch (IOException ex) { Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, "Invalid image", ex); - JOptionPane.showMessageDialog(null, translate("error.image.invalid"), translate("error"), JOptionPane.ERROR_MESSAGE); + View.showMessageDialog(null, translate("error.image.invalid"), translate("error"), JOptionPane.ERROR_MESSAGE); } reload(true); } @@ -2353,7 +2359,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel tagObj = ((TagNode) tagObj).tag; } if (tagObj instanceof Tag) { - if (JOptionPane.showConfirmDialog(this, translate("message.confirm.remove").replace("%item%", tagObj.toString()), translate("message.confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { + if (View.showConfirmDialog(this, translate("message.confirm.remove").replace("%item%", tagObj.toString()), translate("message.confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { swf.removeTag((Tag) tagObj); showCard(CARDEMPTYPANEL); refreshTree(); @@ -2388,7 +2394,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel } Font f = new Font(fontName, font.getFontStyle(), 18); if (!f.canDisplay(character)) { - JOptionPane.showMessageDialog(null, translate("error.font.nocharacter").replace("%char%", "" + character), translate("error"), JOptionPane.ERROR_MESSAGE); + View.showMessageDialog(null, translate("error.font.nocharacter").replace("%char%", "" + character), translate("error"), JOptionPane.ERROR_MESSAGE); return false; } font.addCharacter(tags, character, fontName); @@ -2399,13 +2405,13 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel setEditText(false); } } catch (ParseException ex) { - JOptionPane.showMessageDialog(null, translate("error.text.invalid").replace("%text%", ex.text).replace("%line%", "" + ex.line), translate("error"), JOptionPane.ERROR_MESSAGE); + View.showMessageDialog(null, translate("error.text.invalid").replace("%text%", ex.text).replace("%line%", "" + ex.line), translate("error"), JOptionPane.ERROR_MESSAGE); } } break; case "AUTODEOBFUSCATE": - if (JOptionPane.showConfirmDialog(this, translate("message.confirm.autodeobfuscate") + "\r\n" + (autoDeobfuscateMenuItem.isSelected() ? translate("message.confirm.on") : translate("message.confirm.off")), translate("message.confirm"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) { + if (View.showConfirmDialog(this, translate("message.confirm.autodeobfuscate") + "\r\n" + (autoDeobfuscateMenuItem.isSelected() ? translate("message.confirm.on") : translate("message.confirm.off")), translate("message.confirm"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) { Configuration.setConfig("autoDeobfuscate", autoDeobfuscateMenuItem.isSelected()); clearCache(); if (abcPanel != null) { @@ -2447,7 +2453,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel }).start(); } else { - JOptionPane.showMessageDialog(null, translate("message.rename.notfound.multiname"), translate("message.rename.notfound.title"), JOptionPane.INFORMATION_MESSAGE); + View.showMessageDialog(null, translate("message.rename.notfound.multiname"), translate("message.rename.notfound.title"), JOptionPane.INFORMATION_MESSAGE); } } else { final String identifier = actionPanel.getStringUnderCursor(); @@ -2461,7 +2467,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel } }).start(); } else { - JOptionPane.showMessageDialog(null, translate("message.rename.notfound.identifier"), translate("message.rename.notfound.title"), JOptionPane.INFORMATION_MESSAGE); + View.showMessageDialog(null, translate("message.rename.notfound.identifier"), translate("message.rename.notfound.title"), JOptionPane.INFORMATION_MESSAGE); } } break; @@ -2485,7 +2491,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel Main.saveFile(Main.file); } catch (IOException ex) { Logger.getLogger(com.jpexs.decompiler.flash.gui.abc.ABCPanel.class.getName()).log(Level.SEVERE, null, ex); - JOptionPane.showMessageDialog(null, translate("error.file.save"), translate("error"), JOptionPane.ERROR_MESSAGE); + View.showMessageDialog(null, translate("error.file.save"), translate("error"), JOptionPane.ERROR_MESSAGE); } break; case "SAVEAS": @@ -2556,7 +2562,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel swf.exportXfl(errorHandler, selfile.getAbsolutePath(), new File(Main.file).getName(), Main.applicationName, Main.applicationVerName, Main.version, (Boolean) Configuration.getConfig("paralelSpeedUp", Boolean.TRUE)); } } catch (IOException ex) { - JOptionPane.showMessageDialog(null, translate("error.export") + ": " + ex.getLocalizedMessage(), translate("error"), JOptionPane.ERROR_MESSAGE); + View.showMessageDialog(null, translate("error.export") + ": " + ex.getLocalizedMessage(), translate("error"), JOptionPane.ERROR_MESSAGE); } Main.stopWork(); } @@ -2599,7 +2605,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel } } catch (Exception ex) { Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, "Error during export", ex); - JOptionPane.showMessageDialog(null, translate("error.export") + ": " + ex.getLocalizedMessage()); + View.showMessageDialog(null, translate("error.export") + ": " + ex.getLocalizedMessage()); } Main.stopWork(); long timeAfter = System.currentTimeMillis(); @@ -2626,7 +2632,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel case "CHECKUPDATES": if (!Main.checkForUpdates()) { - JOptionPane.showMessageDialog(null, translate("update.check.nonewversion"), translate("update.check.title"), JOptionPane.INFORMATION_MESSAGE); + View.showMessageDialog(null, translate("update.check.nonewversion"), translate("update.check.title"), JOptionPane.INFORMATION_MESSAGE); } break; @@ -2640,7 +2646,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel } catch (Exception ex) { } } else { - JOptionPane.showMessageDialog(null, translate("message.helpus").replace("%url%", helpUsURL)); + View.showMessageDialog(null, translate("message.helpus").replace("%url%", helpUsURL)); } break; @@ -2654,7 +2660,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel } catch (Exception ex) { } } else { - JOptionPane.showMessageDialog(null, translate("message.homepage").replace("%url%", homePageURL)); + View.showMessageDialog(null, translate("message.homepage").replace("%url%", homePageURL)); } break; @@ -2679,7 +2685,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(bi, abcPanel.abc); } Main.stopWork(); - JOptionPane.showMessageDialog(null, "Control flow restored"); + View.showMessageDialog(null, "Control flow restored"); abcPanel.reload(); doFilter(); return true; @@ -2699,7 +2705,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel int cnt = 0; cnt = swf.deobfuscateIdentifiers(renameType); Main.stopWork(); - JOptionPane.showMessageDialog(null, translate("message.rename.renamed").replace("%count%", "" + cnt)); + View.showMessageDialog(null, translate("message.rename.renamed").replace("%count%", "" + cnt)); swf.assignClassesToSymbols(); clearCache(); if (abcPanel != null) { @@ -2758,7 +2764,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, "Deobfuscation error", ex); } Main.stopWork(); - JOptionPane.showMessageDialog(null, translate("work.deobfuscating.complete")); + View.showMessageDialog(null, translate("work.deobfuscating.complete")); clearCache(); abcPanel.reload(); doFilter(); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/NewVersionDialog.java b/trunk/src/com/jpexs/decompiler/flash/gui/NewVersionDialog.java index 13d205d53..62843067f 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/NewVersionDialog.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/NewVersionDialog.java @@ -126,7 +126,7 @@ public class NewVersionDialog extends AppDialog implements ActionListener { } } if (desktop == null) { - JOptionPane.showMessageDialog(null, translate("newvermessage").replace("%oldAppName%", Main.shortApplicationName).replace("%newAppName%", latestVersion.appName).replace("%projectPage%", Main.projectPage), translate("newversion"), JOptionPane.INFORMATION_MESSAGE); + View.showMessageDialog(null, translate("newvermessage").replace("%oldAppName%", Main.shortApplicationName).replace("%newAppName%", latestVersion.appName).replace("%projectPage%", Main.projectPage), translate("newversion"), JOptionPane.INFORMATION_MESSAGE); } } setVisible(false); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/SearchDialog.java b/trunk/src/com/jpexs/decompiler/flash/gui/SearchDialog.java index 5be8fccaf..f49d46128 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/SearchDialog.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/SearchDialog.java @@ -92,7 +92,7 @@ public class SearchDialog extends AppDialog implements ActionListener { try { Pattern pat = Pattern.compile(searchField.getText()); } catch (PatternSyntaxException ex) { - JOptionPane.showMessageDialog(null, translate("error.invalidregexp"), translate("error"), JOptionPane.ERROR_MESSAGE); + View.showMessageDialog(null, translate("error.invalidregexp"), translate("error"), JOptionPane.ERROR_MESSAGE); return; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/View.java b/trunk/src/com/jpexs/decompiler/flash/gui/View.java index e5e7322b1..3b2304563 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/View.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/View.java @@ -26,10 +26,12 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.AbstractAction; import javax.swing.Action; +import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFrame; +import javax.swing.JOptionPane; import javax.swing.JRootPane; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; @@ -172,4 +174,59 @@ public class View { } } } + + public static int showOptionDialog(final Component parentComponent, final Object message, final String title, final int optionType, final int messageType, final Icon icon, final Object[] options, final Object initialValue) { + final int ret[] = new int[1]; + execInEventDispatch(new Runnable() { + @Override + public void run() { + ret[0] = JOptionPane.showOptionDialog(parentComponent, message, title, optionType, messageType, icon, options, initialValue); + } + }); + return ret[0]; + } + + public static int showConfirmDialog(final Component parentComponent, final Object message, final String title, final int optionType) { + return showConfirmDialog(parentComponent, message, title, optionType, JOptionPane.PLAIN_MESSAGE); + } + + public static int showConfirmDialog(final Component parentComponent, final Object message, final String title, final int optionType, final int messageTyp) { + final int ret[] = new int[1]; + execInEventDispatch(new Runnable() { + @Override + public void run() { + ret[0] = JOptionPane.showConfirmDialog(parentComponent, message, title, optionType, messageTyp); + } + }); + return ret[0]; + } + + public static void showMessageDialog(final Component parentComponent, final Object message, final String title, final int messageType) { + execInEventDispatch(new Runnable() { + @Override + public void run() { + JOptionPane.showMessageDialog(parentComponent, message, title, messageType); + } + }); + } + + public static void showMessageDialog(final Component parentComponent, final Object message) { + execInEventDispatch(new Runnable() { + @Override + public void run() { + JOptionPane.showMessageDialog(parentComponent, message); + } + }); + } + + public static String showInputDialog(final Object message, final Object initialSelection) { + final String ret[] = new String[1]; + execInEventDispatch(new Runnable() { + @Override + public void run() { + ret[0] = JOptionPane.showInputDialog(message, initialSelection); + } + }); + return ret[0]; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java b/trunk/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java index e76ef802f..12792f80e 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java @@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.abc.avm2.graph.AVM2Graph; import com.jpexs.decompiler.flash.abc.avm2.parser.ASM3Parser; import com.jpexs.decompiler.flash.abc.avm2.parser.ParseException; import com.jpexs.decompiler.flash.gui.GraphFrame; +import com.jpexs.decompiler.flash.gui.View; import com.jpexs.decompiler.flash.helpers.Helper; import com.jpexs.decompiler.flash.helpers.Highlighting; import com.jpexs.decompiler.graph.GraphTargetItem; @@ -125,7 +126,7 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi args.put(0, new Object()); //object "this" args.put(1, new Long(466561)); //param1 Object o = abc.bodies[bodyIndex].code.execute(args, abc.constants); - JOptionPane.showMessageDialog(this, "Returned object:" + o.toString()); + View.showMessageDialog(this, "Returned object:" + o.toString()); } public boolean save(ConstantPool constants) { @@ -135,7 +136,7 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi abc.bodies[bodyIndex].code = acode; } catch (IOException ex) { } catch (ParseException ex) { - JOptionPane.showMessageDialog(this, (ex.text + " on line " + ex.line)); + View.showMessageDialog(this, (ex.text + " on line " + ex.line)); selectLine((int) ex.line); return false; } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/abc/DetailPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/abc/DetailPanel.java index 512799672..d48cb41f1 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/abc/DetailPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/abc/DetailPanel.java @@ -159,7 +159,7 @@ public class DetailPanel extends JPanel implements ActionListener { int lasttrait = abcPanel.decompiledTextArea.lastTraitIndex; abcPanel.decompiledTextArea.reloadClass(); abcPanel.decompiledTextArea.gotoTrait(lasttrait); - JOptionPane.showMessageDialog(this, translate("message.trait.saved")); + View.showMessageDialog(this, translate("message.trait.saved")); } } } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/abc/DialogMissingSymbolHandler.java b/trunk/src/com/jpexs/decompiler/flash/gui/abc/DialogMissingSymbolHandler.java index 531c3cd6c..0a7c8130b 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/abc/DialogMissingSymbolHandler.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/abc/DialogMissingSymbolHandler.java @@ -18,27 +18,28 @@ package com.jpexs.decompiler.flash.gui.abc; import com.jpexs.decompiler.flash.abc.avm2.parser.MissingSymbolHandler; import static com.jpexs.decompiler.flash.gui.AppStrings.translate; +import com.jpexs.decompiler.flash.gui.View; import javax.swing.JOptionPane; public class DialogMissingSymbolHandler implements MissingSymbolHandler { @Override public boolean missingString(String value) { - return JOptionPane.showConfirmDialog(null, translate("message.constant.new.string").replace("%value%", value), translate("message.constant.new.string.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION; + return View.showConfirmDialog(null, translate("message.constant.new.string").replace("%value%", value), translate("message.constant.new.string.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION; } @Override public boolean missingInt(long value) { - return JOptionPane.showConfirmDialog(null, translate("message.constant.new.integer").replace("%value%", "" + value), translate("message.constant.new.integer.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION; + return View.showConfirmDialog(null, translate("message.constant.new.integer").replace("%value%", "" + value), translate("message.constant.new.integer.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION; } @Override public boolean missingUInt(long value) { - return JOptionPane.showConfirmDialog(null, translate("message.constant.new.unsignedinteger").replace("%value%", "" + value), translate("message.constant.new.unsignedinteger.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION; + return View.showConfirmDialog(null, translate("message.constant.new.unsignedinteger").replace("%value%", "" + value), translate("message.constant.new.unsignedinteger.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION; } @Override public boolean missingDouble(double value) { - return JOptionPane.showConfirmDialog(null, translate("message.constant.new.double").replace("%value%", "" + value), translate("message.constant.new.double.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION; + return View.showConfirmDialog(null, translate("message.constant.new.double").replace("%value%", "" + value), translate("message.constant.new.double.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/abc/MethodBodyParamsPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/abc/MethodBodyParamsPanel.java index 181722129..7ffc95762 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/abc/MethodBodyParamsPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/abc/MethodBodyParamsPanel.java @@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.gui.abc; import com.jpexs.decompiler.flash.abc.types.MethodBody; import static com.jpexs.decompiler.flash.gui.AppStrings.translate; import com.jpexs.decompiler.flash.gui.MyFormattedTextField; +import com.jpexs.decompiler.flash.gui.View; import java.awt.Color; import java.awt.Dimension; import java.text.NumberFormat; @@ -113,7 +114,7 @@ public class MethodBodyParamsPanel extends JPanel implements ChangeListener { body.max_scope_depth = Integer.parseInt(maxScopeDepthField.getText()); } else { if (!body.autoFillStats(abcPanel.abc)) { - JOptionPane.showMessageDialog(null, translate("message.autofill.failed"), translate("message.warning"), JOptionPane.WARNING_MESSAGE); + View.showMessageDialog(null, translate("message.autofill.failed"), translate("message.warning"), JOptionPane.WARNING_MESSAGE); } } return true; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/abc/MethodInfoPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/abc/MethodInfoPanel.java index 48ecd701a..a762e1fc8 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/abc/MethodInfoPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/abc/MethodInfoPanel.java @@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.abc.methodinfo_parser.MethodInfoParser; import com.jpexs.decompiler.flash.abc.methodinfo_parser.ParseException; import com.jpexs.decompiler.flash.abc.types.MethodInfo; import static com.jpexs.decompiler.flash.gui.AppStrings.translate; +import com.jpexs.decompiler.flash.gui.View; import com.jpexs.decompiler.flash.helpers.Helper; import java.awt.Dimension; import java.awt.Font; @@ -120,13 +121,13 @@ public class MethodInfoPanel extends JPanel { try { MethodInfoParser.parseParams(paramEditor.getText(), methodInfo, abc); } catch (ParseException ex) { - JOptionPane.showMessageDialog(paramEditor, ex.text, translate("error.methodinfo.params"), JOptionPane.ERROR_MESSAGE); + View.showMessageDialog(paramEditor, ex.text, translate("error.methodinfo.params"), JOptionPane.ERROR_MESSAGE); return false; } try { MethodInfoParser.parseReturnType(returnTypeEditor.getText(), methodInfo); } catch (ParseException ex) { - JOptionPane.showMessageDialog(returnTypeEditor, ex.text, translate("error.methodinfo.returnvalue"), JOptionPane.ERROR_MESSAGE); + View.showMessageDialog(returnTypeEditor, ex.text, translate("error.methodinfo.returnvalue"), JOptionPane.ERROR_MESSAGE); return false; } return true; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/abc/SlotConstTraitDetailPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/abc/SlotConstTraitDetailPanel.java index 59b2c680b..3016719a5 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/abc/SlotConstTraitDetailPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/abc/SlotConstTraitDetailPanel.java @@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.abc.methodinfo_parser.ParseException; import com.jpexs.decompiler.flash.abc.types.ValueKind; import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; import static com.jpexs.decompiler.flash.gui.AppStrings.translate; +import com.jpexs.decompiler.flash.gui.View; import com.jpexs.decompiler.flash.helpers.Helper; import java.awt.BorderLayout; import java.awt.Color; @@ -94,7 +95,7 @@ public class SlotConstTraitDetailPanel extends JPanel implements TraitDetail { return false; } } catch (ParseException ex) { - JOptionPane.showMessageDialog(slotConstEditor, ex.text, translate("error.slotconst.typevalue"), JOptionPane.ERROR_MESSAGE); + View.showMessageDialog(slotConstEditor, ex.text, translate("error.slotconst.typevalue"), JOptionPane.ERROR_MESSAGE); return false; } return true; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java index a7027b643..a313c381e 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java @@ -640,7 +640,7 @@ public class ActionPanel extends JPanel implements ActionListener { try { src.setActions(ASMParser.parse(0, src.getPos(), true, new StringReader(editor.getText()), SWF.DEFAULT_VERSION), SWF.DEFAULT_VERSION); setSource(this.src, false); - JOptionPane.showMessageDialog(this, translate("message.action.saved")); + View.showMessageDialog(this, translate("message.action.saved")); saveButton.setVisible(false); cancelButton.setVisible(false); editButton.setVisible(true); @@ -648,7 +648,7 @@ public class ActionPanel extends JPanel implements ActionListener { editMode = false; } catch (IOException ex) { } catch (ParseException ex) { - JOptionPane.showMessageDialog(this, translate("error.action.save").replace("%error%", ex.text).replace("%line%", "" + ex.line), translate("error"), JOptionPane.ERROR_MESSAGE); + View.showMessageDialog(this, translate("error.action.save").replace("%error%", ex.text).replace("%line%", "" + ex.line), translate("error"), JOptionPane.ERROR_MESSAGE); } } else if (e.getActionCommand().equals("EDITDECOMPILED")) { setDecompiledEditMode(true); @@ -659,12 +659,12 @@ public class ActionPanel extends JPanel implements ActionListener { ActionScriptParser par = new ActionScriptParser(); src.setActions(par.actionsFromString(decompiledEditor.getText()), SWF.DEFAULT_VERSION); setSource(this.src, false); - JOptionPane.showMessageDialog(this, translate("message.action.saved")); + View.showMessageDialog(this, translate("message.action.saved")); setDecompiledEditMode(false); } catch (IOException ex) { Logger.getLogger(ActionPanel.class.getName()).log(Level.SEVERE, "IOException during action compiling", ex); } catch (ParseException ex) { - JOptionPane.showMessageDialog(this, translate("error.action.save").replace("%error%", ex.text).replace("%line%", "" + ex.line), translate("error"), JOptionPane.ERROR_MESSAGE); + View.showMessageDialog(this, translate("error.action.save").replace("%error%", ex.text).replace("%line%", "" + ex.line), translate("error"), JOptionPane.ERROR_MESSAGE); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/proxy/ProxyFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/proxy/ProxyFrame.java index c2276f18e..559500003 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/proxy/ProxyFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/proxy/ProxyFrame.java @@ -189,7 +189,7 @@ public class ProxyFrame extends AppFrame implements ActionListener, CatchedListe if (e.getActionCommand().equals("RENAME")) { if (swfList.getSelectedIndex() > -1) { Replacement r = (Replacement) listModel.getElementAt(swfList.getSelectedIndex()); - String s = JOptionPane.showInputDialog("URL", r.urlPattern); + String s = View.showInputDialog("URL", r.urlPattern); r.urlPattern = s; listModel.dataChanged(swfList.getSelectedIndex()); } @@ -246,7 +246,7 @@ public class ProxyFrame extends AppFrame implements ActionListener, CatchedListe } catch (NumberFormatException nfe) { } if ((port <= 0) || (port > 65535)) { - JOptionPane.showMessageDialog(this, translate("error.port"), translate("error"), JOptionPane.ERROR_MESSAGE); + View.showMessageDialog(this, translate("error.port"), translate("error"), JOptionPane.ERROR_MESSAGE); started = false; return; } diff --git a/trunk/src/com/jpexs/decompiler/graph/Graph.java b/trunk/src/com/jpexs/decompiler/graph/Graph.java index 8520d61f5..a8e39c855 100644 --- a/trunk/src/com/jpexs/decompiler/graph/Graph.java +++ b/trunk/src/com/jpexs/decompiler/graph/Graph.java @@ -1474,6 +1474,19 @@ public class Graph { } }*/ + if (parseNext) { + List retCheck = check(code, localData, allParts, stack, parent, part, stopPart, loops, output, currentLoop, staticOperation, path); + if (retCheck != null) { + if (!retCheck.isEmpty()) { + currentRet.addAll(retCheck); + } + parseNext = false; + //return ret; + } else { + currentRet.addAll(output); + } + } + /** * AND / OR detection */ @@ -1587,18 +1600,7 @@ public class Graph { } //********************************END PART DECOMPILING - if (parseNext) { - List retCheck = check(code, localData, allParts, stack, parent, part, stopPart, loops, output, currentLoop, staticOperation, path); - if (retCheck != null) { - if (!retCheck.isEmpty()) { - currentRet.addAll(retCheck); - } - parseNext = false; - //return ret; - } else { - currentRet.addAll(output); - } - } + if (parseNext) {