Add ASMifier support

This adds support (both GUI and CLI) for generating Java code from ASMifier to generate the bytecode of a class with ASM
This commit is contained in:
nick-botticelli 2022-05-27 16:53:59 -07:00
parent 56b3a72c25
commit 0d221dbca5
8 changed files with 88 additions and 26 deletions

View file

@ -100,6 +100,7 @@ public class CommandLineInput {
System.out.println("Krakatau-Bytecode"); System.out.println("Krakatau-Bytecode");
System.out.println("JD-GUI"); System.out.println("JD-GUI");
System.out.println("Smali"); System.out.println("Smali");
System.out.println("ASMifier");
return STOP; return STOP;
} else if (cmd.hasOption("clean")) { } else if (cmd.hasOption("clean")) {
new File(Constants.getBCVDirectory()).delete(); new File(Constants.getBCVDirectory()).delete();
@ -163,7 +164,8 @@ public class CommandLineInput {
!decompiler.equalsIgnoreCase("krakatau") && !decompiler.equalsIgnoreCase("krakatau") &&
!decompiler.equalsIgnoreCase("krakatau-bytecode") && !decompiler.equalsIgnoreCase("krakatau-bytecode") &&
!decompiler.equalsIgnoreCase("jd-gui") && !decompiler.equalsIgnoreCase("jd-gui") &&
!decompiler.equalsIgnoreCase("smali") !decompiler.equalsIgnoreCase("smali") &&
!decompiler.equalsIgnoreCase("asmifier")
) { ) {
System.out.println("Error, no decompiler called '" + decompiler + "' found. Type -list" System.out.println("Error, no decompiler called '" + decompiler + "' found. Type -list"
+ " for the list"); + " for the list");
@ -356,6 +358,26 @@ public class CommandLineInput {
} }
} }
} }
else if (decompiler.equalsIgnoreCase("asmifier")) {
System.out.println("Generating ASM code for " + input.getAbsolutePath() + " with ASMifier");
BytecodeViewer.openFiles(new File[]{input}, false);
Thread.sleep(5 * 1000);
if (target.equalsIgnoreCase("all")) {
System.out.println("Coming soon.");
//Decompiler.smali.decompileToZip(output.getAbsolutePath());
} else {
try {
ClassNode cn = BytecodeViewer.blindlySearchForClassNode(target);
final ClassWriter cw = accept(cn);
String contents = Decompiler.ASMIFIER_DECOMPILER.getDecompiler().decompileClassNode(cn, cw.toByteArray());
DiskWriter.replaceFile(output.getAbsolutePath(), contents, false);
} catch (Exception e) {
BytecodeViewer.handleException(e);
}
}
}
System.out.println("Finished."); System.out.println("Finished.");
System.out.println("Bytecode Viewer " + VERSION + " [CLI] - Created by @Konloch - https://bytecodeviewer.com"); System.out.println("Bytecode Viewer " + VERSION + " [CLI] - Created by @Konloch - https://bytecodeviewer.com");

View file

@ -1,16 +1,6 @@
package the.bytecode.club.bytecodeviewer.decompilers; package the.bytecode.club.bytecodeviewer.decompilers;
import the.bytecode.club.bytecodeviewer.decompilers.impl.ASMTextifierDisassembler; import the.bytecode.club.bytecodeviewer.decompilers.impl.*;
import the.bytecode.club.bytecodeviewer.decompilers.impl.BytecodeDisassembler;
import the.bytecode.club.bytecodeviewer.decompilers.impl.CFRDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.impl.FernFlowerDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.impl.JADXDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.impl.JDGUIDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.impl.JavapDisassembler;
import the.bytecode.club.bytecodeviewer.decompilers.impl.KrakatauDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.impl.KrakatauDisassembler;
import the.bytecode.club.bytecodeviewer.decompilers.impl.ProcyonDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.impl.SmaliDisassembler;
/*************************************************************************** /***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
@ -51,6 +41,7 @@ public enum Decompiler
JD_DECOMPILER("JD-GUI Decompiler", "jdgui", new JDGUIDecompiler()), JD_DECOMPILER("JD-GUI Decompiler", "jdgui", new JDGUIDecompiler()),
JADX_DECOMPILER("JADX Decompiler", "jadx", new JADXDecompiler()), JADX_DECOMPILER("JADX Decompiler", "jadx", new JADXDecompiler()),
ASM_TEXTIFY_DISASSEMBLER("ASM Disassembler", "asm", new ASMTextifierDisassembler()), ASM_TEXTIFY_DISASSEMBLER("ASM Disassembler", "asm", new ASMTextifierDisassembler()),
ASMIFIER_DECOMPILER("ASMifier Generator", "asmifier", new ASMifierGenerator()),
JAVAP_DISASSEMBLER("Javap Disassembler", "javap", new JavapDisassembler()), JAVAP_DISASSEMBLER("Javap Disassembler", "javap", new JavapDisassembler()),
; ;

View file

@ -0,0 +1,47 @@
package the.bytecode.club.bytecodeviewer.decompilers.impl;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.util.ASMifier;
import org.objectweb.asm.util.Textifier;
import org.objectweb.asm.util.TraceClassVisitor;
import the.bytecode.club.bytecodeviewer.decompilers.InternalDecompiler;
import java.io.PrintWriter;
import java.io.StringWriter;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
* Objectweb ASMifier output
*
* @author Nick Botticelli
*/
public class ASMifierGenerator extends InternalDecompiler
{
@Override
public String decompileClassNode(ClassNode cn, byte[] b) {
StringWriter writer = new StringWriter();
cn.accept(new TraceClassVisitor(null, new ASMifier(), new PrintWriter(writer)));
return writer.toString();
}
@Override
public void decompileToZip(String sourceJar, String zipName) {
}
}

