Skip to content

Commit 1cd3bfa

Browse files
committed
2.8.0
02/01/2015 - Updated CFR and Proycon to latest versions. 02/01/2015 - Started working on implementing Krakatau. 02/01/2015 - Sexifixed the security manager a little bit. 02/03/2015 - Fully added Krakatau Java decompiler, just disassembly/assembly left. 02/03/2015 - Updated the about window. 02/03/2015 - Dropped JRuby and Jython support (BCV is now roughly 16mb, was 45mb). 02/04/2015 - Added Krakatau Disassembly. 02/04/2015 - Added Krakatau Assembly.
1 parent 58020b0 commit 1cd3bfa

28 files changed

Lines changed: 1111 additions & 280 deletions

BytecodeViewer 2.7.1.jar

-42.1 MB
Binary file not shown.

README.txt

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
Bytecode Viewer is an Advanced Lightweight Java Bytecode Viewer, GUI Smali, GUI Baksmali, GUI APK Editor, GUI Dex Editor, GUI APK Decompiler, GUI DEX Decompiler, GUI Procyon Java Decompiler, GUI CFR Java Decompiler, GUI FernFlower Java Decompiler, GUI DEX2Jar, GUI Jar2DEX, GUI Jar-Jar, Hex Viewer, Code Searcher, Debugger and more.
1+
Bytecode Viewer is an Advanced Lightweight Java Bytecode Viewer, GUI Smali, GUI Baksmali, GUI APK Editor, GUI Dex Editor, GUI APK Decompiler, GUI DEX Decompiler, GUI Procyon Java Decompiler, GUI Krakatau, GUI CFR Java Decompiler, GUI FernFlower Java Decompiler, GUI DEX2Jar, GUI Jar2DEX, GUI Jar-Jar, Hex Viewer, Code Searcher, Debugger and more.
22
It's written completely in Java, and it's open sourced. It's currently being maintained and developed by Konloch.
33

44
There is also a plugin system that will allow you to interact with the loaded classfiles, for example you can write a String deobfuscator, a malicious code searcher, or something else you can think of.
5-
You can either use one of the pre-written plugins, or write your own. It supports groovy, python and ruby scripting. Once a plugin is activated, it will execute the plugin with a ClassNode ArrayList of every single class loaded in BCV, this allows the user to handle it completely using ASM.
5+
You can either use one of the pre-written plugins, or write your own. It supports groovy scripting. Once a plugin is activated, it will execute the plugin with a ClassNode ArrayList of every single class loaded in BCV, this allows the user to handle it completely using ASM.
66

77
Code from various projects has been used, including but not limited to:
88
J-RET by WaterWolf
@@ -16,6 +16,7 @@ Code from various projects has been used, including but not limited to:
1616
CFIDE by Bibl
1717
Smali by JesusFreke
1818
Dex2Jar by pxb1..?
19+
Krakatau by Storyyeller
1920

2021
Contributors:
2122
Konloch
@@ -31,7 +32,7 @@ Contribution Guide Lines:
3132
Packages must start with the.bytecode.club.bytecodeviewer
3233
If code you write can throw an exception, handle it using new the.bytecode.club.bytecodeviewer.ExceptionUI(exception)
3334

34-
Video: http://the.bytecode.club/bytecodeviewer-video/
35+
Website: https://bytecodeviewer.com
3536
Source Code: https://github.com/konloch/bytecode-viewer
3637
Bin/Archive: https://github.com/konloch/bytecode-viewer/releases
3738
Java Docs: https://the.bytecode.club/docs/bytecode-viewer/
@@ -40,15 +41,16 @@ Report Bugs (or below): https://github.com/Konloch/bytecode-viewer/issues
4041
Discussion Forum: https://the.bytecode.club/forumdisplay.php?fid=69
4142

