Merge remote-tracking branch 'origin/master' into fixes
This commit is contained in:
commit
da06975535
20 changed files with 523 additions and 232 deletions
|
@ -97,8 +97,14 @@ Just clone this repo and run ``mvn package``. It's that simple!
|
||||||
|
|
||||||
Open the Maven project (e.g. in IntelliJ, open the ``pom.xml`` as a project file).
|
Open the Maven project (e.g. in IntelliJ, open the ``pom.xml`` as a project file).
|
||||||
|
|
||||||
## Java Heap Space Issues
|
## Java Heap Space Issues (java.lang.OutOfMemoryError)
|
||||||
Start BCV with more RAM, e.g. `java -Xmx3G -jar BCV.jar`
|
Start BCV with more RAM, e.g. `java -Xmx3G -jar BCV.jar`
|
||||||
|
|
||||||
|
## File Permission Issues (java.io.FileNotFoundException)
|
||||||
|
Right click on the jar file, go to Properties, and select Unblock under Security at the bottom of the General tab.
|
||||||
|
|
||||||
|
## APK File Permission Issues (java.io.FileNotFoundException)
|
||||||
|
Run BCV as administrator.
|
||||||
|
|
||||||
#### Are you a Java Reverse Engineer? Do you want to learn?
|
#### Are you a Java Reverse Engineer? Do you want to learn?
|
||||||
Join The Bytecode Club Today! - https://the.bytecode.club
|
Join The Bytecode Club Today! - https://the.bytecode.club
|
||||||
|
|
7
pom.xml
7
pom.xml
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
<groupId>the.bytecode.club</groupId>
|
<groupId>the.bytecode.club</groupId>
|
||||||
<artifactId>bytecodeviewer</artifactId>
|
<artifactId>bytecodeviewer</artifactId>
|
||||||
<version>2.10.14</version>
|
<version>2.11.0</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
|
@ -244,6 +244,11 @@
|
||||||
<artifactId>webp-imageio</artifactId>
|
<artifactId>webp-imageio</artifactId>
|
||||||
<version>0.2.1</version>
|
<version>0.2.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.skuzzle</groupId>
|
||||||
|
<artifactId>semantic-version</artifactId>
|
||||||
|
<version>2.1.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- TODO Re-add for Graal.JS support -->
|
<!-- TODO Re-add for Graal.JS support -->
|
||||||
<!--<dependency>
|
<!--<dependency>
|
||||||
|
|
|
@ -31,6 +31,7 @@ public class HTTPRequest {
|
||||||
private DataOutputStream writer;
|
private DataOutputStream writer;
|
||||||
private HttpURLConnection connection;
|
private HttpURLConnection connection;
|
||||||
private Set<Entry<String, List<String>>> lastConnectionHeaders;
|
private Set<Entry<String, List<String>>> lastConnectionHeaders;
|
||||||
|
private int statusCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new HTTPRequest object
|
* Creates a new HTTPRequest object
|
||||||
|
@ -89,7 +90,12 @@ public class HTTPRequest {
|
||||||
public Set<Entry<String, List<String>>> getLastConnectionHeaders() {
|
public Set<Entry<String, List<String>>> getLastConnectionHeaders() {
|
||||||
return lastConnectionHeaders;
|
return lastConnectionHeaders;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getStatusCode()
|
||||||
|
{
|
||||||
|
return statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* By default follow redirects are enabled
|
* By default follow redirects are enabled
|
||||||
*/
|
*/
|
||||||
|
@ -147,6 +153,7 @@ public class HTTPRequest {
|
||||||
st.add(s);
|
st.add(s);
|
||||||
|
|
||||||
lastConnectionHeaders = connection.getHeaderFields().entrySet();
|
lastConnectionHeaders = connection.getHeaderFields().entrySet();
|
||||||
|
statusCode = connection.getResponseCode();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
cleanup();
|
cleanup();
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -178,6 +185,7 @@ public class HTTPRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
lastConnectionHeaders = connection.getHeaderFields().entrySet();
|
lastConnectionHeaders = connection.getHeaderFields().entrySet();
|
||||||
|
statusCode = connection.getResponseCode();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
cleanup();
|
cleanup();
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -203,6 +211,7 @@ public class HTTPRequest {
|
||||||
s = reader.readLine();
|
s = reader.readLine();
|
||||||
|
|
||||||
lastConnectionHeaders = connection.getHeaderFields().entrySet();
|
lastConnectionHeaders = connection.getHeaderFields().entrySet();
|
||||||
|
statusCode = connection.getResponseCode();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
cleanup();
|
cleanup();
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -232,6 +241,7 @@ public class HTTPRequest {
|
||||||
s = reader.readLine();
|
s = reader.readLine();
|
||||||
|
|
||||||
lastConnectionHeaders = connection.getHeaderFields().entrySet();
|
lastConnectionHeaders = connection.getHeaderFields().entrySet();
|
||||||
|
statusCode = connection.getResponseCode();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
cleanup();
|
cleanup();
|
||||||
throw e;
|
throw e;
|
||||||
|
|
|
@ -16,6 +16,7 @@ import me.konloch.kontainer.io.DiskReader;
|
||||||
import the.bytecode.club.bytecodeviewer.bootloader.Boot;
|
import the.bytecode.club.bytecodeviewer.bootloader.Boot;
|
||||||
import the.bytecode.club.bytecodeviewer.api.BCV;
|
import the.bytecode.club.bytecodeviewer.api.BCV;
|
||||||
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
|
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
|
||||||
|
import the.bytecode.club.bytecodeviewer.bootloader.UpdateCheck;
|
||||||
import the.bytecode.club.bytecodeviewer.gui.MainViewerGUI;
|
import the.bytecode.club.bytecodeviewer.gui.MainViewerGUI;
|
||||||
import the.bytecode.club.bytecodeviewer.gui.components.*;
|
import the.bytecode.club.bytecodeviewer.gui.components.*;
|
||||||
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.TabbedPane;
|
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.TabbedPane;
|
||||||
|
@ -68,12 +69,10 @@ import static the.bytecode.club.bytecodeviewer.Constants.*;
|
||||||
* http://the.bytecode.club
|
* http://the.bytecode.club
|
||||||
*
|
*
|
||||||
* TODO BUGS:
|
* TODO BUGS:
|
||||||
* + Viewing a new resource should unlock the refresh button
|
|
||||||
* + Resource List creates swing lag with large projects
|
* + Resource List creates swing lag with large projects
|
||||||
* + View>Visual Settings>Show Class Methods
|
* + View>Visual Settings>Show Class Methods
|
||||||
* + Spam-clicking the refresh button will cause the swing thread to deadlock (Quickly opening resources used to also do this)
|
* + 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
|
* 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
|
* + Fix classfile searcher
|
||||||
*
|
*
|
||||||
* TODO API BUGS:
|
* TODO API BUGS:
|
||||||
|
@ -147,7 +146,7 @@ public class BytecodeViewer
|
||||||
public static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
public static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
|
||||||
//Threads
|
//Threads
|
||||||
private static final Thread versionChecker = new Thread(new VersionChecker(), "Version Checker");
|
private static final Thread versionChecker = new Thread(new UpdateCheck(), "Version Checker");
|
||||||
private static final Thread pingBack = new Thread(new PingBack(), "Pingback");
|
private static final Thread pingBack = new Thread(new PingBack(), "Pingback");
|
||||||
private static final Thread installFatJar = new Thread(new InstallFatJar(), "Install Fat-Jar");
|
private static final Thread installFatJar = new Thread(new InstallFatJar(), "Install Fat-Jar");
|
||||||
private static final Thread bootCheck = new Thread(new BootCheck(), "Boot Check");
|
private static final Thread bootCheck = new Thread(new BootCheck(), "Boot Check");
|
||||||
|
|
|
@ -45,6 +45,9 @@ public class Constants
|
||||||
//dev mode is just a check for running via IDE
|
//dev mode is just a check for running via IDE
|
||||||
public static boolean DEV_MODE;
|
public static boolean DEV_MODE;
|
||||||
|
|
||||||
|
//if true the version checker will prompt and ask how you would like to proceed
|
||||||
|
public static final boolean FORCE_VERSION_CHECKER_PROMPT = false;
|
||||||
|
|
||||||
public static final String fs = System.getProperty("file.separator");
|
public static final String fs = System.getProperty("file.separator");
|
||||||
public static final String nl = System.getProperty("line.separator");
|
public static final String nl = System.getProperty("line.separator");
|
||||||
|
|
||||||
|
@ -111,6 +114,9 @@ public class Constants
|
||||||
*/
|
*/
|
||||||
public static String getVersion(String mavenVersion)
|
public static String getVersion(String mavenVersion)
|
||||||
{
|
{
|
||||||
|
if(FORCE_VERSION_CHECKER_PROMPT)
|
||||||
|
return "9.9.9";
|
||||||
|
|
||||||
if(mavenVersion == null)
|
if(mavenVersion == null)
|
||||||
{
|
{
|
||||||
DEV_MODE = true;
|
DEV_MODE = true;
|
||||||
|
|
|
@ -0,0 +1,302 @@
|
||||||
|
package the.bytecode.club.bytecodeviewer.bootloader;
|
||||||
|
|
||||||
|
import de.skuzzle.semantic.Version;
|
||||||
|
import me.konloch.kontainer.io.HTTPRequest;
|
||||||
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
|
import the.bytecode.club.bytecodeviewer.Configuration;
|
||||||
|
import the.bytecode.club.bytecodeviewer.api.BCV;
|
||||||
|
import the.bytecode.club.bytecodeviewer.gui.components.FileChooser;
|
||||||
|
import the.bytecode.club.bytecodeviewer.gui.components.MultipleChoiceDialog;
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import static the.bytecode.club.bytecodeviewer.Constants.*;
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* 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/>. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Konloch
|
||||||
|
*/
|
||||||
|
public class UpdateCheck implements Runnable
|
||||||
|
{
|
||||||
|
//just brute force download the url path
|
||||||
|
//one of these works for every single version of BCV
|
||||||
|
public static final String[] remoteGithubReleases = new String[]
|
||||||
|
{
|
||||||
|
//current url scheme since v2.9.12
|
||||||
|
"https://github.com/Konloch/bytecode-viewer/releases/download/v{VERSION}/Bytecode-Viewer-{VERSION}.jar",
|
||||||
|
//for v2.9.10 and v2.9.11
|
||||||
|
"https://github.com/Konloch/bytecode-viewer/releases/download/{VERSION}/Bytecode-Viewer-{VERSION}.jar",
|
||||||
|
//for v2.7.0 to v2.9.8
|
||||||
|
"https://github.com/Konloch/bytecode-viewer/releases/download/v{VERSION}/BytecodeViewer.{VERSION}.zip",
|
||||||
|
//for v2.0 to v2.6.0
|
||||||
|
"https://github.com/Konloch/bytecode-viewer/releases/download/v{VERSION}/BytecodeViewer.{VERSION}.jar",
|
||||||
|
//for v1.1 to v1.5.3
|
||||||
|
"https://github.com/Konloch/bytecode-viewer/releases/download/b{VERSION}/BytecodeViewer.Beta.{VERSION}.jar",
|
||||||
|
//for v1.4
|
||||||
|
"https://github.com/Konloch/bytecode-viewer/releases/download/b.{VERSION}/BytecodeViewer.Beta.{VERSION}.jar",
|
||||||
|
//for v1.0
|
||||||
|
"https://github.com/Konloch/bytecode-viewer/releases/download/B{VERSION}/BytecodeViewer.jar",
|
||||||
|
};
|
||||||
|
|
||||||
|
//a list of all of the released versions of BCV
|
||||||
|
public static final String[] versions = new String[]
|
||||||
|
{
|
||||||
|
"2.11.0",
|
||||||
|
"2.10.14",
|
||||||
|
"2.10.13",
|
||||||
|
"2.10.12",
|
||||||
|
"2.10.11",
|
||||||
|
"2.9.22",
|
||||||
|
"2.9.21",
|
||||||
|
"2.9.20",
|
||||||
|
"2.9.19",
|
||||||
|
"2.9.18",
|
||||||
|
"2.9.17",
|
||||||
|
"2.9.16",
|
||||||
|
"2.9.15",
|
||||||
|
"2.9.14",
|
||||||
|
"2.9.13",
|
||||||
|
"2.9.12",
|
||||||
|
"2.9.11",
|
||||||
|
"2.9.10", //broken due to repo change
|
||||||
|
"2.9.8", //broken due to repo change & zip
|
||||||
|
"2.9.7", //broken due to repo change & zip
|
||||||
|
"2.9.6", //zip
|
||||||
|
"2.9.5", //zip
|
||||||
|
"2.9.4", //zip
|
||||||
|
"2.9.3", //zip
|
||||||
|
"2.9.2", //zip
|
||||||
|
"2.9.1", //zip
|
||||||
|
"2.9.0", //zip
|
||||||
|
"2.8.1", //zip
|
||||||
|
"2.8.0", //zip
|
||||||
|
"2.7.1", //zip
|
||||||
|
"2.7.0", //zip
|
||||||
|
"2.6.0",
|
||||||
|
"2.5.2",
|
||||||
|
"2.5.1",
|
||||||
|
"2.5.0",
|
||||||
|
"2.4.0",
|
||||||
|
"2.3.0",
|
||||||
|
"2.2.1",
|
||||||
|
"2.2.0",
|
||||||
|
"2.1.1",
|
||||||
|
"2.1.0",
|
||||||
|
"2.0.1",
|
||||||
|
"2.0",
|
||||||
|
"1.5.3",
|
||||||
|
"1.5.2",
|
||||||
|
"1.5.1",
|
||||||
|
"1.5",
|
||||||
|
"1.4",
|
||||||
|
"1.3.1",
|
||||||
|
"1.3",
|
||||||
|
"1.2",
|
||||||
|
"1.1",
|
||||||
|
"1.0",
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
HTTPRequest r = new HTTPRequest(new URL("https://raw.githubusercontent.com/Konloch/bytecode-viewer/master/VERSION"));
|
||||||
|
final Version version = Version.parseVersion(r.readSingle());
|
||||||
|
final Version localVersion = Version.parseVersion(VERSION);
|
||||||
|
|
||||||
|
try {
|
||||||
|
//developer version
|
||||||
|
if (!localVersion.isGreaterThan(version))
|
||||||
|
return;
|
||||||
|
} catch (Exception ignored) { }
|
||||||
|
|
||||||
|
MultipleChoiceDialog outdatedDialog = new MultipleChoiceDialog("Bytecode Viewer - Outdated Version",
|
||||||
|
"Your version: " + localVersion + ", latest version: " + version + nl +
|
||||||
|
"What would you like to do?",
|
||||||
|
new String[]{"Open The Download Page", "Download The Updated Jar", "Do Nothing (And Don't Ask Again)"});
|
||||||
|
|
||||||
|
int result = outdatedDialog.promptChoice();
|
||||||
|
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
if (Desktop.isDesktopSupported())
|
||||||
|
Desktop.getDesktop().browse(new URI("https://github.com/Konloch/bytecode-viewer/releases"));
|
||||||
|
else
|
||||||
|
BytecodeViewer.showMessage("Cannot open the page, please manually type it."
|
||||||
|
+ nl + "https://github.com/Konloch/bytecode-viewer/releases");
|
||||||
|
}
|
||||||
|
else if (result == 1)
|
||||||
|
{
|
||||||
|
//TODO move this to after the file extension has been found
|
||||||
|
final File file = promptFileSave("Jar Archives", "jar");
|
||||||
|
|
||||||
|
if(file != null)
|
||||||
|
{
|
||||||
|
Thread downloadThread = new Thread(() ->
|
||||||
|
downloadBCV(version.toString(), file, ()->{}, ()->{}), "Downloader");
|
||||||
|
downloadThread.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(result == 2)
|
||||||
|
{
|
||||||
|
//TODO save version into a hashset called doNotPrompt
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File promptFileSave(String description, String extension) throws IOException
|
||||||
|
{
|
||||||
|
JFileChooser fc = new FileChooser(new File("./").getCanonicalFile(),
|
||||||
|
"Select Save File", description, extension);
|
||||||
|
|
||||||
|
int returnVal = fc.showSaveDialog(BytecodeViewer.viewer);
|
||||||
|
File file = null;
|
||||||
|
if (returnVal == JFileChooser.APPROVE_OPTION)
|
||||||
|
{
|
||||||
|
Configuration.setLastOpenDirectory(fc.getSelectedFile());
|
||||||
|
|
||||||
|
file = fc.getSelectedFile();
|
||||||
|
String nameLowercase = file.getAbsolutePath().toLowerCase();
|
||||||
|
if (!nameLowercase.endsWith(".jar"))
|
||||||
|
file = new File(file.getAbsolutePath() + ".jar");
|
||||||
|
|
||||||
|
if (file.exists())
|
||||||
|
{
|
||||||
|
MultipleChoiceDialog overwriteDialog = new MultipleChoiceDialog("Bytecode Viewer - Overwrite File",
|
||||||
|
"The file " + file + " exists, would you like to overwrite it?",
|
||||||
|
new String[]{TranslatedStrings.YES.toString(), TranslatedStrings.NO.toString()});
|
||||||
|
|
||||||
|
if (overwriteDialog.promptChoice() != 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
//used to download all released versions of BCV
|
||||||
|
/*public static void main(String[] args)
|
||||||
|
{
|
||||||
|
BytecodeViewer.viewer = new MainViewerGUI();
|
||||||
|
for(String version : versions)
|
||||||
|
{
|
||||||
|
//TODO most are jars, check which are zip and append zip as needed
|
||||||
|
File file = new File("./" + version + ".zip");
|
||||||
|
if(!file.exists())
|
||||||
|
downloadBCV(version, file, () -> {}, () -> {});
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
private static void downloadBCV(String version, File saveTo, Runnable onFinish, Runnable onFail)
|
||||||
|
{
|
||||||
|
boolean found = false;
|
||||||
|
for(String urlAttempt : remoteGithubReleases)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String url = urlAttempt.replace("{VERSION}", version);
|
||||||
|
|
||||||
|
if(validURl(url))
|
||||||
|
{
|
||||||
|
download(url, saveTo, onFinish);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (FileNotFoundException ex) {
|
||||||
|
//ignore 404s
|
||||||
|
} catch (Exception e) {
|
||||||
|
//print network errors but don't alert user
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!found)
|
||||||
|
{
|
||||||
|
BCV.logE("Failed to download BCV v" + version);
|
||||||
|
BytecodeViewer.showMessage("Unable to download BCV v" + version + ", please let Konloch know.");
|
||||||
|
onFail.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean validURl(String url) throws Exception
|
||||||
|
{
|
||||||
|
HTTPRequest request = new HTTPRequest(new URL(url));
|
||||||
|
request.readSingle();
|
||||||
|
return request.getStatusCode() == 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void download(String url, File saveTo, Runnable onFinish) throws Exception
|
||||||
|
{
|
||||||
|
BCV.log("Downloading from: " + url);
|
||||||
|
BytecodeViewer.showMessage("Downloading the jar in the background, when it's finished you will be alerted with another message box."
|
||||||
|
+ nl + nl + "Expect this to take several minutes.");
|
||||||
|
|
||||||
|
InputStream is = new URL(url).openConnection().getInputStream();
|
||||||
|
FileOutputStream fos = new FileOutputStream(saveTo);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[8192];
|
||||||
|
int len;
|
||||||
|
int downloaded = 0;
|
||||||
|
boolean flag = false;
|
||||||
|
|
||||||
|
while ((len = is.read(buffer)) > 0)
|
||||||
|
{
|
||||||
|
fos.write(buffer, 0, len);
|
||||||
|
fos.flush();
|
||||||
|
|
||||||
|
downloaded += 8192;
|
||||||
|
int mbs = downloaded / 1048576;
|
||||||
|
if (mbs % 5 == 0 && mbs != 0)
|
||||||
|
{
|
||||||
|
if (!flag)
|
||||||
|
System.out.println("Downloaded " + mbs + "MBs so far");
|
||||||
|
flag = true;
|
||||||
|
} else
|
||||||
|
flag = false;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (is != null)
|
||||||
|
is.close();
|
||||||
|
} finally {
|
||||||
|
fos.flush();
|
||||||
|
fos.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BCV.log("Download finished!");
|
||||||
|
BytecodeViewer.showMessage("Download successful! You can find the updated program at " + saveTo.getAbsolutePath());
|
||||||
|
|
||||||
|
onFinish.run();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package the.bytecode.club.bytecodeviewer.bootloader.util;
|
package the.bytecode.club.bytecodeviewer.bootloader.classtree;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
|
@ -1,4 +1,4 @@
|
||||||
package the.bytecode.club.bytecodeviewer.bootloader.util;
|
package the.bytecode.club.bytecodeviewer.bootloader.classtree;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -8,11 +8,11 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
import org.objectweb.asm.tree.MethodNode;
|
import org.objectweb.asm.tree.MethodNode;
|
||||||
import the.bytecode.club.bytecodeviewer.bootloader.util.nullpermablehashmap.NullPermeableHashMap;
|
import the.bytecode.club.bytecodeviewer.bootloader.classtree.nullpermablehashmap.NullPermeableHashMap;
|
||||||
import the.bytecode.club.bytecodeviewer.bootloader.util.nullpermablehashmap.SetCreator;
|
import the.bytecode.club.bytecodeviewer.bootloader.classtree.nullpermablehashmap.SetCreator;
|
||||||
|
|
||||||
import static the.bytecode.club.bytecodeviewer.bootloader.util.ClassHelper.convertToMap;
|
import static the.bytecode.club.bytecodeviewer.bootloader.classtree.ClassHelper.convertToMap;
|
||||||
import static the.bytecode.club.bytecodeviewer.bootloader.util.ClassHelper.copyOf;
|
import static the.bytecode.club.bytecodeviewer.bootloader.classtree.ClassHelper.copyOf;
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
|
@ -1,4 +1,4 @@
|
||||||
package the.bytecode.club.bytecodeviewer.bootloader.util.nullpermablehashmap;
|
package the.bytecode.club.bytecodeviewer.bootloader.classtree.nullpermablehashmap;
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
|
@ -1,4 +1,4 @@
|
||||||
package the.bytecode.club.bytecodeviewer.bootloader.util.nullpermablehashmap;
|
package the.bytecode.club.bytecodeviewer.bootloader.classtree.nullpermablehashmap;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package the.bytecode.club.bytecodeviewer.bootloader.util.nullpermablehashmap;
|
package the.bytecode.club.bytecodeviewer.bootloader.classtree.nullpermablehashmap;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
|
@ -1,4 +1,4 @@
|
||||||
package the.bytecode.club.bytecodeviewer.bootloader.util.nullpermablehashmap;
|
package the.bytecode.club.bytecodeviewer.bootloader.classtree.nullpermablehashmap;
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
|
@ -11,7 +11,7 @@ import org.objectweb.asm.ClassWriter;
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
import the.bytecode.club.bytecodeviewer.bootloader.resource.external.ExternalResource;
|
import the.bytecode.club.bytecodeviewer.bootloader.resource.external.ExternalResource;
|
||||||
import the.bytecode.club.bytecodeviewer.bootloader.resource.jar.contents.JarContents;
|
import the.bytecode.club.bytecodeviewer.bootloader.resource.jar.contents.JarContents;
|
||||||
import the.bytecode.club.bytecodeviewer.bootloader.util.ClassTree;
|
import the.bytecode.club.bytecodeviewer.bootloader.classtree.ClassTree;
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
||||||
|
|
|
@ -16,6 +16,7 @@ import the.bytecode.club.bytecodeviewer.gui.components.MaxWidthJLabel;
|
||||||
import the.bytecode.club.bytecodeviewer.gui.components.listeners.MouseClickedListener;
|
import the.bytecode.club.bytecodeviewer.gui.components.listeners.MouseClickedListener;
|
||||||
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ResourceViewer;
|
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ResourceViewer;
|
||||||
import the.bytecode.club.bytecodeviewer.gui.util.DelayTabbedPaneThread;
|
import the.bytecode.club.bytecodeviewer.gui.util.DelayTabbedPaneThread;
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
||||||
|
@ -84,8 +85,8 @@ public class TabbedPane extends JPanel
|
||||||
|
|
||||||
//define the right click pop-up menu
|
//define the right click pop-up menu
|
||||||
JPopupMenu rightClickMenu = new JPopupMenu();
|
JPopupMenu rightClickMenu = new JPopupMenu();
|
||||||
JMenuItem closeAllTabs = new JMenuItem("Close All But This: " + name);
|
JMenuItem closeAllTabs = new JMenuItem(TranslatedStrings.CLOSE_ALL_BUT_THIS.toString() + ": " + name);
|
||||||
JMenuItem closeTab = new JMenuItem("Close Tab: " + name);
|
JMenuItem closeTab = new JMenuItem(TranslatedStrings.CLOSE_TAB.toString() + ": " + name);
|
||||||
|
|
||||||
rightClickMenu.add(closeAllTabs);
|
rightClickMenu.add(closeAllTabs);
|
||||||
rightClickMenu.add(closeTab);
|
rightClickMenu.add(closeTab);
|
||||||
|
|
|
@ -111,8 +111,8 @@ public class Workspace extends TranslatedVisibleComponent
|
||||||
if (c != null && bounds.intersects(c.getBounds()))
|
if (c != null && bounds.intersects(c.getBounds()))
|
||||||
{
|
{
|
||||||
popUp.setVisible(true);
|
popUp.setVisible(true);
|
||||||
closeAllTabs.setText("Close All But This: " + ((TabbedPane) c).tabName);
|
closeAllTabs.setText(TranslatedStrings.CLOSE_TAB.toString() + ": " + ((TabbedPane) c).tabName);
|
||||||
closeTab.setText("Close Tab: " + ((TabbedPane) c).tabName);
|
closeTab.setText(TranslatedStrings.CLOSE_TAB.toString() + ": " + ((TabbedPane) c).tabName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -179,6 +179,8 @@ public class Workspace extends TranslatedVisibleComponent
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//unlock the refresh button
|
||||||
|
BytecodeViewer.viewer.workPane.refreshClass.setEnabled(true);
|
||||||
|
|
||||||
final String workingName = container.getWorkingName(name);
|
final String workingName = container.getWorkingName(name);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package the.bytecode.club.bytecodeviewer.translation;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import org.apache.commons.collections4.map.LinkedMap;
|
import org.apache.commons.collections4.map.LinkedMap;
|
||||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
|
import the.bytecode.club.bytecodeviewer.Constants;
|
||||||
import the.bytecode.club.bytecodeviewer.api.BCV;
|
import the.bytecode.club.bytecodeviewer.api.BCV;
|
||||||
import the.bytecode.club.bytecodeviewer.resources.IconResources;
|
import the.bytecode.club.bytecodeviewer.resources.IconResources;
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ import java.util.*;
|
||||||
public enum Language
|
public enum Language
|
||||||
{
|
{
|
||||||
ARABIC("/translations/arabic.json", "عربى", "English", "ar"),
|
ARABIC("/translations/arabic.json", "عربى", "English", "ar"),
|
||||||
ENGLISH("/translations/english.json", "English", "English", "en"),
|
ENGLISH("/translations/english.json", "English", (Constants.DEV_MODE ? "english.draft" : "english"), "en"),
|
||||||
ESTONIAN("/translations/estonian.json", "Eesti", "English", "et"),
|
ESTONIAN("/translations/estonian.json", "Eesti", "English", "et"),
|
||||||
FARSI("/translations/farsi.json", "فارسی ", "English", "fa"),
|
FARSI("/translations/farsi.json", "فارسی ", "English", "fa"),
|
||||||
FINNISH("/translations/finnish.json", "Suomen Kieli", "English", "fi"),
|
FINNISH("/translations/finnish.json", "Suomen Kieli", "English", "fi"),
|
||||||
|
|
|
@ -73,6 +73,8 @@ public enum TranslatedStrings
|
||||||
EXIT_CONFIRM,
|
EXIT_CONFIRM,
|
||||||
ABOUT_TITLE,
|
ABOUT_TITLE,
|
||||||
PLUGIN_CONSOLE_TITLE,
|
PLUGIN_CONSOLE_TITLE,
|
||||||
|
CLOSE_ALL_BUT_THIS,
|
||||||
|
CLOSE_TAB,
|
||||||
|
|
||||||
|
|
||||||
YES,
|
YES,
|
||||||
|
|
|
@ -1,210 +0,0 @@
|
||||||
package the.bytecode.club.bytecodeviewer.util;
|
|
||||||
|
|
||||||
import me.konloch.kontainer.io.HTTPRequest;
|
|
||||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
|
||||||
import the.bytecode.club.bytecodeviewer.Configuration;
|
|
||||||
import the.bytecode.club.bytecodeviewer.gui.components.FileChooser;
|
|
||||||
import the.bytecode.club.bytecodeviewer.gui.components.MultipleChoiceDialog;
|
|
||||||
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
import static the.bytecode.club.bytecodeviewer.Constants.*;
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* 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/>. *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Konloch
|
|
||||||
*/
|
|
||||||
public class VersionChecker implements Runnable
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
HTTPRequest r = new HTTPRequest(new URL("https://raw.githubusercontent.com/Konloch/bytecode-viewer/master/VERSION"));
|
|
||||||
final String version = r.readSingle();
|
|
||||||
final String localVersion = VERSION + 0;
|
|
||||||
try {
|
|
||||||
int simplemaths = Integer.parseInt(version.replace(".", ""));
|
|
||||||
int simplemaths2 = Integer.parseInt(localVersion.replace(".", ""));
|
|
||||||
if (simplemaths2 > simplemaths)
|
|
||||||
return; //developer version
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (VERSION != null && !VERSION.equals(version))
|
|
||||||
{
|
|
||||||
MultipleChoiceDialog outdatedDialog = new MultipleChoiceDialog("Bytecode Viewer - Outdated Version",
|
|
||||||
"Your version: " + VERSION + ", latest version: "
|
|
||||||
+ version + nl + "What would you like to do?",
|
|
||||||
new String[]{"Open The Download Page", "Download The Updated Jar", "Do Nothing"});
|
|
||||||
|
|
||||||
int result = outdatedDialog.promptChoice();
|
|
||||||
|
|
||||||
if (result == 0)
|
|
||||||
{
|
|
||||||
if (Desktop.isDesktopSupported())
|
|
||||||
Desktop.getDesktop().browse(new URI("https://github.com/Konloch/bytecode-viewer/releases"));
|
|
||||||
else
|
|
||||||
BytecodeViewer.showMessage("Cannot open the page, please manually type it."
|
|
||||||
+ nl + "https://github.com/Konloch/bytecode-viewer/releases");
|
|
||||||
}
|
|
||||||
else if (result == 1)
|
|
||||||
{
|
|
||||||
JFileChooser fc = new FileChooser(Configuration.getLastOpenDirectory(),
|
|
||||||
"Select Save File",
|
|
||||||
"Zip Archives",
|
|
||||||
"zip");
|
|
||||||
|
|
||||||
try {
|
|
||||||
fc.setCurrentDirectory(new File(".").getAbsoluteFile()); //set the current working directory
|
|
||||||
} catch (Exception e) {
|
|
||||||
BytecodeViewer.handleException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
int returnVal = fc.showSaveDialog(BytecodeViewer.viewer);
|
|
||||||
if (returnVal == JFileChooser.APPROVE_OPTION)
|
|
||||||
{
|
|
||||||
Configuration.setLastOpenDirectory(fc.getSelectedFile());
|
|
||||||
|
|
||||||
File file = fc.getSelectedFile();
|
|
||||||
if (!file.getAbsolutePath().endsWith(".zip"))
|
|
||||||
file = new File(file.getAbsolutePath() + ".zip");
|
|
||||||
|
|
||||||
if (file.exists())
|
|
||||||
{
|
|
||||||
MultipleChoiceDialog overwriteDialog = new MultipleChoiceDialog("Bytecode Viewer - Overwrite File",
|
|
||||||
"The file " + file + " exists, would you like to overwrite it?",
|
|
||||||
new String[]{TranslatedStrings.YES.toString(), TranslatedStrings.NO.toString()});
|
|
||||||
|
|
||||||
if (overwriteDialog.promptChoice() != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
file.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
final File finalFile = file;
|
|
||||||
Thread downloadThread = new Thread(() -> {
|
|
||||||
try {
|
|
||||||
InputStream is = new URL("https://github.com/Konloch/bytecode-viewer/releases/download/v" + version + "/BytecodeViewer." + version + ".zip").openConnection().getInputStream();
|
|
||||||
FileOutputStream fos = new FileOutputStream(finalFile);
|
|
||||||
try {
|
|
||||||
System.out.println("Downloading from https://github.com/Konloch/bytecode-viewer/releases/download/v" + version + "/BytecodeViewer." + version + ".zip");
|
|
||||||
byte[] buffer = new byte[8192];
|
|
||||||
int len;
|
|
||||||
int downloaded = 0;
|
|
||||||
boolean flag = false;
|
|
||||||
BytecodeViewer.showMessage("Downloading the jar in the background, when it's finished "
|
|
||||||
+ "you will be alerted with another message box." + nl + nl +
|
|
||||||
"Expect this to take several minutes.");
|
|
||||||
|
|
||||||
while ((len = is.read(buffer)) > 0)
|
|
||||||
{
|
|
||||||
fos.write(buffer, 0, len);
|
|
||||||
fos.flush();
|
|
||||||
downloaded += 8192;
|
|
||||||
int mbs = downloaded / 1048576;
|
|
||||||
if (mbs % 5 == 0 && mbs != 0)
|
|
||||||
{
|
|
||||||
if (!flag)
|
|
||||||
System.out.println("Downloaded " + mbs + "MBs so far");
|
|
||||||
flag = true;
|
|
||||||
} else
|
|
||||||
flag = false;
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (is != null) {
|
|
||||||
is.close();
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
fos.flush();
|
|
||||||
fos.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
System.out.println("Download finished!");
|
|
||||||
BytecodeViewer.showMessage("Download successful! You can find the updated program at " + finalFile.getAbsolutePath());
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
try {
|
|
||||||
InputStream is = new URL("https://github.com/Konloch/bytecode-viewer/releases/download/v" + version + "/BytecodeViewer." + version + ".jar"
|
|
||||||
).openConnection().getInputStream();
|
|
||||||
FileOutputStream fos = new FileOutputStream(finalFile);
|
|
||||||
try {
|
|
||||||
System.out.println("Downloading from https://github.com/Konloch/bytecode-viewer/releases/download/v" + version + "/BytecodeViewer." + version + ".jar");
|
|
||||||
byte[] buffer = new byte[8192];
|
|
||||||
int len;
|
|
||||||
int downloaded = 0;
|
|
||||||
boolean flag = false;
|
|
||||||
BytecodeViewer.showMessage("Downloading the jar in the background, when it's "
|
|
||||||
+ "finished you will be alerted with another message box." + nl + nl + "Expect this to take several minutes.");
|
|
||||||
while ((len = is.read(buffer)) > 0) {
|
|
||||||
fos.write(buffer, 0, len);
|
|
||||||
fos.flush();
|
|
||||||
downloaded += 8192;
|
|
||||||
int mbs = downloaded / 1048576;
|
|
||||||
if (mbs % 5 == 0 && mbs != 0) {
|
|
||||||
if (!flag)
|
|
||||||
System.out.println("Downloaded " + mbs + "MBs so far");
|
|
||||||
flag = true;
|
|
||||||
} else
|
|
||||||
flag = false;
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (is != null) {
|
|
||||||
is.close();
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
fos.flush();
|
|
||||||
fos.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
System.out.println("Download finished!");
|
|
||||||
BytecodeViewer.showMessage("Download successful! You can find the updated program at " + finalFile.getAbsolutePath());
|
|
||||||
} catch (FileNotFoundException ex) {
|
|
||||||
BytecodeViewer.showMessage("Unable to download, the zip file has not been uploaded yet, "
|
|
||||||
+ "please try again in about 10 minutes.");
|
|
||||||
} catch (Exception ex) {
|
|
||||||
BytecodeViewer.handleException(ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
BytecodeViewer.handleException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}, "Downloader");
|
|
||||||
downloadThread.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -252,6 +252,8 @@
|
||||||
"EXIT_CONFIRM": "Are you sure you want to exit?",
|
"EXIT_CONFIRM": "Are you sure you want to exit?",
|
||||||
"ABOUT_TITLE": "{PRODUCT_NAME} - About - {WEBSITE} | {TBC}",
|
"ABOUT_TITLE": "{PRODUCT_NAME} - About - {WEBSITE} | {TBC}",
|
||||||
"PLUGIN_CONSOLE_TITLE": "{PRODUCT_NAME} - Plugin Console",
|
"PLUGIN_CONSOLE_TITLE": "{PRODUCT_NAME} - Plugin Console",
|
||||||
|
"CLOSE_ALL_BUT_THIS": "Close All But This",
|
||||||
|
"CLOSE_TAB": "Close Tab",
|
||||||
|
|
||||||
|
|
||||||
"FILES": "Files",
|
"FILES": "Files",
|
||||||
|
|
165
src/main/resources/translations/html/intro.english.draft.html
Normal file
165
src/main/resources/translations/html/intro.english.draft.html
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
<html>
|
||||||
|
<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:
|
||||||
|
Decode Resources
|
||||||
|
Enjarify
|
||||||
|
Dex2Jar (d2j)
|
||||||
|
Decode Resources will run APKTool to decode any packed android-specific resources
|
||||||
|
Enjarify will convert the dalvik specific bytecode to java bytecode
|
||||||
|
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>
|
Loading…
Add table
Add a link
Reference in a new issue