View file

@ -11,10 +11,7 @@ import the.bytecode.club.bytecodeviewer.translation.TranslatedComponents;
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJCheckBoxMenuItem; import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJCheckBoxMenuItem;
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJRadioButtonMenuItem; import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJRadioButtonMenuItem;
import static the.bytecode.club.bytecodeviewer.gui.components.DecompilerViewComponent.DecompilerComponentType.BYTECODE; import static the.bytecode.club.bytecodeviewer.gui.components.DecompilerViewComponent.DecompilerComponentType.*;
import static the.bytecode.club.bytecodeviewer.gui.components.DecompilerViewComponent.DecompilerComponentType.BYTECODE_NON_EDITABLE;
import static the.bytecode.club.bytecodeviewer.gui.components.DecompilerViewComponent.DecompilerComponentType.JAVA;
import static the.bytecode.club.bytecodeviewer.gui.components.DecompilerViewComponent.DecompilerComponentType.JAVA_AND_BYTECODE;
/*************************************************************************** /***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
@ -63,12 +60,12 @@ public class DecompilerViewComponent
private void createMenu() private void createMenu()
{ {
if(type == JAVA || type == JAVA_AND_BYTECODE) if(type == JAVA || type == JAVA_NON_EDITABLE || type == JAVA_AND_BYTECODE)
menu.add(java); menu.add(java);
if(type == BYTECODE || type == JAVA_AND_BYTECODE || type == BYTECODE_NON_EDITABLE) if(type == BYTECODE || type == JAVA_AND_BYTECODE || type == BYTECODE_NON_EDITABLE)
menu.add(bytecode); menu.add(bytecode);
if(type != BYTECODE_NON_EDITABLE) if(type != JAVA_NON_EDITABLE && type != BYTECODE_NON_EDITABLE)
{ {
menu.add(new JSeparator()); menu.add(new JSeparator());
menu.add(editable); menu.add(editable);
@ -79,7 +76,7 @@ public class DecompilerViewComponent
public void addToGroup(ButtonGroup group) public void addToGroup(ButtonGroup group)
{ {
if(type == JAVA || type == JAVA_AND_BYTECODE) if(type == JAVA || type == JAVA_NON_EDITABLE || type == JAVA_AND_BYTECODE)
group.add(java); group.add(java);
if(type == BYTECODE || type == JAVA_AND_BYTECODE || type == BYTECODE_NON_EDITABLE) if(type == BYTECODE || type == JAVA_AND_BYTECODE || type == BYTECODE_NON_EDITABLE)
group.add(bytecode); group.add(bytecode);
@ -118,6 +115,7 @@ public class DecompilerViewComponent
public enum DecompilerComponentType public enum DecompilerComponentType
{ {
JAVA, JAVA,
JAVA_NON_EDITABLE,
BYTECODE, BYTECODE,
BYTECODE_NON_EDITABLE, BYTECODE_NON_EDITABLE,
JAVA_AND_BYTECODE JAVA_AND_BYTECODE

View file

@ -18,10 +18,7 @@ import the.bytecode.club.bytecodeviewer.translation.TranslatedComponents;
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJMenu; import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJMenu;
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJRadioButtonMenuItem; import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJRadioButtonMenuItem;
import static the.bytecode.club.bytecodeviewer.gui.components.DecompilerViewComponent.DecompilerComponentType.BYTECODE; import static the.bytecode.club.bytecodeviewer.gui.components.DecompilerViewComponent.DecompilerComponentType.*;
import static the.bytecode.club.bytecodeviewer.gui.components.DecompilerViewComponent.DecompilerComponentType.BYTECODE_NON_EDITABLE;
import static the.bytecode.club.bytecodeviewer.gui.components.DecompilerViewComponent.DecompilerComponentType.JAVA;
import static the.bytecode.club.bytecodeviewer.gui.components.DecompilerViewComponent.DecompilerComponentType.JAVA_AND_BYTECODE;
/*************************************************************************** /***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
@ -61,12 +58,13 @@ public class DecompilerSelectionPane
private final DecompilerViewComponent smali = new DecompilerViewComponent("Smali", BYTECODE, Decompiler.SMALI_DISASSEMBLER); private final DecompilerViewComponent smali = new DecompilerViewComponent("Smali", BYTECODE, Decompiler.SMALI_DISASSEMBLER);
private final DecompilerViewComponent bytecode = new DecompilerViewComponent("Bytecode", BYTECODE_NON_EDITABLE, Decompiler.BYTECODE_DISASSEMBLER); private final DecompilerViewComponent bytecode = new DecompilerViewComponent("Bytecode", BYTECODE_NON_EDITABLE, Decompiler.BYTECODE_DISASSEMBLER);
private final DecompilerViewComponent asmTextify = new DecompilerViewComponent("ASM Textify", BYTECODE_NON_EDITABLE, Decompiler.ASM_TEXTIFY_DISASSEMBLER); private final DecompilerViewComponent asmTextify = new DecompilerViewComponent("ASM Textify", BYTECODE_NON_EDITABLE, Decompiler.ASM_TEXTIFY_DISASSEMBLER);
private final DecompilerViewComponent asmifier = new DecompilerViewComponent("ASMifier", JAVA_NON_EDITABLE, Decompiler.ASMIFIER_DECOMPILER);
private final DecompilerViewComponent javap = new DecompilerViewComponent("Javap", BYTECODE_NON_EDITABLE, Decompiler.JAVAP_DISASSEMBLER); private final DecompilerViewComponent javap = new DecompilerViewComponent("Javap", BYTECODE_NON_EDITABLE, Decompiler.JAVAP_DISASSEMBLER);
//TODO when adding new decompilers insert the DecompilerViewComponent object into here //TODO when adding new decompilers insert the DecompilerViewComponent object into here
// also in the group, then finally the build menu // also in the group, then finally the build menu
public List<DecompilerViewComponent> components = new ArrayList<>(Arrays.asList( public List<DecompilerViewComponent> components = new ArrayList<>(Arrays.asList(
procyon, CFR, JADX, JD, fern, krakatau, smali, bytecode, asmTextify, javap)); procyon, CFR, JADX, JD, fern, krakatau, smali, bytecode, asmTextify, asmifier, javap));
public DecompilerSelectionPane(int paneID) public DecompilerSelectionPane(int paneID)
{ {
@ -159,13 +157,16 @@ public class DecompilerSelectionPane
menu.add(bytecode.getMenu()); menu.add(bytecode.getMenu());
menu.add(javap.getMenu()); menu.add(javap.getMenu());
menu.add(asmTextify.getMenu()); menu.add(asmTextify.getMenu());
menu.add(asmifier.getMenu());
menu.add(new JSeparator()); menu.add(new JSeparator());
menu.add(hexcode); menu.add(hexcode);
} }
public Decompiler getSelectedDecompiler() public Decompiler getSelectedDecompiler()
{ {
return Decompiler.valueOf(group.getSelection().getActionCommand()); javax.swing.ButtonModel selection = group.getSelection();
String actionCommand = selection.getActionCommand();
return Decompiler.valueOf(actionCommand);
} }
public void setSelectedDecompiler(Decompiler decompiler) public void setSelectedDecompiler(Decompiler decompiler)

View file

@ -94,6 +94,7 @@ public enum TranslatedComponents
BYTECODE, BYTECODE,
HEXCODE, HEXCODE,
ASM_TEXTIFY, ASM_TEXTIFY,
ASMIFIER,
SETTINGS, SETTINGS,
COMPILE_ON_SAVE, COMPILE_ON_SAVE,

View file

@ -54,6 +54,7 @@ public enum TranslatedStrings
HEXCODE, HEXCODE,
BYTECODE, BYTECODE,
ASM_TEXTIFY, ASM_TEXTIFY,
ASMIFIER,
ERROR, ERROR,
DISASSEMBLER, DISASSEMBLER,
RESULTS, RESULTS,

View file

@ -96,6 +96,7 @@
"HEXCODE": "Hexcode", "HEXCODE": "Hexcode",
"BYTECODE": "Bytecode", "BYTECODE": "Bytecode",
"ASM_TEXTIFY": "ASM Textify", "ASM_TEXTIFY": "ASM Textify",
"ASMIFIER": "ASMifier",
"BYTECODE_DECOMPILER": "Bytecode Decompiler", "BYTECODE_DECOMPILER": "Bytecode Decompiler",
"DEBUG_HELPERS": "Debug Helpers", "DEBUG_HELPERS": "Debug Helpers",