4243
Key Features:
43-
Smali/BakSmali Intergration - You can now edit class files/dex files via smali!
44+
Krakatau Integration for Bytecode assembly/disassembly.
45+
Smali/BakSmali Integration - You can now edit class files/dex files via smali!
4446
APK/DEX Support - Using Dex2Jar and Jar2Dex it's able to load and save APKs with ease!
4547
Java Decompiler - It utilizes FernFlower, Procyon and CFR for decompilation.
4648
Bytecode Decompiler - A modified version of CFIDE's.
4749
Hex Viewer - Powered by JHexPane.
4850
Each Decompiler/Viewer is toggleable, you can also select what will display on each pane.
4951
Fully Featured Search System - Search through strings, functions, variables and more!
5052
A Plugin System With Built In Plugins - (Show All Strings, Malicious Code Scanner, String Decrypters, etc)
51-
Fully Featured Scripting System That Supports Groovy, Python And Ruby.
53+
Fully Featured Scripting System That Supports Groovy.
5254
EZ-Inject - Graphically insert hooks and debugging code, invoke main and start the program.
5355
Recent Files & Recent Plugins.
5456
And more! Give it a try for yourself!
@@ -276,4 +278,13 @@ Changelog:
276278
01/27/2015 - Decided to scrap the JVM Sandbox POC and use the Security Manager.
277279
01/27/2015 - BCV now blocks exec and won't allow any ports to be bound.
278280
--- 2.7.1 ---:
279-
01/27/2015 - Fixed hide file.
281+
01/27/2015 - Fixed hide file.
282+
--- 2.8.0 ---:
283+
02/01/2015 - Updated CFR and Proycon to latest versions.
284+
02/01/2015 - Started working on implementing Krakatau.
285+
02/01/2015 - Sexifixed the security manager a little bit.
286+
02/03/2015 - Fully added Krakatau Java decompiler, just disassembly/assembly left.
287+
02/03/2015 - Updated the about window.
288+
02/03/2015 - Dropped JRuby and Jython support (BCV is now roughly 16mb, was 45mb).
289+
02/04/2015 - Added Krakatau Disassembly.
290+
02/04/2015 - Added Krakatau Assembly.
Binary file not shown.

libs/jruby.jar

-12.7 MB
Binary file not shown.

src/krakatau.zip

280 KB
Binary file not shown.

src/the/bytecode/club/bytecodeviewer/BytecodeViewer.java

Lines changed: 76 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,13 @@
77
import java.io.ByteArrayInputStream;
88
import java.io.ByteArrayOutputStream;
99
import java.io.File;
10-
import java.io.FileDescriptor;
1110
import java.io.FileInputStream;
1211
import java.io.FileNotFoundException;
1312
import java.io.FileOutputStream;
1413
import java.io.IOException;
1514
import java.io.InputStream;
16-
import java.net.InetAddress;
1715
import java.net.URI;
1816
import java.net.URL;
19-
import java.security.Permission;
2017
import java.util.ArrayList;
2118
import java.util.HashMap;
2219
import java.util.Map.Entry;
@@ -37,7 +34,7 @@
3734
import org.imgscalr.Scalr;
3835
import org.objectweb.asm.tree.ClassNode;
3936

40-
import the.bytecode.club.bytecodeviewer.decompilers.Smali;
37+
import the.bytecode.club.bytecodeviewer.api.ClassNodeLoader;
4138
import the.bytecode.club.bytecodeviewer.gui.ClassViewer;
4239
import the.bytecode.club.bytecodeviewer.gui.FileNavigationPane;
4340
import the.bytecode.club.bytecodeviewer.gui.MainViewerGUI;
@@ -63,7 +60,7 @@
6360
* There is also a plugin system that will allow you to interact with the loaded
6461
* classfiles, for example you can write a String deobfuscator, a malicious code
6562
* searcher, or something else you can think of. You can either use one of the
66-
* pre-written plugins, or write your own. It supports groovy, python and ruby
63+
* pre-written plugins, or write your own. It supports groovy
6764
* scripting. Once a plugin is activated, it will send a ClassNode ArrayList of
6865
* every single class loaded in the file system to the execute function, this
6966
* allows the user to handle it completely using ASM.
@@ -303,27 +300,45 @@
303300
* 01/27/2015 - Added java.awt.Robot to the malicious code scanner.
304301
* -----2.7.1-----:
305302
* 01/27/2015 - Fixed hide file.
303+
* -----2.8.0-----:
304+
* 02/01/2015 - Updated CFR and Proycon to latest versions.
305+
* 02/01/2015 - Started working on implementing Krakatau.
306+
* 02/01/2015 - Sexifixed the security manager a little bit.
307+
* 02/03/2015 - Fully added Krakatau Java decompiler, just disassembly/assembly left.
308+
* 02/03/2015 - Updated the about window.
309+
* 02/03/2015 - Dropped JRuby and Jython support (BCV is now roughly 16mb, was 45mb).
310+
* 02/04/2015 - Added Krakatau Disassembly.
311+
* 02/04/2015 - Added Krakatau Assembly.
306312
*
307313
* @author Konloch
308314
*
309315
*/
310316

