77import java .io .ByteArrayInputStream ;
88import java .io .ByteArrayOutputStream ;
99import java .io .File ;
10- import java .io .FileDescriptor ;
1110import java .io .FileInputStream ;
1211import java .io .FileNotFoundException ;
1312import java .io .FileOutputStream ;
1413import java .io .IOException ;
1514import java .io .InputStream ;
16- import java .net .InetAddress ;
1715import java .net .URI ;
1816import java .net .URL ;
19- import java .security .Permission ;
2017import java .util .ArrayList ;
2118import java .util .HashMap ;
2219import java .util .Map .Entry ;
3734import org .imgscalr .Scalr ;
3835import org .objectweb .asm .tree .ClassNode ;
3936
40- import the .bytecode .club .bytecodeviewer .decompilers . Smali ;
37+ import the .bytecode .club .bytecodeviewer .api . ClassNodeLoader ;
4138import the .bytecode .club .bytecodeviewer .gui .ClassViewer ;
4239import the .bytecode .club .bytecodeviewer .gui .FileNavigationPane ;
4340import the .bytecode .club .bytecodeviewer .gui .MainViewerGUI ;
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.
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
311317public 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 ) {
0 commit comments