Improved BCV Error Handling
This commit is contained in:
parent
35561fa5ca
commit
434d5cd58f
13 changed files with 73 additions and 57 deletions
|
@ -313,7 +313,7 @@ public class BytecodeViewer
|
|||
*/
|
||||
public static ClassNode getCurrentlyOpenedClassNode()
|
||||
{
|
||||
return getActiveResource().cn;
|
||||
return getActiveResource().viewerClassNode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -134,7 +134,6 @@ public class GlobalHotKeys
|
|||
Configuration.lastHotKeyExecuted = System.currentTimeMillis();
|
||||
|
||||
String recentFile = Settings.getRecentFile();
|
||||
System.out.println("Opening..." + recentFile);
|
||||
|
||||
if(!BytecodeViewer.hasResources() && recentFile != null)
|
||||
{
|
||||
|
|
|
@ -166,9 +166,8 @@ public class ResourceListPane extends TranslatedVisibleComponent implements File
|
|||
|
||||
if (!container.resourceClasses.isEmpty())
|
||||
{
|
||||
for (ClassNode c : container.resourceClasses.values())
|
||||
for (String name : container.resourceClasses.keySet())
|
||||
{
|
||||
String name = c.name;
|
||||
final String[] spl = name.split("/");
|
||||
if (spl.length < 2)
|
||||
{
|
||||
|
@ -304,9 +303,10 @@ public class ResourceListPane extends TranslatedVisibleComponent implements File
|
|||
}
|
||||
|
||||
String name = nameBuffer.toString();
|
||||
|
||||
if (name.endsWith(".class"))
|
||||
{
|
||||
final ClassNode cn = Objects.requireNonNull(container).getClassNode(
|
||||
final ClassNode cn = container.getClassNode(
|
||||
name.substring(0, name.length() - ".class".length()));
|
||||
|
||||
if (cn != null)
|
||||
|
|
|
@ -188,7 +188,7 @@ public class SearchBoxPane extends TranslatedVisibleComponent
|
|||
final ResourceViewer cv = BytecodeViewer.getActiveResource();
|
||||
|
||||
if (cv != null)
|
||||
searchType.details.search(cv.container, cv.cn, srn, exact.isSelected());
|
||||
searchType.details.search(cv.container, cv.viewerClassNode, srn, exact.isSelected());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package the.bytecode.club.bytecodeviewer.gui.resourceviewer;
|
||||
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||
import the.bytecode.club.bytecodeviewer.compilers.Compiler;
|
||||
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
|
||||
import the.bytecode.club.bytecodeviewer.gui.components.SearchableRSyntaxTextArea;
|
||||
|
@ -59,9 +58,9 @@ public class ResourceViewPanel
|
|||
panel.removeAll();
|
||||
textArea = null;
|
||||
|
||||
if(viewer.cn == null)
|
||||
if(viewer.viewerClassNode == null)
|
||||
{
|
||||
panel.add(new JLabel("This resource has been removed."));
|
||||
panel.add(new JLabel("ERROR: Resource Viewer Corrupt ClassNode"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,7 +75,7 @@ public class ResourceViewPanel
|
|||
return true;
|
||||
|
||||
SystemConsole errConsole = new SystemConsole("Java Compile Issues");
|
||||
errConsole.setText("Error compiling class: " + viewer.cn.name +
|
||||
errConsole.setText("Error compiling class: " + viewer.viewerClassNode.name +
|
||||
nl + "Keep in mind most decompilers cannot produce compilable classes" +
|
||||
nl + nl + TranslatedStrings.SUGGESTED_FIX_COMPILER_ERROR +
|
||||
nl + nl);
|
||||
|
@ -84,12 +83,12 @@ public class ResourceViewPanel
|
|||
try
|
||||
{
|
||||
String text = textArea.getText();
|
||||
byte[] compiledClass = compileMode.getCompiler().compile(text, viewer.cn.name);
|
||||
byte[] compiledClass = compileMode.getCompiler().compile(text, viewer.viewerClassNode.name);
|
||||
|
||||
if (compiledClass != null)
|
||||
{
|
||||
ClassNode newNode = JarUtils.getNode(compiledClass);
|
||||
viewer.container.updateNode(viewer.cn, newNode);
|
||||
viewer.container.updateNode(viewer.viewerClassNode, newNode);
|
||||
errConsole.finished();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,22 +1,15 @@
|
|||
package the.bytecode.club.bytecodeviewer.gui.resourceviewer;
|
||||
|
||||
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||
import the.bytecode.club.bytecodeviewer.Configuration;
|
||||
import the.bytecode.club.bytecodeviewer.compilers.Compiler;
|
||||
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
|
||||
import the.bytecode.club.bytecodeviewer.gui.components.SearchableRSyntaxTextArea;
|
||||
import the.bytecode.club.bytecodeviewer.gui.hexviewer.JHexEditor;
|
||||
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ClassViewer;
|
||||
import the.bytecode.club.bytecodeviewer.gui.util.PaneUpdaterThread;
|
||||
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.EDITABLE;
|
||||
|
||||
/***************************************************************************
|
||||
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
||||
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
|
||||
|
@ -46,7 +39,6 @@ public class ResourceViewProcessing extends PaneUpdaterThread
|
|||
{
|
||||
private final ResourceViewPanel resourceViewPanel;
|
||||
private final byte[] b;
|
||||
private final boolean isPanelEditable;
|
||||
private final JButton button;
|
||||
public boolean waitingFor;
|
||||
|
||||
|
@ -73,7 +65,7 @@ public class ResourceViewProcessing extends PaneUpdaterThread
|
|||
if (resourceViewPanel.decompiler == Decompiler.HEXCODE_VIEWER)
|
||||
{
|
||||
final ClassWriter cw = new ClassWriter(0);
|
||||
viewer.cn.accept(cw);
|
||||
viewer.viewerClassNode.accept(cw);
|
||||
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
|
@ -88,34 +80,12 @@ public class ResourceViewProcessing extends PaneUpdaterThread
|
|||
final Decompiler decompiler = resourceViewPanel.decompiler;
|
||||
|
||||
//perform decompiling inside of this thread
|
||||
final String decompiledSource = decompiler.getDecompiler().decompileClassNode(viewer.cn, b);
|
||||
final String decompiledSource = decompiler.getDecompiler().decompileClassNode(viewer.viewerClassNode, b);
|
||||
|
||||
//set the swing components on the swing thread
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
updateUpdaterTextArea = new SearchableRSyntaxTextArea();
|
||||
|
||||
Configuration.rstaTheme.apply(updateUpdaterTextArea);
|
||||
resourceViewPanel.panel.add(updateUpdaterTextArea.getScrollPane());
|
||||
resourceViewPanel.panel.add(updateUpdaterTextArea.getTitleHeader(), BorderLayout.NORTH);
|
||||
|
||||
resourceViewPanel.textArea = updateUpdaterTextArea;
|
||||
resourceViewPanel.textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
|
||||
resourceViewPanel.textArea.setCodeFoldingEnabled(true);
|
||||
resourceViewPanel.textArea.setAntiAliasingEnabled(true);
|
||||
resourceViewPanel.textArea.setText(decompiledSource);
|
||||
resourceViewPanel.textArea.setCaretPosition(0);
|
||||
resourceViewPanel.textArea.setEditable(isPanelEditable);
|
||||
|
||||
if(isPanelEditable && decompiler == Decompiler.SMALI_DISASSEMBLER)
|
||||
resourceViewPanel.compileMode = Compiler.SMALI_ASSEMBLER;
|
||||
else if(isPanelEditable && decompiler == Decompiler.KRAKATAU_DISASSEMBLER)
|
||||
resourceViewPanel.compileMode = Compiler.KRAKATAU_ASSEMBLER;
|
||||
|
||||
String editable = isPanelEditable ? " - " + EDITABLE : "";
|
||||
resourceViewPanel.textArea.getTitleHeader().setText(decompiler.getDecompilerName() + editable);
|
||||
resourceViewPanel.textArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int) BytecodeViewer.viewer.fontSpinner.getValue()));
|
||||
|
||||
buildTextArea(decompiler, decompiledSource);
|
||||
waitingFor = false;
|
||||
});
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ public class ClassViewer extends ResourceViewer
|
|||
this.container = container;
|
||||
|
||||
this.name = name;
|
||||
this.cn = cn;
|
||||
this.viewerClassNode = cn;
|
||||
this.setName(name);
|
||||
this.setLayout(new BorderLayout());
|
||||
|
||||
|
@ -91,7 +91,7 @@ public class ClassViewer extends ResourceViewer
|
|||
@Override
|
||||
public void refresh(final JButton button)
|
||||
{
|
||||
this.cn = container.getClassNode(cn.name); //update the classnode
|
||||
this.viewerClassNode = container.getClassNode(name); //update the classnode
|
||||
|
||||
setPanes();
|
||||
refreshTitle();
|
||||
|
@ -113,7 +113,7 @@ public class ClassViewer extends ResourceViewer
|
|||
System.err.println("TODO: Update it to use the FileContainerImporter");
|
||||
}
|
||||
|
||||
classBytes = ASMUtil.nodeToBytes(cn);
|
||||
classBytes = ASMUtil.nodeToBytes(viewerClassNode);
|
||||
}
|
||||
|
||||
resourceViewPanel1.updatePane(this, classBytes, button, isPanel1Editable());
|
||||
|
|
|
@ -34,7 +34,7 @@ import the.bytecode.club.bytecodeviewer.util.MiscUtils;
|
|||
|
||||
public abstract class ResourceViewer extends JPanel
|
||||
{
|
||||
public ClassNode cn;
|
||||
public ClassNode viewerClassNode;
|
||||
public String name;
|
||||
public String workingName;
|
||||
public ResourceContainer container;
|
||||
|
|
|
@ -11,8 +11,11 @@ import javax.swing.event.CaretListener;
|
|||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
|
||||
import org.fife.ui.rtextarea.RTextScrollPane;
|
||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||
import the.bytecode.club.bytecodeviewer.Configuration;
|
||||
import the.bytecode.club.bytecodeviewer.compilers.Compiler;
|
||||
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
|
||||
import the.bytecode.club.bytecodeviewer.gui.components.MethodsRenderer;
|
||||
import the.bytecode.club.bytecodeviewer.gui.components.SearchableRSyntaxTextArea;
|
||||
|
@ -21,6 +24,7 @@ import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ClassViewer;
|
|||
import the.bytecode.club.bytecodeviewer.util.MethodParser;
|
||||
|
||||
import static the.bytecode.club.bytecodeviewer.gui.resourceviewer.TabbedPane.BLANK_COLOR;
|
||||
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.EDITABLE;
|
||||
|
||||
/***************************************************************************
|
||||
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
||||
|
@ -54,6 +58,7 @@ public abstract class PaneUpdaterThread implements Runnable
|
|||
public final ResourceViewPanel resourceViewPanel;
|
||||
public SearchableRSyntaxTextArea updateUpdaterTextArea;
|
||||
public JComboBox<Integer> methodsList;
|
||||
public boolean isPanelEditable;
|
||||
private Thread thread;
|
||||
|
||||
public PaneUpdaterThread(ClassViewer viewer, ResourceViewPanel resourceViewPanel)
|
||||
|
@ -78,6 +83,16 @@ public abstract class PaneUpdaterThread implements Runnable
|
|||
|
||||
processDisplay();
|
||||
|
||||
//nullcheck broken pane
|
||||
if(updateUpdaterTextArea == null || updateUpdaterTextArea.getScrollPane() == null
|
||||
|| updateUpdaterTextArea.getScrollPane().getViewport() == null)
|
||||
{
|
||||
//build an error message
|
||||
SwingUtilities.invokeLater(() ->
|
||||
buildTextArea(resourceViewPanel.decompiler, "Critical BCV Error"));
|
||||
return;
|
||||
}
|
||||
|
||||
//this still freezes the swing UI
|
||||
synchronizePane();
|
||||
|
||||
|
@ -284,4 +299,30 @@ public abstract class PaneUpdaterThread implements Runnable
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void buildTextArea(Decompiler decompiler, String decompiledSource)
|
||||
{
|
||||
updateUpdaterTextArea = new SearchableRSyntaxTextArea();
|
||||
|
||||
Configuration.rstaTheme.apply(updateUpdaterTextArea);
|
||||
resourceViewPanel.panel.add(updateUpdaterTextArea.getScrollPane());
|
||||
resourceViewPanel.panel.add(updateUpdaterTextArea.getTitleHeader(), BorderLayout.NORTH);
|
||||
|
||||
resourceViewPanel.textArea = updateUpdaterTextArea;
|
||||
resourceViewPanel.textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
|
||||
resourceViewPanel.textArea.setCodeFoldingEnabled(true);
|
||||
resourceViewPanel.textArea.setAntiAliasingEnabled(true);
|
||||
resourceViewPanel.textArea.setText(decompiledSource);
|
||||
resourceViewPanel.textArea.setCaretPosition(0);
|
||||
resourceViewPanel.textArea.setEditable(isPanelEditable);
|
||||
|
||||
if(isPanelEditable && decompiler == Decompiler.SMALI_DISASSEMBLER)
|
||||
resourceViewPanel.compileMode = Compiler.SMALI_ASSEMBLER;
|
||||
else if(isPanelEditable && decompiler == Decompiler.KRAKATAU_DISASSEMBLER)
|
||||
resourceViewPanel.compileMode = Compiler.KRAKATAU_ASSEMBLER;
|
||||
|
||||
String editable = isPanelEditable ? " - " + EDITABLE : "";
|
||||
resourceViewPanel.textArea.getTitleHeader().setText(decompiler.getDecompilerName() + editable);
|
||||
resourceViewPanel.textArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int) BytecodeViewer.viewer.fontSpinner.getValue()));
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package the.bytecode.club.bytecodeviewer.resources;
|
|||
import java.io.File;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import the.bytecode.club.bytecodeviewer.api.ASMUtil;
|
||||
import the.bytecode.club.bytecodeviewer.util.LazyNameUtil;
|
||||
|
@ -58,6 +59,10 @@ public class ResourceContainer
|
|||
*/
|
||||
public ClassNode getClassNode(String resourceName)
|
||||
{
|
||||
//fallback incase the resource contains the file extension
|
||||
if(resourceClassBytes.containsKey(resourceName))
|
||||
return resourceClasses.get(FilenameUtils.removeExtension(resourceName));
|
||||
|
||||
return resourceClasses.get(resourceName);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,8 @@ public enum Import
|
|||
{
|
||||
DIRECTORY(new DirectoryResourceImporter()),
|
||||
FILE(new FileResourceImporter()),
|
||||
//TODO ear needs to work the same as XAPK
|
||||
//TODO ear needs to import the same as XAPK
|
||||
//TODO war needs to add the /libs correctly similar to XAPK
|
||||
ZIP(new ZipResourceImporter(), "zip", "jar", "war", "ear"),
|
||||
CLASS(new ClassResourceImporter(), "class"),
|
||||
XAPK(new XAPKResourceImporter(), "xapk"),
|
||||
|
|
|
@ -41,6 +41,7 @@ public class ImportResource implements Runnable
|
|||
for (final File file : files)
|
||||
{
|
||||
final String fn = file.getName();
|
||||
System.out.println("Opening..." + fn);
|
||||
|
||||
//check if file exists
|
||||
if (!file.exists())
|
||||
|
|
|
@ -60,12 +60,7 @@ public class DirectoryResourceImporter implements Importer
|
|||
.replaceAll("\\\\", "\\/");
|
||||
final String fileName = child.getName();
|
||||
|
||||
//attempt to import archives automatically
|
||||
if(ImportResource.importKnownFile(file))
|
||||
{
|
||||
//let import resource handle it
|
||||
}
|
||||
else if (fileName.endsWith(".class"))
|
||||
if (fileName.endsWith(".class"))
|
||||
{
|
||||
byte[] bytes = Files.readAllBytes(Paths.get(child.getAbsolutePath()));
|
||||
if (MiscUtils.getFileHeaderMagicNumber(bytes).equalsIgnoreCase("cafebabe"))
|
||||
|
@ -74,6 +69,11 @@ public class DirectoryResourceImporter implements Importer
|
|||
allDirectoryClasses.put(FilenameUtils.removeExtension(trimmedPath), cn);
|
||||
}
|
||||
}
|
||||
//attempt to import archives automatically
|
||||
else if(ImportResource.importKnownFile(file))
|
||||
{
|
||||
//let import resource handle it
|
||||
}
|
||||
else //pack files into a single container
|
||||
{
|
||||
allDirectoryFiles.put(trimmedPath, Files.readAllBytes(Paths.get(child.getAbsolutePath())));
|
||||
|
|
Loading…
Reference in a new issue