311317
public class BytecodeViewer {
312318

319+
/*per version*/
320+
public static String version = "2.8.0";
321+
public static String krakatauVersion = "2";
322+
/*the rest*/
313323
public static MainViewerGUI viewer = null;
324+
public static ClassNodeLoader loader = new ClassNodeLoader(); //might be insecure due to assholes targeting BCV, however that's highly unlikely.
325+
public static String python = "";
326+
public static String rt = "";
327+
public static SecurityMan sm = new SecurityMan();
314328
public static HashMap<String, ClassNode> loadedClasses = new HashMap<String, ClassNode>();
315329
public static HashMap<String, byte[]> loadedResources = new HashMap<String, byte[]>();
316330
private static int maxRecentFiles = 25;
317331
public static String fs = System.getProperty("file.separator");
318332
public static String nl = System.getProperty("line.separator");
333+
private static File BCVDir = new File(System.getProperty("user.home") + fs + ".Bytecode-Viewer");
319334
private static String filesName = getBCVDirectory() + fs + "recentfiles.bcv";
320335
private static String pluginsName = getBCVDirectory() + fs + "recentplugins.bcv";
321336
public static String settingsName = getBCVDirectory() + fs + "settings.bcv";
322337
public static String tempDirectory = getBCVDirectory() + fs + "bcv_temp" + fs;
338+
public static String krakatauWorkingDirectory = getBCVDirectory() + fs + "krakatau_" + krakatauVersion + fs + "Krakatau-master";
323339
private static ArrayList<String> recentFiles = DiskReader.loadArrayList(filesName, false);
324340
private static ArrayList<String> recentPlugins = DiskReader.loadArrayList(pluginsName, false);
325341
public static boolean runningObfuscation = false;
326-
public static String version = "2.7.1";
327342
private static long start = System.currentTimeMillis();
328343
public static String lastDirectory = "";
329344
private static Thread versionChecker = new Thread() {
@@ -502,51 +517,8 @@ public static byte[] getClassFile(Class<?> clazz) throws IOException {
502517
}
503518

504519
public static void main(String[] args) {
505-
getBCVDirectory();
506-
SecurityManager sm = new SecurityManager() {
507-
@Override
508-
public void checkExec(String cmd) {
509-
throw new SecurityException("BCV is awesome.");
510-
}
511-
@Override
512-
public void checkListen(int port) {
513-
throw new SecurityException("BCV is awesome.");
514-
}
515-
@Override
516-
public void checkPermission(Permission perm) { //expand eventually
517-
}
518-
@Override
519-
public void checkPermission(Permission perm, Object context) {//expand eventually
520-
}
521-
@Override public void checkAccess(Thread t) {}
522-
@Override public void checkAccept(String host, int port) {}
523-
@Override public void checkAccess(ThreadGroup g) {}
524-
@Override public void checkAwtEventQueueAccess() {}
525-
@Override public void checkConnect(String host, int port) {}
526-
@Override public void checkConnect(String host, int port, Object context) {}
527-
@Override public void checkCreateClassLoader() {}
528-
@Override public void checkDelete(String file) {}
529-
@Override public void checkExit(int status) {}
530-
@Override public void checkLink(String lib) {}
531-
@Override public void checkMemberAccess(Class<?> clazz, int which) {}
532-
@Override public void checkMulticast(InetAddress maddr) {}
533-
@Override public void checkMulticast(InetAddress maddr, byte ttl) {}
534-
@Override public void checkPackageAccess(String pkg) {}
535-
@Override public void checkPackageDefinition(String pkg) {}
536-
@Override public void checkPrintJobAccess() {}
537-
@Override public void checkPropertiesAccess() {}
538-
@Override public void checkPropertyAccess(String key) {}
539-
@Override public void checkRead(FileDescriptor fd) {}
540-
@Override public void checkRead(String file) {}
541-
@Override public void checkRead(String file, Object context) {}
542-
@Override public void checkSecurityAccess(String target) {}
543-
@Override public void checkSetFactory() {}
544-
@Override public void checkSystemClipboardAccess() {}
545-
@Override public void checkWrite(FileDescriptor fd) {}
546-
@Override public void checkWrite(String file) {}
547-
};
548520
System.setSecurityManager(sm);
549-
521+
checkKrakatau();
550522
System.out.println("https://the.bytecode.club - Created by @Konloch - Bytecode Viewer " + version);
551523
iconList = new ArrayList<BufferedImage>();
552524
int size = 16;
@@ -616,18 +588,18 @@ public static ArrayList<ClassNode> getLoadedClasses() {
616588
}
617589

618590
//called whenever a save function is executed
619-
public static boolean compileSmali(boolean message) {
591+
public static boolean compile(boolean message) {
620592
if(getLoadedClasses().isEmpty())
621593
return false;
622594

623595
for(java.awt.Component c : BytecodeViewer.viewer.workPane.getLoadedViewers()) {
624596
if(c instanceof ClassViewer) {
625597
ClassViewer cv = (ClassViewer) c;
626598
Object smali[] = cv.getSmali();
627-
ClassNode origNode = (ClassNode) smali[0];
628-
String smaliText = (String) smali[1];
629599
if(smali != null) {
630-
byte[] smaliCompiled = Smali.compile(smaliText);
600+
ClassNode origNode = (ClassNode) smali[0];
601+
String smaliText = (String) smali[1];
602+
byte[] smaliCompiled = the.bytecode.club.bytecodeviewer.compilers.SmaliAssembler.compile(smaliText);
631603
if(smaliCompiled != null) {
632604
ClassNode newNode = JarUtils.getNode(smaliCompiled);
633605
System.out.println(origNode.name+":"+newNode.name);
@@ -637,6 +609,22 @@ public static boolean compileSmali(boolean message) {
637609
return false;
638610
}
639611
}
612+
613+
614+
Object krakatau[] = cv.getKrakatau();
615+
if(krakatau != null) {
616+
ClassNode origNodeK = (ClassNode) krakatau[0];
617+
String krakatauText = (String) krakatau[1];
618+
byte[] krakatauCompiled = the.bytecode.club.bytecodeviewer.compilers.KrakatauAssembler.compile(krakatauText, origNodeK.name);
619+
if(krakatauCompiled != null) {
620+
ClassNode newNode = JarUtils.getNode(krakatauCompiled);
621+
System.out.println(origNodeK.name+":"+newNode.name);
622+
BytecodeViewer.updateNode(origNodeK, newNode);
623+
} else {
624+
BytecodeViewer.showMessage("There has been an error with assembling your Krakatau Bytecode, please check this. Class: " + origNodeK.name);
625+
return false;
626+
}
627+
}
640628
}
641629
}
642630

@@ -646,6 +634,30 @@ public static boolean compileSmali(boolean message) {
646634
return true;
647635
}
648636

637+
public static void checkKrakatau() {
638+
File krakatauDirectory = new File(getBCVDirectory() + fs + "krakatau_" + krakatauVersion);
639+
if(!krakatauDirectory.exists()) {
640+
try {
641+
File temp = new File(getBCVDirectory() + fs + "krakatau_" + krakatauVersion + ".zip");
642+
while(temp.exists())
643+
temp.delete();
644+
InputStream is = BytecodeViewer.class.getClassLoader().getResourceAsStream("krakatau.zip");
645+
FileOutputStream baos = new FileOutputStream(temp);
646+
int r = 0;
647+
byte[] buffer = new byte[8192];
648+
while((r=is.read(buffer))>=0) {
649+
baos.write(buffer, 0, r);
650+
}
651+
baos.close();
652+
ZipUtils.unzipFilesToPath(temp.getAbsolutePath(), krakatauDirectory.getAbsolutePath());
653+
temp.delete();
654+
} catch(Exception e) {
655+
showMessage("ERROR: There was an issue unzipping Krakatau decompiler, please contact @Konloch with your stacktrace.");
656+
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
657+
}
658+
}
659+
}
660+
649661
private static boolean update = true;
650662
public static void openFiles(final File[] files, boolean recentFiles) {
651663
if(recentFiles)
@@ -741,7 +753,6 @@ public static void showMessage(String message) {
741753
JOptionPane.showMessageDialog(viewer, message);
742754
}
743755

744-
@SuppressWarnings("deprecation")
745756
public static void resetWorkSpace(boolean ask) {
746757
if(!ask) {
747758
loadedResources.clear();
@@ -759,7 +770,7 @@ public static void resetWorkSpace(boolean ask) {
759770
pane.setOptions(options);
760771
JDialog dialog = pane.createDialog(viewer,
761772
"Bytecode Viewer - Reset Workspace");
762-
dialog.show();
773+
dialog.setVisible(true);
763774
Object obj = pane.getValue();
764775
int result = -1;
765776
for (int k = 0; k < options.length; k++)
@@ -793,8 +804,7 @@ public static void addRecentFile(File f) {
793804
killList.clear();
794805
}
795806

796-
if (recentFiles.contains(f.getAbsolutePath())) // already added on the
797-
// list
807+
if (recentFiles.contains(f.getAbsolutePath())) // already added on the list
798808
recentFiles.remove(f.getAbsolutePath());
799809
if (recentFiles.size() >= maxRecentFiles)
800810
recentFiles.remove(maxRecentFiles - 1); // zero indexing
@@ -818,8 +828,7 @@ public static void addRecentPlugin(File f) {
818828
killList2.clear();
819829
}
820830

821-
if (recentPlugins.contains(f.getAbsolutePath())) // already added on the
822-
// list
831+
if (recentPlugins.contains(f.getAbsolutePath())) // already added on the list
823832
recentPlugins.remove(f.getAbsolutePath());
824833
if (recentPlugins.size() >= maxRecentFiles)
825834
recentPlugins.remove(maxRecentFiles - 1); // zero indexing
@@ -887,29 +896,28 @@ public static String getRandomizedName() {
887896
}
888897

889898
public static String getBCVDirectory() {
890-
File f = new File(System.getProperty("user.home") + fs
891-
+ ".Bytecode-Viewer");
892-
while (!f.exists())
893-
f.mkdirs();
899+
while (!BCVDir.exists())
900+
BCVDir.mkdirs();
894901

895-
if (!f.isHidden() && isWindows())
896-
hideFile(f);
902+
if (!BCVDir.isHidden() && isWindows())
903+
hideFile(BCVDir);
897904

898-
return f.getAbsolutePath();
905+
return BCVDir.getAbsolutePath();
899906
}
900907

901908
private static boolean isWindows() {
902909
return System.getProperty("os.name").toLowerCase().contains("win");
903910
}
904911

905912
private static void hideFile(File f) {
906-
System.out.println("hiding file");
913+
sm.blocking = false;
907914
try {
908915
// Hide file by running attrib system command (on Windows)
909916
Runtime.getRuntime().exec("attrib +H " + f.getAbsolutePath());
910917
} catch (Exception e) {
911918
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
912919
}
920+
sm.blocking = true;
913921
}
914922

915923
private static String quickConvert(ArrayList<String> a) {

src/the/bytecode/club/bytecodeviewer/MiscUtils.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package the.bytecode.club.bytecodeviewer;
22

3+
import java.io.File;
34
import java.util.Random;
45

56
public class MiscUtils {
@@ -20,4 +21,35 @@ public static String randomStringNum(int len) {
2021
sb.append(AN.charAt(rnd.nextInt(AN.length())));
2122
return sb.toString();
2223
}
24+
25+
26+
27+
public static String getUniqueName(String start, String ext) {
28+
String s = null;
29+
boolean b = true;
30+
File f = null;
31+
String m = null;
32+
while (b) {
33+
m = MiscUtils.randomString(32);
34+
f = new File(start + m + ext);
35+
if (!f.exists()) {
36+
s = start + m;
37+
b = false;
38+
}
39+
}
40+
return s;
41+
}
42+
43+
public static int getClassNumber(String start, String ext) {
44+
boolean b = true;
45+
int i = 0;
46+
while (b) {
47+
File tempF = new File(start + i + ext);
48+
if (!tempF.exists())
49+
b = false;
50+
else
51+
i++;
52+
}
53+
return i;
54+
}
2355
}

0 commit comments

Comments
 (0)