Merge remote-tracking branch 'origin/master'

This commit is contained in:
Nico Mexis 2022-01-23 21:50:01 +01:00
commit ece284c95b
No known key found for this signature in database
GPG key ID: 27D6E17CE092AB78
19 changed files with 210 additions and 302 deletions

View file

@ -3,6 +3,7 @@
Bytecode Viewer - a lightweight user-friendly Java/Android Bytecode Viewer, Decompiler & More.
#### New Features
* Patched [CVE-2022-21675](https://github.com/Konloch/bytecode-viewer/security/advisories/GHSA-3wq9-j4fc-4wmc) (Make sure to upgrade to v2.11.X)
* Dark mode with multiple themes
* Translated into over 30 languages including: Arabic, German, Japanese, Mandarin, Russian, Spanish
* Plugin Writer - create and edit external plugins from within BCV
@ -16,10 +17,6 @@ Bytecode Viewer - a lightweight user-friendly Java/Android Bytecode Viewer, Deco
* Added support to Java files compiled using JDK > 13
* Migrated to Maven
#### v2.10.x Notes
* The rewrite/refactoring process is currently ongoing so please report any bugs you find
* If you're encountering any issues try using [v2.9.22](https://github.com/Konloch/bytecode-viewer/releases/tag/v2.9.22)
#### Links
* [BCV Discord](https://discord.gg/aexsYpfMEf)
* [Website](https://bytecodeviewer.com)

View file

@ -1,13 +0,0 @@
import org.objectweb.asm.tree.ClassNode
import the.bytecode.club.bytecodeviewer.api.*
class Skeleton extends Plugin {
@Override
void execute(List<ClassNode> classNodesList) {
PluginConsole gui = new PluginConsole("Skeleton")
gui.setVisible(true)
gui.appendText("executed skeleton")
}
}

View file

@ -1,6 +0,0 @@
function execute(classNodeList) {
var PluginConsole = Java.type("the.bytecode.club.bytecodeviewer.api.PluginConsole");
var gui = new PluginConsole("Skeleton");
gui.setVisible(true);
gui.appendText("executed skeleton");
}

View file

@ -1,48 +0,0 @@
import java.lang.reflect.Field;
import java.util.List;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import the.bytecode.club.bytecodeviewer.api.*;
import the.bytecode.club.bytecodeviewer.gui.components.MultipleChoiceDialog;
import static the.bytecode.club.bytecodeviewer.Constants.nl;
/**
* This is an example of a string decrypter plugin
*/
public class ExampleStringDecrypter extends Plugin {
@Override
public void execute(List<ClassNode> classNodesList) {
PluginConsole gui = new PluginConsole("Example String Decrypter");
MultipleChoiceDialog dialog = new MultipleChoiceDialog("Bytecode Viewer - WARNING",
"WARNING: This will load the classes into the JVM and execute the initialize function"
+ nl + "for each class. IF THE FILE YOU'RE LOADING IS MALICIOUS, DO NOT CONTINUE.",
new String[]{"Continue", "Cancel"});
if (dialog.promptChoice() == 0) {
for (ClassNode cn : classNodesList) {
BCV.getClassNodeLoader().addClass(cn);
for (Object o : cn.fields.toArray()) {
FieldNode f = (FieldNode) o;
if (f.name.equals("z")) {// && f.desc.equals("([Ljava/lang/String;)V")) {
try {
for (Field f2 : BCV.getClassNodeLoader().nodeToClass(cn).getFields()) {
String s = (String) f2.get(null);
if (s != null && !s.isEmpty())
gui.appendText(cn + ":" + s);
}
} catch (Exception ignored) {
}
}
}
}
gui.setVisible(true);
}
}
}

View file

@ -10,13 +10,15 @@ import java.lang.reflect.Field
import static the.bytecode.club.bytecodeviewer.Constants.nl
/**
* This is an example of a string decrypter plugin
*/
** This is an example of a String Decrypter Groovy Plugin for BCV.
**
** @author [Your-Name-Goes-Here]
**/
class ExampleStringDecrypter extends Plugin {
@Override
void execute(List<ClassNode> classNodesList) {
PluginConsole gui = new PluginConsole("Example String Decrypter")
PluginConsole gui = new PluginConsole("Example String Decrypter Groovy Edition")
MultipleChoiceDialog dialog = new MultipleChoiceDialog("Bytecode Viewer - WARNING",
"WARNING: This will load the classes into the JVM and execute the initialize function"

View file

@ -0,0 +1,18 @@
import org.objectweb.asm.tree.ClassNode
import the.bytecode.club.bytecodeviewer.api.*
/**
** This is a skeleton template for BCV's Groovy Plugin System
**
** @author [Your Name Goes Here]
**/
class Skeleton extends Plugin {
@Override
void execute(List<ClassNode> classNodesList) {
PluginConsole gui = new PluginConsole("Skeleton Title")
gui.setVisible(true)
gui.appendText("executed skeleton example")
}
}

View file

@ -0,0 +1,68 @@
import java.lang.reflect.Field;
import java.util.List;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import the.bytecode.club.bytecodeviewer.api.*;
import the.bytecode.club.bytecodeviewer.gui.components.MultipleChoiceDialog;
import static the.bytecode.club.bytecodeviewer.Constants.nl;
/**
** This is an example of a String Decrypter Java Plugin for BCV.
**
** @author [Your-Name-Goes-Here]
**/
public class ExampleStringDecrypter extends Plugin {
@Override
public void execute(List<ClassNode> classNodesList) {
PluginConsole gui = new PluginConsole("Example String Decrypter Java Edition");
MultipleChoiceDialog dialog = new MultipleChoiceDialog("Bytecode Viewer - WARNING",
"WARNING: This will load the classes into the JVM and execute the initialize function"
+ nl + "for each class. IF THE FILE YOU'RE LOADING IS MALICIOUS, DO NOT CONTINUE.",
new String[]{"Continue", "Cancel"});
if (dialog.promptChoice() == 0) {
boolean needsWarning = false;
for (ClassNode cn : classNodesList) {
try {
//load the class node into the classloader
BCV.getClassNodeLoader().addClass(cn);
for (Object o : cn.fields.toArray()) {
FieldNode f = (FieldNode) o;
//if the class contains the field z, get the class object from the class node
//then print out the value of the fields inside the class
//if the strings get decrypted on init, this allows you to dump the current values
if (f.name.equals("z")) {
try {
for (Field f2 : BCV.getClassNodeLoader().nodeToClass(cn).getFields()) {
String s = (String) f2.get(null);
if (s != null && !s.isEmpty())
gui.appendText(cn + ":" + s);
}
} catch (Exception ignored) {
}
}
}
} catch (Exception e) {
gui.appendText("Failed loading class " + cn.name);
e.printStackTrace();
needsWarning = true;
}
}
if (needsWarning) {
BytecodeViewer.showMessage("Some classes failed to decrypt, if you'd like to decrypt all of them\n"
+ "makes sure you include ALL the libraries it requires.");
}
gui.setVisible(true);
}
}
}

View file

@ -2,13 +2,18 @@ import java.util.List;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.api.*;
/**
** This is a skeleton template for BCV's Java Plugin System
**
** @author [Your Name Goes Here]
**/
public class Skeleton extends Plugin {
@Override
public void execute(List<ClassNode> classNodesList) {
PluginConsole gui = new PluginConsole("Skeleton");
PluginConsole gui = new PluginConsole("Skeleton Title");
gui.setVisible(true);
gui.appendText("executed skeleton");
gui.appendText("executed skeleton example");
}
}
}

View file

@ -18,10 +18,13 @@ import the.bytecode.club.bytecodeviewer.decompilers.impl.FernFlowerDecompiler;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ResourceViewer;
/**
* @author jowasp
*/
** This is an Xposed Generator Plugin, used to aid Reverse-Engineering.
**
** @author jowasp
**/
public class XposedGenerator extends Plugin {
//PRIVATE
private static final List<String> methodsNames = new ArrayList<>();
private static final List<String> cleanMethodsNames = new ArrayList<>();
private static String foundPckg;
@ -40,7 +43,6 @@ public class XposedGenerator extends Plugin {
}
String className = viewer.getName();
//String containerName = viewer.getName();
ClassNode classnode = BytecodeViewer.getCurrentlyOpenedClassNode();
//Call XposedGenerator class
@ -64,7 +66,6 @@ public class XposedGenerator extends Plugin {
//Set results of parsed methods into a list
List<String> methodsExtracted = ProcessContentExtractedClass(decomp);
String packgExtracted = ProcessContentExtractedPackage(decomp);
System.out.println("PACKAGE NAME: " + packgExtracted);
//Get a clean list
List<String> cleanMethods;
@ -114,16 +115,16 @@ public class XposedGenerator extends Plugin {
public static void WriteXposedModule(String functionToHook, String packageName, String classToHook,
String template) {
System.out.println("TEMPLATE: " + template);
if (template != null && !template.equals("Empty")) {
try {
//TODO: Prompt save dialog
File file = new File("./XposedClassTest.java");
// if file doesn't exist, then create it
if (!file.exists()) {
if (!file.exists())
file.createNewFile();
}
//Extract the package name only
String packageNameOnly = packageName.substring(8, packageName.length() - 2).trim();
String classToHookNameOnly = classToHook;
@ -132,18 +133,14 @@ public class XposedGenerator extends Plugin {
String[] classClean = classToHookNameOnly.split("/");
String[] functionSplitValues = functionToHook.split("\\s+");
//select
String onlyClass = classClean[classClean.length - 1];
//String onlyFunctionParateses = functionSplitValues[functionSplitValues.length-2];
String onlyFunction = CleanUpFunction(functionSplitValues);
//String functionToHookOnly = "dummy function";
System.out.println(onlyClass);
System.out.println(packageNameOnly);
//Write Xposed Class
String XposedClassText =
"package androidpentesting.com.xposedmodule;" + "\r\n" +
String XposedClassText = "package androidpentesting.com.xposedmodule;" + "\r\n" +
"import de.robv.android.xposed.IXposedHookLoadPackage;" + "\r\n" +
"\r\n" +
"import de.robv.android.xposed.XC_MethodHook;" + "\r\n" +
@ -177,7 +174,6 @@ public class XposedGenerator extends Plugin {
bw.write("\r\n");
bw.close();
System.out.println("Done");
JOptionPane.showMessageDialog(null, "Xposed Module Generated");
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "Error" + e);
@ -193,19 +189,16 @@ public class XposedGenerator extends Plugin {
try {
scanner = new Scanner(contentFile);
//@TODO : Improve patterns to match other excepts 'public'
String regexclass = "public";
//String regexPkg = "package";
Pattern pattern = Pattern.compile(regexclass, Pattern.CASE_INSENSITIVE);
//Pattern patternVoid = Pattern.compile(regexVoid , Pattern.CASE_INSENSITIVE);
// Pattern patternPkg = Pattern.compile(regexPkg , Pattern.CASE_INSENSITIVE);
//scanner.useDelimiter(";");
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
// process the line
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
if (matcher.group() != null) {
System.out.println("find() found the pattern \"" + quote(line.trim()));
System.out.println("Function: " + CleanUpFunction(line.trim().split("\\s+")));
@ -213,9 +206,7 @@ public class XposedGenerator extends Plugin {
} else {
methodsNames.add("No methods found");
}
}
}
if (methodsNames.isEmpty()) {
@ -237,11 +228,9 @@ public class XposedGenerator extends Plugin {
if (!m.contains("extends") && (!m.contains("implements") && (m.contains("(")))) {
cleanMethodsNames.add(m);
}
}
return cleanMethodsNames;
}
private static String CleanUpFunction(String[] rawFunction) {
@ -254,7 +243,6 @@ public class XposedGenerator extends Plugin {
}
return onlyFunc;
}
private static String ProcessContentExtractedPackage(String contentFile) {
@ -264,20 +252,19 @@ public class XposedGenerator extends Plugin {
String regexPkg = "package";
Pattern patternPkg = Pattern.compile(regexPkg, Pattern.CASE_INSENSITIVE);
String line = scanner.nextLine();
// process the line
Matcher matcher = patternPkg.matcher(line);
while (matcher.find()) {
if (matcher.group() != null) {
System.out.println("find() found the pattern \"" + quote(line.trim()));
foundPckg = quote(line.trim());
} else {
foundPckg = "";
}
}
try
//
{
if (foundPckg == null || foundPckg.isEmpty())
foundPckg = "No Package Found";
@ -296,8 +283,8 @@ public class XposedGenerator extends Plugin {
if (scanner != null)
scanner.close();
}
return foundPckg;
}
private static String quote(String aText) {

View file

@ -1,10 +1,14 @@
/**
* This is an example plugin
*/
** An example BCV Javascript Plugin.
** This is used to display all of loaded classnodes that have been imported into BCV.
**
** @author [Your-Name-Goes-Here]
**/
var PluginConsole = Java.type("the.bytecode.club.bytecodeviewer.api.PluginConsole");
var gui = new PluginConsole("Example Plugin Print Loaded Classes");
var gui = new PluginConsole("Example Plugin Print Loaded Classes Javascript Edition");
function execute(classNodeList) {
for (index = 0; index < classNodeList.length; index++) {
@ -13,4 +17,4 @@ function execute(classNodeList) {
}
gui.setVisible(true);
}
}

View file

@ -1,6 +1,9 @@
/**
* This is an example of a string decrypter plugin
*/
** This is an example of a String Decrypter Javascript Plugin for BCV.
**
** @author [Your-Name-Goes-Here]
**/
var PluginConsole = Java.type("the.bytecode.club.bytecodeviewer.api.PluginConsole");
var MultipleChoiceDialog = Java.type("the.bytecode.club.bytecodeviewer.gui.components.MultipleChoiceDialog")
@ -13,7 +16,7 @@ var dialog = new MultipleChoiceDialog("Bytecode Viewer - WARNING",
var gui;
function execute(classNodeList) {
gui = new PluginConsole("Skeleton");
gui = new PluginConsole("Example String Decrypter Javascript Edition");
if (dialog.promptChoice() == 0) {
var needsWarning = false;
@ -33,7 +36,7 @@ function execute(classNodeList) {
//then print out the value of the fields inside the class
//if the strings get decrypted on init, this allows you to dump the current values
if (field.name.equals("z")) {// && f.desc.equals("([Ljava/lang/String;)V")) {
if (field.name.equals("z")) {
try {
var loadedClass = BytecodeViewer.getClassNodeLoader().nodeToClass(cn);
var reflectedFields = loadedClass.getFields();
@ -45,7 +48,7 @@ function execute(classNodeList) {
if (s != null && !s.empty())
gui.appendText(cn + "->" + s);
}
} catch (e) {
} catch (ignored) {
}
}
}

View file

@ -0,0 +1,13 @@
/**
** This is a skeleton template for BCV's Javascript Plugin System
**
** @author [Your Name Goes Here]
**/
function execute(classNodeList) {
var PluginConsole = Java.type("the.bytecode.club.bytecodeviewer.api.PluginConsole");
var gui = new PluginConsole("Skeleton Title");
gui.setVisible(true);
gui.appendText("executed skeleton example");
}

View file

@ -5,9 +5,14 @@ from java.lang import Boolean
from java.util import ArrayList
from org.objectweb.asm.tree import ClassNode
class skeleton(Plugin):
#
# This is a skeleton template for BCV's Ruby Plugin System
#
# @author [Your Name Goes Here]
#
def execute(classNodeList, poop): #for some reason it requires a second arg
gui = PluginConsole("Skeleton")
class skeleton(Plugin):
def execute(classNodeList, notUsed): #for some reason it requires a second arg
gui = PluginConsole("Skeleton Title")
gui.setVisible(Boolean.TRUE)
gui.appendText("exceuted skeleton")
gui.appendText("executed skeleton example")

View file

@ -6,10 +6,16 @@ java_import 'java.lang.System'
java_import 'java.util.ArrayList'
java_import 'org.objectweb.asm.tree.ClassNode'
#
# This is a skeleton template for BCV's Ruby Plugin System
#
# @author [Your Name Goes Here]
#
class Skeleton < Plugin
def execute(classNodeList)
gui = PluginConsole.new "Skeleton"
gui = PluginConsole.new "Skeleton Title"
gui.setVisible(true)
gui.appendText("executed skeleton")
gui.appendText("executed skeleton example")
end
end
end

View file

@ -36,7 +36,7 @@
<gson.version>2.8.9</gson.version>
<guava.version>31.0.1-jre</guava.version>
<imgscalr-lib.version>4.2</imgscalr-lib.version>
<jadx.version>1.3.1</jadx.version>
<jadx.version>1.3.2</jadx.version>
<janino.version>3.1.6</janino.version>
<jd-gui.version>1.6.6bcv</jd-gui.version>
<jgraphx.version>3.4.1.3</jgraphx.version>

View file

@ -37,7 +37,8 @@ public class PluginConsole extends SystemConsole
public PluginConsole(String pluginName)
{
super(Configuration.pluginConsoleAsNewTab ? (pluginName + " Output") : (TranslatedStrings.PLUGIN_CONSOLE_TITLE + " - " + pluginName));
super(Configuration.pluginConsoleAsNewTab ? (pluginName + " Output")
: (TranslatedStrings.PLUGIN_CONSOLE_TITLE + " - " + pluginName));
}
@Override

View file

@ -156,7 +156,8 @@ public final class PluginManager
}
final String name = activePlugin.activeContainer == null
? "#" + (activeTabbedException.getTabbedPane().getTabCount() + 1) : activePlugin.activeContainer.name;
? "#" + (activeTabbedException.getTabbedPane().getTabCount() + 1)
: activePlugin.activeContainer.name;
ExceptionUI existingUI = exceptionTabs.get(name);
@ -201,7 +202,8 @@ public final class PluginManager
console.setConsoleID(id);
final String name = (activePlugin == null || activePlugin.activeContainer == null)
? ("#" + (activeTabbedConsole.getTabbedPane().getTabCount() + 1)) : activePlugin.activeContainer.name;
? ("#" + (activeTabbedConsole.getTabbedPane().getTabCount() + 1))
: activePlugin.activeContainer.name;
activeTabbedConsole.addConsole(console.getComponent(0), name);
}

View file

@ -1,166 +0,0 @@
<html lang="en">
<h2>About</h2>
Bytecode Viewer (BCV) is an easy to use Java & Android Reverse Engineering Suite!<br>
BCV is designed to be extremely user and beginner friendly, because of this almost everything is accessible through an interface, settings, tools, etc.
<br><br>To start drag your Jar/APK/Class file into the resource list.
<h2>How To - Java Importing</h2>
<pre>
Java resources have no special preprocessing before you open them.
Import your Jar/Class/WAR/EAR file via the File>Open menu in Bytecode Viewer. (CTRL + O)
</pre>
<h2>How To - Android Importing</h2>
<pre>
Android resources have three options for preprocessing:
1). Decode Resources
2). Enjarify
3). Dex2Jar (d2j)
1). Decode Resources will run APKTool to decode any packed android-specific resources
2). Enjarify will convert the dalvik specific bytecode to java bytecode
3). Dex2Jar will convert the dalvik specific bytecode to java bytecode
Import your APK/WAPK/DEX file via the File>Open menu in Bytecode Viewer. (CTRL + O)
</pre>
<h2>How To - File Navigation</h2>
<pre>
Using the resource list (it should say "Files" on the title bar) you can select all of the resources added into BCV.
Any archive will opened, to select a resource click + button for each folder.
Using the search pane inside of the resource list you can search by file name and extension.
For case-sensitivity enable the checkbox labeled "Exact".
</pre>
<h2>Settings</h2>
<ul>
<li>Fat Jar: {fatJar}</li>
<li>Java: {java}</li>
<li>Javac: {javac}</li>
<li>Python 2.7 (or PyPy): {python}</li>
<li>Python 3.X (or PyPy): {python3}</li>
<li>RT.jar: {rt}</li>
<li>Optional Lib: {lib}</li>
<li>BCV Dir: {bcvDir}</li>
<li>Temp Dir: {tempDir}</li>
<li>Krakatau Dir: {krakatauDir}</li>
<li>Enjarify Dir: {enjarifyDir}</li>
<li>BCV Krakatau version: v{krakatauVersion}</li>
<li>BCV Enjarify version: v{enjarifyVersion}</li>
</ul>
<h2>Command Line Interface (CLI)</h2>
<ul>
<li> -help Displays the help menu</li>
<li> -list Displays the available decompilers</li>
<li> -decompiler [decompiler] Selects the decompiler, procyon by default</li>
<li> -i [input file] Selects the input file (Jar, Class, APK, ZIP, DEX all work automatically)</li>
<li> -o [output file] Selects the output file (Java or Java-Bytecode)</li>
<li> -t [target classname] Must either be the fully qualified classname or "all" to decompile all as zip</li>
<li> -nowait Doesn't wait for the user to read the CLI messages</li>
</ul>
<h2>File</h2>
<ul>
<li>Add (Ctrl + O) - If you add a jar/zip BCV will unzip it, if you add an APK or DEX file, BCV will run dex2jar
then run the jar input process.
</li>
<li>Reopen Recent File (Ctrl + L) - Reopens your last recent opened file.</li>
<li>New Workspace (Ctrl + N) - It clears the opened jars/resources.</li>
<li>Run (Ctrl + R) - Runs the classfiles you've loaded into BCV in a secure sandboxed JVM instance that you can
fully debug.
</li>
<li>Compile (Ctrl + T) - Tries to compile all of the editable panes you've selected, if it's Java it'll compile with
Ranino. Krakatau and *Smali use their own assemblers.
</li>
<li>Save As Jar - Export the class files and loaded resources as a runnable Jar file.</li>
<li>Save As DEX - Run jar2dex and export the Classfiles as DEX.</li>
<li>Save Files As - Save all the Classfiles and resources as a zip.</li>
<li>Save Java File As - Save the currently opened decompiled Classfile.</li>
<li>Save Java Files As - Save all of the decompiled Classfiles as a zip.</li>
<li>Recent Files - Last 25 files/directories you've opened with BCV.</li>
<li>About - A small information window about BCV.</li>
<li>Exit - Closes BCV.</li>
</ul>
<h2>View Panes</h2>
<ul>
<li>Editable - Defines if that viewing pane will be editable.</li>
<li>None - Nothing will be displayed.</li>
<li>Procyon - Decompiles with Procyon decompiler.</li>
<li>CFR - Decompilers with CFR decompiler.</li>
<li>FernFlower - Decompiles with FernFlower decompiler.</li>
<li>JD-GUI - Decompiles with JD-GUI decompiler.</li>
<li>Krakatau Java - Decompiles with Krakatau decompiler.</li>
<li>Krakatau Bytecode - Disassembles with Krakatau disassembler.</li>
<li>Smali - Disassembles with Smali.</li>
<li>Bytecode - Decompiles the Bytecode via CFIDE. Not Editable.</li>
<li>Hexcode - Shows the classfile in a hex viewer. Not Editable.</li>
</ul>
<h2>Settings</h2>
<ul>
<li>Compile On Save - If selected whenever you do one of the File>Save * functions it will try to compile before it
saves.
</li>
<li>Compile On Refresh - If selected whenever you press refresh it compile before it reloads the resource/class.
</li>
<li>Update Check - If selected it queries https://github.com/Konloch/bytecode-viewer to ensure you've got the latest
version.
</li>
<li>Refresh On View Change - If selected whenever you change an option in the View Panes it will refresh the
currently opened resources/class.
</li>
<li>Decode APK Resources - If selected whenever you add an APK, it will first run APKTool.jar to decode the
resources.
</li>
<li>Set Python 2.7 Executable - Set the Python 2.7 executable if you want Krakatau decompiler/disassembler/assembler
to work.
</li>
<li>Set JRE RT Library - Set the JRE RT library for Krakatau decompiler.</li>
</ul>
<h2>Plugins</h2>
<ul>
<li>Open Plugin - Open a .java plugin created for BCV.</li>
<li>Recent Plugins - Last 25 plugins you've opened with BCV.</li>
<li>Code Sequence Diagram - Builds a crude code sequence diagram for the classfile that's currently opened.</li>
<li>Malicious Code Scanner - Allows you to define what to search for, and outputs what it found.</li>
<li>Show Main Methods - Detects and outputs all of the public static void main(String[]) functions.</li>
<li>Show All Strings - Grabs then outputs all of the strings in every classfile.</li>
<li>Replace Strings - Allows you to do a simple permanent .replace on the classfile strings, very useful for URL swapping.</li>
<li>Allatori String Decrypter - Decrypts the Allatori obfuscated/encrypted strings.</li>
<li>ZKM String Decrypter - Decrypts the ZKM obfuscated/encrypted strings.</li>
<li>ZStringArray String Decrypter - Decrypts the ZStringArray obfuscated/encrypted strings.</li>
</ul>
<h2>Code from various projects has been used, including but not limited to</h2>
<ul>
<li>J-RET by WaterWolf</li>
<li>JHexPane by Sam Koivu</li>
<li>RSynaxPane by Robert Futrell</li>
<li>Commons IO by Apache</li>
<li>ASM by OW2</li>
<li>FernFlower by Stiver</li>
<li>Procyon by Mstrobel</li>
<li>CFR by Lee Benfield</li>
<li>CFIDE by Bibl</li>
<li>Smali by JesusFreke</li>
<li>Dex2Jar by pxb1988</li>
<li>Krakatau by Storyyeller</li>
<li>JD-GUI + JD-Core by The Java-Decompiler Team</li>
<li>Enjarify by Storyyeller</li>
</ul>
<h2>Notes</h2>
<ul>
<li>If BCV fails to boot simply append -clean as an argument to clean the lib directory.</li>
<li>Relax and take notes</li>
<li>BCV was created out of love for Java Reverse engineering.</li>
<li>You can join our Discord server at <a href="https://discord.gg/aexsYpfMEf">https://discord.gg/aexsYpfMEf</a>!</li>
<li>Bytecode Viewer's Homepage is <a href="https://bytecodeviewer.com">https://bytecodeviewer.com</a></li>
</ul>
</html>

View file

@ -1,25 +1,55 @@
<html lang="en">
<h2>About</h2>
Bytecode Viewer (BCV) was designed to be extremely user and beginner friendly, because of this almost everything
is accessible through an interface, settings, tools, etc.
Bytecode Viewer (BCV) is an easy-to-use Java & Android Reverse Engineering Suite!<br>
BCV is designed to be extremely user and beginner-friendly, this means everything is accessible through an interface such as settings, tools, etc.
<br><br>To start drag your Jar/APK/Class file into the resource list.
<br><br>To start, simply drag your Jar/APK/Class file into the resource list.
<h2>How To - Java Importing</h2>
<pre>
Java resources have no special preprocessing before you open them.
Import your Jar/Class/WAR/EAR file via the File>Open menu in Bytecode Viewer. (CTRL + O)
</pre>
<h2>How To - Android Importing</h2>
<pre>
Android resources have three options for preprocessing:
1). Decode Resources
2). Enjarify
3). Dex2Jar (d2j)
1). Decode Resources will run APKTool to decode any packed android-specific resources
2). Enjarify will convert the Android Dalvik Bytecode to Java Bytecode
3). Dex2Jar will convert the Android Dalvik Bytecode to Java Bytecode
Import your APK/WAPK/DEX file via the File>Open menu in Bytecode Viewer. (CTRL + O)
</pre>
<h2>How To - File Navigation</h2>
<pre>
To use the resource list - (Note: it will say "Files" on the title bar) - you can select all of the resources added into BCV.
Any archive (Zip, Jar, ETC.) will opened.
To select a resource click + button for each folder.
Using the search pane inside of the resource list you can search by file name and extension.
For case-sensitivity enable the checkbox labeled "Exact".
</pre>
<h2>Settings</h2>
<ul>
<li>Fat Jar: {fatJar}</li>
<li>Java: {java}</li>
<li>Javac: {javac}</li>
<li>BCV Dir: {bcvDir}</li>
<li>Python 2.7 (or PyPy): {python}</li>
<li>Python 3.X (or PyPy): {python3}</li>
<li>RT.jar: {rt}</li>
<li>Optional Lib: {lib}</li>
<li>BCV Krakatau: v{krakatauVersion}</li>
<li>BCV Dir: {bcvDir}</li>
<li>Temp Dir: {tempDir}</li>
<li>Krakatau Dir: {krakatauDir}</li>
<li>BCV Enjarify: v{enjarifyVersion}</li>
<li>Enjarify Dir: {enjarifyDir}</li>
<li>BCV Krakatau version: v{krakatauVersion}</li>
<li>BCV Enjarify version: v{enjarifyVersion}</li>
</ul>
<h2>Command Line Interface (CLI)</h2>
@ -134,4 +164,4 @@ is accessible through an interface, settings, tools, etc.
<li>Bytecode Viewer's Homepage is <a href="https://bytecodeviewer.com">https://bytecodeviewer.com</a></li>
</ul>
</html>
</html>