diff --git a/CHANGELOG.md b/CHANGELOG.md index 736188170..94bfedbf7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. - Deobfuscation and its options as icons on script panel toolbar - Warning before switching auto rename identifiers on - [#1231] Button transforming +- [#1690] Deobfuscation tool dialog for script level (not just current method / all classes) ### Fixed - [#1904] NullPointerException when renaming invalid identifiers in AS1/2 files caused by missing charset @@ -23,6 +24,10 @@ All notable changes to this project will be documented in this file. ### Changed - Warning before switching deobfuscation is now optional +- [#1690] Redesigned Deobfuscation tool dialog. + +### Removed +- "Restore control flow" deobfuscation level as it was the same as "Remove traps" ## [18.0.0] - 2022-12-18 ### Added @@ -2762,6 +2767,7 @@ All notable changes to this project will be documented in this file. [#1231]: https://www.free-decompiler.com/flash/issues/1231 [#1904]: https://www.free-decompiler.com/flash/issues/1904 [#595]: https://www.free-decompiler.com/flash/issues/595 +[#1690]: https://www.free-decompiler.com/flash/issues/1690 [#1898]: https://www.free-decompiler.com/flash/issues/1898 [#1511]: https://www.free-decompiler.com/flash/issues/1511 [#1765]: https://www.free-decompiler.com/flash/issues/1765 diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java index 09e2ada77..59afba593 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -3761,8 +3761,6 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { tag.getABC().removeDeadCode(deoListener); } else if (level == DeobfuscationLevel.LEVEL_REMOVE_TRAPS) { tag.getABC().removeTraps(deoListener); - } else if (level == DeobfuscationLevel.LEVEL_RESTORE_CONTROL_FLOW) { - tag.getABC().removeTraps(deoListener); } ((Tag) tag).setModified(true); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/DeobfuscationLevel.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/DeobfuscationLevel.java index 54f7e0e57..ebc3f8e35 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/DeobfuscationLevel.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/DeobfuscationLevel.java @@ -23,9 +23,7 @@ package com.jpexs.decompiler.flash.abc.avm2.deobfuscation; public enum DeobfuscationLevel { LEVEL_REMOVE_DEAD_CODE(1), - LEVEL_REMOVE_TRAPS(2), - LEVEL_RESTORE_CONTROL_FLOW(3); - + LEVEL_REMOVE_TRAPS(2); private final int level; public int getLevel() { @@ -37,9 +35,7 @@ public enum DeobfuscationLevel { case 1: return LEVEL_REMOVE_DEAD_CODE; case 2: - return LEVEL_REMOVE_TRAPS; - case 3: - return LEVEL_RESTORE_CONTROL_FLOW; + return LEVEL_REMOVE_TRAPS; } return null; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/DeobfuscationScope.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/DeobfuscationScope.java new file mode 100644 index 000000000..0b335b773 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/DeobfuscationScope.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2010-2022 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.deobfuscation; + +/** + * + * @author JPEXS + */ +public enum DeobfuscationScope { + METHOD, + CLASS, + SWF +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java index e3615ad22..1caf3fbf2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java @@ -192,8 +192,6 @@ public final class MethodBody implements Cloneable { removeDeadCode(abc.constants, trait, abc.method_info.get(method_info)); } else if (level == DeobfuscationLevel.LEVEL_REMOVE_TRAPS) { removeTraps(abc, trait, scriptIndex, classIndex, isStatic, path); - } else if (level == DeobfuscationLevel.LEVEL_RESTORE_CONTROL_FLOW) { - removeTraps(abc, trait, scriptIndex, classIndex, isStatic, path); } ((Tag) abc.parentTag).setModified(true); diff --git a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java index 2b5d6681f..4a4ef6b0c 100644 --- a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java +++ b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java @@ -576,7 +576,7 @@ public class CommandLineArgumentParser { if (filter == null || filter.equals("deobfuscate")) { out.println(" " + (cnt++) + ") -deobfuscate "); out.println(" ...Deobfuscates AS3 P-code in and saves result to "); - out.println(" ... can be one of: controlflow/3/max, traps/2, deadcode/1"); + out.println(" ... can be one of: traps/2/max, deadcode/1"); out.println(" ...WARNING: The deobfuscation result is still probably far enough to be openable by other decompilers."); } @@ -2504,11 +2504,12 @@ public class CommandLineArgumentParser { DeobfuscationLevel lev; switch (mode) { case "controlflow": - case "max": case "3": - lev = DeobfuscationLevel.LEVEL_RESTORE_CONTROL_FLOW; + System.err.println("WARNING: Control flow level(3) is not implemented - it is the same as remove traps (2) level."); + lev = DeobfuscationLevel.LEVEL_REMOVE_TRAPS; break; case "traps": + case "max": case "2": lev = DeobfuscationLevel.LEVEL_REMOVE_TRAPS; break; diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index 51d63e1c2..b0156779d 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -30,7 +30,14 @@ import com.jpexs.decompiler.flash.abc.ScriptPack; import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; import com.jpexs.decompiler.flash.abc.avm2.deobfuscation.AbcMultiNameCollisionFixer; import com.jpexs.decompiler.flash.abc.avm2.deobfuscation.DeobfuscationLevel; +import com.jpexs.decompiler.flash.abc.avm2.deobfuscation.DeobfuscationScope; +import com.jpexs.decompiler.flash.abc.types.ClassInfo; +import com.jpexs.decompiler.flash.abc.types.InstanceInfo; +import com.jpexs.decompiler.flash.abc.types.MethodBody; import com.jpexs.decompiler.flash.abc.types.traits.Trait; +import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; +import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction; +import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.configuration.ConfigurationItem; import com.jpexs.decompiler.flash.configuration.ConfigurationItemChangeListener; @@ -469,14 +476,13 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se return; } TreeItem item = (TreeItem) paths[0].getLastPathComponent(); - + if (item instanceof Tag) { - if (((Tag)item).isReadOnly()) { + if (((Tag) item).isReadOnly()) { return; - } + } } - - + if (e.getKeyCode() == KeyEvent.VK_UP) { contextPopupMenu.moveUpDown(item, true); } @@ -573,13 +579,13 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } } boolean allWritable = true; - for (TreeItem item:tagItems) { - if (((Tag)item).isReadOnly()) { + for (TreeItem item : tagItems) { + if (((Tag) item).isReadOnly()) { allWritable = false; break; } } - + if (e.getKeyCode() == 'C') { if (e.isShiftDown()) { contextPopupMenu.copyTagToClipboardWithDependenciesActionPerformed(null, tagItems); @@ -834,7 +840,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se public void setStatus(String s) { statusPanel.setStatus(s); } - + public void setEditingStatus() { statusPanel.setStatus(translate("status.editing")); } @@ -842,7 +848,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se public void clearEditingStatus() { statusPanel.setStatus(""); } - + public void setWorkStatus(String s, CancellableWorker worker) { statusPanel.setWorkStatus(s, worker); mainMenu.updateComponents(); @@ -1603,8 +1609,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se tagTree.updateUI(); } TreePath tp = getCurrentTree().getTreePathFromString(selectionPath); - if (tp != null) - { + if (tp != null) { getCurrentTree().setSelectionPath(tp); } } @@ -1960,7 +1965,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se ScriptExportSettings scriptExportSettings = new ScriptExportSettings(export.getValue(ScriptExportMode.class), singleScriptFile, false); String singleFileName = Path.combine(scriptsFolder, openable.getShortFileName() + scriptExportSettings.getFileExtension()); - try ( FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) { + try (FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) { scriptExportSettings.singleFileWriter = writer; if (swf.isAS3()) { ret.addAll(new AS3ScriptExporter().exportActionScript3(swf, handler, scriptsFolder, as3scripts, scriptExportSettings, parallel, evl)); @@ -2067,7 +2072,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se ScriptExportSettings scriptExportSettings = new ScriptExportSettings(export.getValue(ScriptExportMode.class), singleScriptFile, false); String singleFileName = Path.combine(scriptsFolder, swf.getShortFileName() + scriptExportSettings.getFileExtension()); - try ( FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) { + try (FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) { scriptExportSettings.singleFileWriter = writer; swf.exportActionScript(handler, scriptsFolder, scriptExportSettings, parallel, evl); } @@ -2184,7 +2189,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se ScriptExportSettings scriptExportSettings = new ScriptExportSettings(exportMode, singleScriptFile, false); String singleFileName = Path.combine(scriptsFolder, swf.getShortFileName() + scriptExportSettings.getFileExtension()); - try ( FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) { + try (FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) { scriptExportSettings.singleFileWriter = writer; swf.exportActionScript(handler, scriptsFolder, scriptExportSettings, parallel, evl); } @@ -3588,7 +3593,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se if (selectedFile != null) { File selfile = Helper.fixDialogFile(selectedFile); try { - try ( FileInputStream fis = new FileInputStream(selfile)) { + try (FileInputStream fis = new FileInputStream(selfile)) { new SwfXmlImporter().importSwf(swf, fis); } swf.clearAllCache(); @@ -3659,20 +3664,63 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } } + private void deobfuscateMethod(Trait t, int scriptIndex, DeobfuscationLevel level, boolean isStatic, int methodIndex, ABC abc) throws InterruptedException { + if (methodIndex == -1) { + return; + } + MethodBody body = abc.findBody(methodIndex); + if (body != null) { + body.deobfuscate(level, t, scriptIndex, methodIndex, isStatic, ""); + } + } + + private void deobfuscateTraits(int scriptIndex, DeobfuscationLevel level, List traits, ABC abc, boolean isStatic) throws InterruptedException { + for (Trait t : traits) { + int methodIndex = -1; + if (t instanceof TraitMethodGetterSetter) { + methodIndex = ((TraitMethodGetterSetter) t).method_info; + } + if (t instanceof TraitFunction) { + methodIndex = ((TraitFunction) t).method_info; + } + if (methodIndex != -1) { + deobfuscateMethod(t, scriptIndex, level, isStatic, methodIndex, abc); + } + if (t instanceof TraitClass) { + TraitClass tc = (TraitClass)t; + ClassInfo ci = abc.class_info.get(tc.class_info); + deobfuscateMethod(t, scriptIndex, level, true, ci.cinit_index, abc); + deobfuscateTraits(scriptIndex, level, ci.static_traits.traits, abc, true); + InstanceInfo ii = abc.instance_info.get(tc.class_info); + deobfuscateMethod(t, scriptIndex, level, false, ii.iinit_index, abc); + deobfuscateTraits(scriptIndex, level, ii.instance_traits.traits, abc, false); + } + } + } + public void deobfuscate() { View.checkAccess(); DeobfuscationDialog deobfuscationDialog = new DeobfuscationDialog(Main.getDefaultDialogsOwner()); if (deobfuscationDialog.showDialog() == AppDialog.OK_OPTION) { - DeobfuscationLevel level = DeobfuscationLevel.getByLevel(deobfuscationDialog.codeProcessingLevel.getValue()); + DeobfuscationLevel level = deobfuscationDialog.getDeobfuscationLevel(); new CancellableWorker() { @Override protected Void doInBackground() throws Exception { try { ABCPanel abcPanel = getABCPanel(); - if (deobfuscationDialog.processAllCheckbox.isSelected()) { + DeobfuscationScope scope = deobfuscationDialog.getDeobfuscationScope(); + if (scope == DeobfuscationScope.SWF) { SWF swf = abcPanel.getSwf(); swf.deobfuscate(level); + } else if (scope == DeobfuscationScope.CLASS) { + ScriptPack pack = abcPanel.getPack(); + if (pack == null) { + return null; + } + List traits = pack.abc.script_info.get(pack.scriptIndex).traits.traits; + deobfuscateMethod(null, pack.scriptIndex, level, true, pack.abc.script_info.get(pack.scriptIndex).init_index, pack.abc); + deobfuscateTraits(pack.scriptIndex, level, traits, pack.abc, true); } else { int mi = abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getMethodIndex(); int bi = abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex(); @@ -3689,6 +3737,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } } catch (Exception ex) { logger.log(Level.SEVERE, "Deobfuscation error", ex); + ViewMessages.showMessageDialog(MainPanel.this, translate("error.deobfuscation"),translate ("error"), JOptionPane.ERROR_MESSAGE); } return null; @@ -4711,7 +4760,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se if (treeItem instanceof ShapeTag) { previewPanel.setImageReplaceButtonVisible(false, false, !((Tag) treeItem).isReadOnly(), false); } - previewPanel.showImagePanel(timelined, tag.getSwf(), -1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), treeItem instanceof ShapeTag, !Configuration.playFrameSounds.get(), (treeItem instanceof DefineSpriteTag) || (treeItem instanceof ButtonTag), (treeItem instanceof DefineSpriteTag)||(treeItem instanceof ButtonTag)); + previewPanel.showImagePanel(timelined, tag.getSwf(), -1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), treeItem instanceof ShapeTag, !Configuration.playFrameSounds.get(), (treeItem instanceof DefineSpriteTag) || (treeItem instanceof ButtonTag), (treeItem instanceof DefineSpriteTag) || (treeItem instanceof ButtonTag)); } else if (treeItem instanceof Frame && internalViewer) { Frame fn = (Frame) treeItem; SWF swf = (SWF) fn.getOpenable(); @@ -5551,7 +5600,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } return itemToStr; } - + public void startEdit() { TreeItem treeItem = getCurrentTree().getCurrentTreeItem(); if (treeItem == null) { @@ -5572,10 +5621,10 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } else if (treeItem instanceof ASMSource) { //There are two kinds of edit - Script and P-code. } else if (treeItem instanceof Tag) { - Tag tag = (Tag)treeItem; + Tag tag = (Tag) treeItem; previewPanel.showGenericTagPanel(tag); previewPanel.startEditGenericTag(); } - + } } diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java index 122079de6..6b3b52009 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java @@ -216,6 +216,10 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener search(final Openable openable, final String txt, boolean ignoreCase, boolean regexp, boolean pcode, CancellableWorker worker, List scope) { if (txt != null && !txt.isEmpty()) { searchPanel.setOptions(ignoreCase, regexp); diff --git a/src/com/jpexs/decompiler/flash/gui/abc/DeobfuscationDialog.java b/src/com/jpexs/decompiler/flash/gui/abc/DeobfuscationDialog.java index 36449b30e..9c0649f3f 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/DeobfuscationDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/DeobfuscationDialog.java @@ -17,21 +17,21 @@ package com.jpexs.decompiler.flash.gui.abc; import com.jpexs.decompiler.flash.abc.avm2.deobfuscation.DeobfuscationLevel; +import com.jpexs.decompiler.flash.abc.avm2.deobfuscation.DeobfuscationScope; import com.jpexs.decompiler.flash.gui.AppDialog; import com.jpexs.decompiler.flash.gui.View; -import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; +import java.awt.Font; import java.awt.Window; import java.awt.event.ActionEvent; -import java.util.Hashtable; import javax.swing.BoxLayout; +import javax.swing.ButtonGroup; import javax.swing.JButton; -import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JPanel; -import javax.swing.JSlider; +import javax.swing.JRadioButton; /** * @@ -39,9 +39,12 @@ import javax.swing.JSlider; */ public class DeobfuscationDialog extends AppDialog { - public JCheckBox processAllCheckbox = new JCheckBox(translate("processallclasses")); + private final JRadioButton removeDeadCodeRadioButton = new JRadioButton(translate("deobfuscation.removedeadcode")); + private final JRadioButton removeTrapsRadioButton = new JRadioButton(translate("deobfuscation.removetraps")); - public JSlider codeProcessingLevel; + private final JRadioButton methodScopeRadioButton = new JRadioButton(translate("deobfuscation.scope.method")); + private final JRadioButton scriptScopeRadioButton = new JRadioButton(translate("deobfuscation.scope.script")); + private final JRadioButton swfScopeRadioButton = new JRadioButton(translate("deobfuscation.scope.swf")); private int result = ERROR_OPTION; @@ -49,39 +52,45 @@ public class DeobfuscationDialog extends AppDialog { public DeobfuscationDialog(Window owner) { super(owner); setDefaultCloseOperation(HIDE_ON_CLOSE); - setSize(new Dimension(330, 270)); setTitle(translate("dialog.title")); - Container cp = getContentPane(); - cp.setLayout(new BoxLayout(cp, BoxLayout.Y_AXIS)); - codeProcessingLevel = new JSlider(JSlider.VERTICAL, 1, 3, 3); - codeProcessingLevel.setMajorTickSpacing(1); - codeProcessingLevel.setPaintTicks(true); - codeProcessingLevel.setMinorTickSpacing(1); - codeProcessingLevel.setSnapToTicks(true); - JLabel lab1 = new JLabel(translate("deobfuscation.level")); - //lab1.setBounds(30, 0, getWidth() - 60, 25); - lab1.setAlignmentX(0.5f); - cp.add(lab1); - Hashtable labelTable = new Hashtable<>(); - //labelTable.put(LEVEL_NONE, new JLabel("None")); + Container contentPane = getContentPane(); + contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS)); + JLabel processingLevelLabel = new JLabel(translate("deobfuscation.level")); + processingLevelLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT); + contentPane.add(processingLevelLabel); - labelTable.put(DeobfuscationLevel.LEVEL_REMOVE_DEAD_CODE.getLevel(), new JLabel(translate("deobfuscation.removedeadcode"))); - labelTable.put(DeobfuscationLevel.LEVEL_REMOVE_TRAPS.getLevel(), new JLabel(translate("deobfuscation.removetraps"))); - labelTable.put(DeobfuscationLevel.LEVEL_RESTORE_CONTROL_FLOW.getLevel(), new JLabel(translate("deobfuscation.restorecontrolflow"))); - codeProcessingLevel.setLabelTable(labelTable); + JPanel processingLevelPanel = new JPanel(new FlowLayout()); + ButtonGroup levelGroup = new ButtonGroup(); + levelGroup.add(removeDeadCodeRadioButton); + levelGroup.add(removeTrapsRadioButton); + removeTrapsRadioButton.setSelected(true); - codeProcessingLevel.setPaintLabels(true); - codeProcessingLevel.setAlignmentX(Component.CENTER_ALIGNMENT); - //codeProcessingLevel.setSize(300, 200); + processingLevelPanel.add(removeDeadCodeRadioButton); + processingLevelPanel.add(removeTrapsRadioButton); + processingLevelPanel.setAlignmentX(JPanel.CENTER_ALIGNMENT); + removeTrapsRadioButton.setSelected(true); + contentPane.add(processingLevelPanel); - //codeProcessingLevel.setBounds(30, 25, getWidth() - 60, 125); - codeProcessingLevel.setAlignmentX(0.5f); - add(codeProcessingLevel); - //processAllCheckbox.setBounds(50, 150, getWidth() - 100, 25); - processAllCheckbox.setAlignmentX(0.5f); - add(processAllCheckbox); + JLabel scopeLabel = new JLabel(translate("deobfuscation.scope")); + scopeLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT); + contentPane.add(scopeLabel); - processAllCheckbox.setSelected(true); + ButtonGroup scopeGroup = new ButtonGroup(); + scopeGroup.add(methodScopeRadioButton); + scopeGroup.add(scriptScopeRadioButton); + scopeGroup.add(swfScopeRadioButton); + JPanel scopePanel = new JPanel(new FlowLayout()); + scopePanel.add(methodScopeRadioButton); + scopePanel.add(scriptScopeRadioButton); + scopePanel.add(swfScopeRadioButton); + swfScopeRadioButton.setSelected(true); + scopePanel.setAlignmentX(JPanel.CENTER_ALIGNMENT); + contentPane.add(scopePanel); + + JLabel warningLabel = new JLabel("
" + translate("warning.modify").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\r\n", "
") + "
"); + warningLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT); + warningLabel.setFont(warningLabel.getFont().deriveFont(Font.BOLD)); + contentPane.add(warningLabel); JButton cancelButton = new JButton(translate("button.cancel")); cancelButton.addActionListener(this::cancelButtonActionPerformed); @@ -92,13 +101,31 @@ public class DeobfuscationDialog extends AppDialog { buttonsPanel.add(okButton); buttonsPanel.add(cancelButton); buttonsPanel.setAlignmentX(0.5f); - cp.add(buttonsPanel); + contentPane.add(buttonsPanel); setModal(true); + pack(); View.centerScreen(this); setIconImage(View.loadImage("deobfuscate16")); } + public DeobfuscationLevel getDeobfuscationLevel() { + if (removeTrapsRadioButton.isSelected()) { + return DeobfuscationLevel.LEVEL_REMOVE_TRAPS; + } + return DeobfuscationLevel.LEVEL_REMOVE_DEAD_CODE; + } + + public DeobfuscationScope getDeobfuscationScope() { + if (methodScopeRadioButton.isSelected()) { + return DeobfuscationScope.METHOD; + } + if (scriptScopeRadioButton.isSelected()) { + return DeobfuscationScope.CLASS; + } + return DeobfuscationScope.SWF; + } + @Override public void setVisible(boolean b) { if (b) { diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties index d3c21b2d5..45509591d 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties @@ -1054,3 +1054,5 @@ deobfuscate_options.simplify_expressions = Simplify expressions deobfuscate_options.remove_obfuscated_declarations = Remove single assigned obfuscated declarations message.confirm.autoRenameIdentifiers = Automatic identifiers renaming feature will walk AS code\r\nupon opening SWF file and renames all nonstandard names to valid identifiers.\r\nThis feature may damage the SWF file upon saving - USE IT AT YOUR OWN RISK. + +error.deobfuscation = Deobfuscation failed for some of the methods. \ No newline at end of file diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties index d830e6557..d01d58452 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties @@ -1039,3 +1039,5 @@ deobfuscate_options.simplify_expressions = Zjednodu\u0161it v\u00fdrazy deobfuscate_options.remove_obfuscated_declarations = Odstranit jednor\u00e1zov\u011b p\u0159i\u0159azen\u00e9 obfuskovan\u00e9 deklarace message.confirm.autoRenameIdentifiers = Mo\u017enost automatick\u00e9ho p\u0159ejmenov\u00e1n\u00ed prom\u011bnn\u00fdch projde AS k\u00f3d\r\npo otev\u0159en\u00ed SWF souboru a p\u0159ejmenuje v\u0161echny nestandardn\u00ed n\u00e1zvy na platn\u00e9 identifik\u00e1tory.\r\nTato mo\u017enost m\u016f\u017ee po ulo\u017een\u00ed po\u0161kodit SWF soubor - POU\u017d\u00cdVAT NA VLASTN\u00cd RIZIKO. + +error.deobfuscation = Deobfuskace pro n\u011bkter\u00e9 metody selhala. \ No newline at end of file diff --git a/src/com/jpexs/decompiler/flash/gui/locales/abc/DeobfuscationDialog.properties b/src/com/jpexs/decompiler/flash/gui/locales/abc/DeobfuscationDialog.properties index 1ab89008a..90bf0fc95 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/abc/DeobfuscationDialog.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/abc/DeobfuscationDialog.properties @@ -22,3 +22,10 @@ deobfuscation.restorecontrolflow = Restore control flow button.ok = OK button.cancel = Cancel + +deobfuscation.scope = Scope: +deobfuscation.scope.method = Current method +deobfuscation.scope.script = Current script +deobfuscation.scope.swf = Whole SWF + +warning.modify = WARNING: This action will modify the SWF file.\r\nIf you want only deobfuscation for display, then use\r\n"Automatic deobfuscation" option in Settings\r\nor the small pill icon above the script editor. diff --git a/src/com/jpexs/decompiler/flash/gui/locales/abc/DeobfuscationDialog_cs.properties b/src/com/jpexs/decompiler/flash/gui/locales/abc/DeobfuscationDialog_cs.properties index 37baf2040..b56e0aa2d 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/abc/DeobfuscationDialog_cs.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/abc/DeobfuscationDialog_cs.properties @@ -22,3 +22,10 @@ deobfuscation.restorecontrolflow = Obnovit control flow button.ok = OK button.cancel = Storno + +deobfuscation.scope = Rozsah: +deobfuscation.scope.method = Aktu\u00e1ln\u00ed metoda +deobfuscation.scope.script = Aktu\u00e1ln\u00ed skript +deobfuscation.scope.swf = Cel\u00e9 SWF + +warning.modify = VAROV\u00c1N\u00cd: Tato akce modifikuje dan\u00fd SWF soubor.\r\nPokud chcete jen deobfuskaci pro zobrazen\u00ed,\r\npou\u017eijte volbu "Automatick\u00e1 deobfuskace" v Nastaven\u00ed\r\nnebo drobnou ikonku s pilulkou nad editorem skript\u016f.