Fixed Compiling

So far only Krakatau Assembler has been tested, so Java and Smali are probably still broken
This commit is contained in:
Konloch 2021-07-04 19:07:34 -07:00
parent 6efbc39ff6
commit 63d7c17d0e
10 changed files with 130 additions and 169 deletions

View file

@ -50,6 +50,7 @@ public class DiskWriter {
*/
public static synchronized void writeNewLine(String filename,
byte[] fileContents, boolean debug) {
new File(filename).getParentFile().mkdirs();
PrintWriter writer = null;
String original = filename;
int counter = 0;
@ -86,6 +87,7 @@ public class DiskWriter {
*/
public static synchronized void writeNewLine(String filename,
String lineToWrite, boolean debug) {
new File(filename).getParentFile().mkdirs();
PrintWriter writer = null;
String original = filename;
int counter = 0;
@ -124,6 +126,7 @@ public class DiskWriter {
*/
public static synchronized void replaceFile(String filename,
byte[] fileContents, boolean debug) {
new File(filename).getParentFile().mkdirs();
File f = new File(filename);
if (f.exists())
f.delete();
@ -164,6 +167,7 @@ public class DiskWriter {
*/
public static synchronized void replaceFile(String filename,
String lineToWrite, boolean debug) {
new File(filename).getParentFile().mkdirs();
File f = new File(filename);
if (f.exists())
f.delete();

View file

@ -20,7 +20,6 @@ import the.bytecode.club.bootloader.Boot;
import the.bytecode.club.bytecodeviewer.api.ClassNodeLoader;
import the.bytecode.club.bytecodeviewer.compilers.Compiler;
import the.bytecode.club.bytecodeviewer.gui.components.*;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.ResourcePanelCompileMode;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.TabbedPane;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ClassViewer;
import the.bytecode.club.bytecodeviewer.gui.resourcelist.ResourceListPane;
@ -80,13 +79,13 @@ import static the.bytecode.club.bytecodeviewer.util.MiscUtils.guessLanguage;
* + The compile mode inside the ResourceViewPanel for Krakatau and Smali assembly needs to be changed when opened with those specific decompilers
* + Spam-clicking the refresh button will cause the swing thread to deadlock (Quickly opening resources used to also do this)
* This is caused by the ctrlMouseWheelZoom code, a temporary patch is just removing it worst case
* + Versioning and updating need to be fixed
* + Fix classfile searcher
* + Smali Assembly compile - Needs to be fixed
* + Krakatau Assembly compile - Needs to be fixed
*
* TODO IN-PROGRESS:
* + While loading an external plugin it should check if its java or JS, if so it should ask if you'd like to run or edit the plugin using the PluginWriter
* + Resource Importer needs to be rewriten to handle resources better
* + Resource Importer needs to be rewritten to handle resources better
* + Finish dragging code
* + Finish right-click tab menu detection
* + Fix hook inject for EZ-Injection
@ -104,6 +103,7 @@ import static the.bytecode.club.bytecodeviewer.util.MiscUtils.guessLanguage;
* + Add decompile all as zip for CLI
*
* TODO IDEAS:
* + App Bundle Support
* + Add the setting to force all non-classes to be opened with the Hex Viewer
* ^ Optionally a right-click menu open-as would work inside of the resource list
* + Allow class files to be opened without needing the .class extension
@ -237,9 +237,11 @@ public class BytecodeViewer
*
* @param cli is it running CLI mode or not
*/
public static void boot(boolean cli) {
public static void boot(boolean cli)
{
cleanupAsync();
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
Runtime.getRuntime().addShutdownHook(new Thread(() ->
{
for (Process proc : createdProcesses)
proc.destroy();
SettingsSerializer.saveSettings();
@ -249,7 +251,9 @@ public class BytecodeViewer
viewer.calledAfterLoad();
Settings.resetRecentFilesMenu();
if (!Configuration.pingback) {
//ping back once on first boot to add to global user count
if (!Configuration.pingback)
{
pingBack.start();
Configuration.pingback = true;
}
@ -386,7 +390,8 @@ public class BytecodeViewer
* @param oldNode the old instance
* @param newNode the new instance
*/
public static void updateNode(ClassNode oldNode, ClassNode newNode) {
public static void updateNode(ClassNode oldNode, ClassNode newNode)
{
for (FileContainer container : files) {
if (container.classes.remove(oldNode))
container.classes.add(newNode);
@ -432,6 +437,7 @@ public class BytecodeViewer
*/
public static boolean compile(boolean message) {
BytecodeViewer.viewer.updateBusyStatus(true);
boolean noErrors = true;
boolean actuallyTried = false;
for (java.awt.Component c : BytecodeViewer.viewer.workPane.getLoadedViewers())
@ -440,114 +446,34 @@ public class BytecodeViewer
{
ClassViewer cv = (ClassViewer) c;
//compile smali assembly
if (cv.resourceViewPanel1.compileMode == ResourcePanelCompileMode.SMALI_ASSEMBLY && cv.resourceViewPanel1.textArea.isEditable() ||
cv.resourceViewPanel2.compileMode == ResourcePanelCompileMode.SMALI_ASSEMBLY && cv.resourceViewPanel2.textArea.isEditable() ||
cv.resourceViewPanel3.compileMode == ResourcePanelCompileMode.SMALI_ASSEMBLY && cv.resourceViewPanel3.textArea.isEditable())
{
if(noErrors && !cv.resourceViewPanel1.compile())
noErrors = false;
if(noErrors && !cv.resourceViewPanel2.compile())
noErrors = false;
if(noErrors && !cv.resourceViewPanel3.compile())
noErrors = false;
if(cv.resourceViewPanel1.textArea.isEditable())
actuallyTried = true;
Object[] smali = cv.getSmali();
if (smali != null)
{
ClassNode origNode = (ClassNode) smali[0];
String smaliText = (String) smali[1];
byte[] smaliCompiled = Compiler.SMALI_ASSEMBLER.getCompiler().compile(smaliText, origNode.name);
if (smaliCompiled != null)
{
try {
ClassNode newNode = JarUtils.getNode(smaliCompiled);
BytecodeViewer.updateNode(origNode, newNode);
} catch (Exception e) {
e.printStackTrace();
}
}
else
{
BytecodeViewer.showMessage("There has been an error with assembling your Smali code, "
+ "please check this. Class: " + origNode.name);
BytecodeViewer.viewer.updateBusyStatus(false);
return false;
}
}
}
//compile krakatau assembly
if (cv.resourceViewPanel1.compileMode == ResourcePanelCompileMode.KRAKATAU_ASSEMBLY && cv.resourceViewPanel1.textArea.isEditable() ||
cv.resourceViewPanel2.compileMode == ResourcePanelCompileMode.KRAKATAU_ASSEMBLY && cv.resourceViewPanel2.textArea.isEditable() ||
cv.resourceViewPanel3.compileMode == ResourcePanelCompileMode.KRAKATAU_ASSEMBLY && cv.resourceViewPanel3.textArea.isEditable())
{
if(cv.resourceViewPanel2.textArea.isEditable())
actuallyTried = true;
Object[] krakatau = cv.getKrakatau();
if (krakatau != null)
{
ClassNode origNode = (ClassNode) krakatau[0];
String krakatauText = (String) krakatau[1];
byte[] krakatauCompiled = Compiler.KRAKATAU_ASSEMBLER.getCompiler().compile(krakatauText, origNode.name);
if (krakatauCompiled != null)
{
try {
ClassNode newNode = JarUtils.getNode(krakatauCompiled);
BytecodeViewer.updateNode(origNode, newNode);
} catch (Exception e) {
e.printStackTrace();
}
}
else
{
BytecodeViewer.showMessage("There has been an error with assembling your Krakatau "
+ "Bytecode, please check this. Class: " + origNode.name);
BytecodeViewer.viewer.updateBusyStatus(false);
return false;
}
}
}
//default to java compiling
if (cv.resourceViewPanel1.textArea != null && cv.resourceViewPanel1.textArea.isEditable() ||
cv.resourceViewPanel2.textArea != null && cv.resourceViewPanel2.textArea.isEditable() ||
cv.resourceViewPanel3.textArea != null && cv.resourceViewPanel3.textArea.isEditable())
{
if(cv.resourceViewPanel3.textArea.isEditable())
actuallyTried = true;
Object[] java = cv.getJava();
if (java != null) {
ClassNode origNode = (ClassNode) java[0];
String javaText = (String) java[1];
SystemErrConsole errConsole = new SystemErrConsole("Java Compile Issues");
errConsole.setText("Error compiling class: " + origNode.name + nl + "Keep in mind most "
+ "decompilers cannot produce compilable classes" + nl + nl);
byte[] javaCompiled = Compiler.JAVA_COMPILER.getCompiler().compile(javaText, origNode.name);
if (javaCompiled != null)
{
try {
ClassNode newNode = JarUtils.getNode(javaCompiled);
BytecodeViewer.updateNode(origNode, newNode);
} catch (Exception e) {
e.printStackTrace();
}
errConsole.finished();
}
else
{
errConsole.pretty();
errConsole.setVisible(true);
errConsole.finished();
BytecodeViewer.viewer.updateBusyStatus(false);
return false;
}
}
}
}
}
if (message)
{
if (actuallyTried)
BytecodeViewer.showMessage("Compiled Successfully.");
{
if(noErrors)
BytecodeViewer.showMessage("Compiled Successfully.");
}
else
{
BytecodeViewer.showMessage("You have no editable panes opened, make one editable and try again.");
}
}
BytecodeViewer.viewer.updateBusyStatus(false);
return true;

View file

@ -151,7 +151,8 @@ public class JavaCompiler extends InternalCompiler
try {
return org.apache.commons.io.FileUtils.readFileToByteArray(clazz);
} catch (IOException e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
e.printStackTrace();
//new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
return null;

View file

@ -4,6 +4,8 @@ import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Objects;
import me.konloch.kontainer.io.DiskWriter;
import org.apache.commons.io.FileUtils;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
@ -107,19 +109,45 @@ public class KrakatauAssembler extends InternalCompiler
int exitValue = process.waitFor();
log.append(nl).append(nl).append("Exit Value is ").append(exitValue);
System.out.println(log);
System.err.println(log);
byte[] b = FileUtils.readFileToByteArray(new File(tempDirectory.getAbsolutePath() + fs + origName + ".class"));
byte[] b = FileUtils.readFileToByteArray(Objects.requireNonNull(findFile(tempDirectory, ".class")));
tempDirectory.delete();
tempJar.delete();
return b;
} catch (Exception e) {
e.printStackTrace();
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(log.toString());
//new the.bytecode.club.bytecodeviewer.api.ExceptionUI(log.toString());
} finally {
BytecodeViewer.sm.setBlocking();
}
return null;
}
/**
* Searches a directory until the extension is found
*/
public static File findFile(File basePath, String extension)
{
for(File f : basePath.listFiles())
{
if(f.isDirectory())
{
File child = findFile(f, extension);
if(child != null)
return child;
continue;
}
if(f.getName().endsWith(extension))
{
return f;
}
}
return null;
}
}

View file

@ -56,7 +56,8 @@ public class SmaliAssembler extends InternalCompiler
try {
DiskWriter.replaceFile(tempSmali.getAbsolutePath(), contents, false);
} catch (final Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
e.printStackTrace();
//new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
try {
@ -64,7 +65,7 @@ public class SmaliAssembler extends InternalCompiler
// .getAbsolutePath()});
} catch (Exception e) {
e.printStackTrace();
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
//new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
@ -96,7 +97,8 @@ public class SmaliAssembler extends InternalCompiler
return FileUtils.readFileToByteArray(outputClass);
} catch (java.lang.NullPointerException ignored) { }
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
e.printStackTrace();
//new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
return null;

View file

@ -641,7 +641,7 @@ public class MainViewerGUI extends JFrame
public void defaultSettings()
{
compileOnSave.setSelected(false);
autoCompileOnRefresh.setSelected(false);
autoCompileOnRefresh.setSelected(true);
decodeAPKResources.setSelected(true);
updateCheck.setSelected(true);
forcePureAsciiAsText.setSelected(true);

View file

@ -1,12 +0,0 @@
package the.bytecode.club.bytecodeviewer.gui.resourceviewer;
/**
* @author Konloch
* @since 6/25/2021
*/
public enum ResourcePanelCompileMode
{
JAVA,
KRAKATAU_ASSEMBLY,
SMALI_ASSEMBLY,
}

View file

@ -1,13 +1,20 @@
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;
import the.bytecode.club.bytecodeviewer.gui.components.SystemErrConsole;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ClassViewer;
import the.bytecode.club.bytecodeviewer.gui.util.PaneUpdaterThread;
import the.bytecode.club.bytecodeviewer.util.JarUtils;
import javax.swing.*;
import java.awt.*;
import static the.bytecode.club.bytecodeviewer.Constants.nl;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
@ -34,15 +41,17 @@ public class ResourceViewPanel
{
public final JPanel panel = new JPanel(new BorderLayout());
public ClassViewer viewer;
public final int panelIndex;
public final ClassViewer viewer;
public Decompiler decompiler = Decompiler.NONE;
public SearchableRSyntaxTextArea textArea;
public PaneUpdaterThread updateThread;
public final int panelIndex;
public ResourcePanelCompileMode compileMode = ResourcePanelCompileMode.JAVA;
public Compiler compileMode = Compiler.JAVA_COMPILER;
public ResourceViewPanel(int panelIndex) {this.panelIndex = panelIndex;}
public ResourceViewPanel(int panelIndex, ClassViewer viewer) {this.panelIndex = panelIndex;
this.viewer = viewer;
}
public void createPane(ClassViewer viewer)
{
@ -59,4 +68,38 @@ public class ResourceViewPanel
{
updateThread = new ResourceViewProcessing(this, cv, b, isPanelEditable, button);
}
public boolean compile()
{
if(!textArea.isEditable())
return true;
SystemErrConsole errConsole = new SystemErrConsole("Java Compile Issues");
errConsole.setText("Error compiling class: " + viewer.cn.name +
nl + "Keep in mind most decompilers cannot produce compilable classes" +
nl + nl);
String text = textArea.getText();
byte[] compiledClass = compileMode.getCompiler().compile(text, viewer.cn.name);
if (compiledClass != null)
{
try {
ClassNode newNode = JarUtils.getNode(compiledClass);
BytecodeViewer.updateNode(viewer.cn, newNode);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
else
{
errConsole.pretty();
errConsole.setVisible(true);
errConsole.finished();
return false;
}
}
}

View file

@ -4,6 +4,7 @@ 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;
@ -104,6 +105,11 @@ public class ResourceViewProcessing extends PaneUpdaterThread
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;
resourceViewPanel.textArea.getTitleHeader().setText(decompiler.getDecompilerName() + " - Editable: " + resourceViewPanel.textArea.isEditable());
resourceViewPanel.textArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN,
(int) BytecodeViewer.viewer.fontSpinner.getValue()));

View file

@ -1,7 +1,6 @@
package the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer;
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.ResourcePanelCompileMode;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.ResourceViewPanel;
import the.bytecode.club.bytecodeviewer.gui.hexviewer.JHexEditor;
import java.awt.BorderLayout;
@ -62,9 +61,9 @@ public class ClassViewer extends ResourceViewer
{
public JSplitPane sp;
public JSplitPane sp2;
public ResourceViewPanel resourceViewPanel1 = new ResourceViewPanel(0);
public ResourceViewPanel resourceViewPanel2 = new ResourceViewPanel(1);
public ResourceViewPanel resourceViewPanel3 = new ResourceViewPanel(2);
public ResourceViewPanel resourceViewPanel1 = new ResourceViewPanel(0, this);
public ResourceViewPanel resourceViewPanel2 = new ResourceViewPanel(1, this);
public ResourceViewPanel resourceViewPanel3 = new ResourceViewPanel(2, this);
public File[] tempFiles;
public ClassViewer THIS = this;
@ -211,42 +210,6 @@ public class ClassViewer extends ResourceViewer
tabbedPane.label.setText(getTabName());
}
public Object[] getSmali()
{
if (resourceViewPanel1.compileMode == ResourcePanelCompileMode.SMALI_ASSEMBLY)
return new Object[]{cn, resourceViewPanel1.textArea.getText()};
if (resourceViewPanel2.compileMode == ResourcePanelCompileMode.SMALI_ASSEMBLY)
return new Object[]{cn, resourceViewPanel2.textArea.getText()};
if (resourceViewPanel3.compileMode == ResourcePanelCompileMode.SMALI_ASSEMBLY)
return new Object[]{cn, resourceViewPanel3.textArea.getText()};
return null;
}
public Object[] getKrakatau()
{
if (resourceViewPanel1.compileMode == ResourcePanelCompileMode.KRAKATAU_ASSEMBLY)
return new Object[]{cn, resourceViewPanel1.textArea.getText()};
if (resourceViewPanel2.compileMode == ResourcePanelCompileMode.KRAKATAU_ASSEMBLY)
return new Object[]{cn, resourceViewPanel2.textArea.getText()};
if (resourceViewPanel3.compileMode == ResourcePanelCompileMode.KRAKATAU_ASSEMBLY)
return new Object[]{cn, resourceViewPanel3.textArea.getText()};
return null;
}
public Object[] getJava()
{
if (resourceViewPanel1.textArea != null)
return new Object[]{cn, resourceViewPanel1.textArea.getText()};
if (resourceViewPanel2.textArea != null)
return new Object[]{cn, resourceViewPanel2.textArea.getText()};
if (resourceViewPanel3.textArea != null)
return new Object[]{cn, resourceViewPanel3.textArea.getText()};
return null;
}
public void setPanes() {
resourceViewPanel1.decompiler = BytecodeViewer.viewer.viewPane1.getSelectedDecompiler();
resourceViewPanel2.decompiler = BytecodeViewer.viewer.viewPane2.getSelectedDecompiler();