diff --git a/src/the/bytecode/club/bytecodeviewer/APKTool.java b/src/the/bytecode/club/bytecodeviewer/APKTool.java index cf472610..0ae6c2b0 100644 --- a/src/the/bytecode/club/bytecodeviewer/APKTool.java +++ b/src/the/bytecode/club/bytecodeviewer/APKTool.java @@ -28,7 +28,9 @@ public class APKTool { try { File dir = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "Decoded Resources"); FileUtils.deleteDirectory(dir); - brut.apktool.Main.main(new String[]{"-s", "-f", "-o", dir.getAbsolutePath(), "decode", input.getAbsolutePath()}); + File temp = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(12)); + temp.mkdirs(); + brut.apktool.Main.main(new String[]{"--frame-path", temp.getAbsolutePath(), "-s", "-f", "-o", dir.getAbsolutePath(), "decode", input.getAbsolutePath()}); File original = new File(dir.getAbsolutePath() + BytecodeViewer.fs + "original"); FileUtils.deleteDirectory(original); File classes = new File(dir.getAbsolutePath() + BytecodeViewer.fs + "classes.dex"); diff --git a/src/the/bytecode/club/bytecodeviewer/BytecodeViewer.java b/src/the/bytecode/club/bytecodeviewer/BytecodeViewer.java index cbfcf9f3..aded07b3 100644 --- a/src/the/bytecode/club/bytecodeviewer/BytecodeViewer.java +++ b/src/the/bytecode/club/bytecodeviewer/BytecodeViewer.java @@ -142,6 +142,7 @@ public class BytecodeViewer public static int krakatauHash; public static boolean currentlyDumping = false; public static boolean needsReDump = true; + public static boolean warnForEditing = false; public static ArrayList files = new ArrayList(); //all of BCV's loaded files/classes/etc private static int maxRecentFiles = 25; public static String fs = System.getProperty("file.separator"); diff --git a/src/the/bytecode/club/bytecodeviewer/Settings.java b/src/the/bytecode/club/bytecodeviewer/Settings.java index 192809df..5cdc6ae5 100644 --- a/src/the/bytecode/club/bytecodeviewer/Settings.java +++ b/src/the/bytecode/club/bytecodeviewer/Settings.java @@ -179,8 +179,8 @@ public class Settings { DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.refreshOnChange.isSelected()), false); DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.isMaximized), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.autoCompileSmali.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.autoCompileOnRefresh.isSelected()), false); + DiskWriter.writeNewLine(BytecodeViewer.settingsName, "deprecated", false); + DiskWriter.writeNewLine(BytecodeViewer.settingsName, "deprecated", false); DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.lastDirectory, false); DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.python, false); DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.rt, false); @@ -214,6 +214,8 @@ public class Settings { DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.python3, false); DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.javac, false); DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.java, false); + DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.autoCompileSmali.isSelected()), false); + DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.autoCompileOnRefresh.isSelected()), false); } catch (Exception e) { new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); } @@ -374,8 +376,6 @@ public class Settings { BytecodeViewer.viewer.setExtendedState(JFrame.MAXIMIZED_BOTH); BytecodeViewer.viewer.isMaximized = true; } - BytecodeViewer.viewer.autoCompileSmali.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 86, false))); - BytecodeViewer.viewer.autoCompileOnRefresh.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 87, false))); BytecodeViewer.lastDirectory = DiskReader.loadString(BytecodeViewer.settingsName, 88, false); BytecodeViewer.python = DiskReader.loadString(BytecodeViewer.settingsName, 89, false); BytecodeViewer.rt = DiskReader.loadString(BytecodeViewer.settingsName, 90, false); @@ -410,6 +410,8 @@ public class Settings { BytecodeViewer.python3 = DiskReader.loadString(BytecodeViewer.settingsName, 115, false); BytecodeViewer.javac = DiskReader.loadString(BytecodeViewer.settingsName, 116, false); BytecodeViewer.java = DiskReader.loadString(BytecodeViewer.settingsName, 117, false); + BytecodeViewer.viewer.autoCompileSmali.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 118, false))); + BytecodeViewer.viewer.autoCompileOnRefresh.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 119, false))); } catch (Exception e) { //ignore because errors are expected, first start up and outdated settings. //e.printStackTrace(); diff --git a/src/the/bytecode/club/bytecodeviewer/compilers/JavaCompiler.java b/src/the/bytecode/club/bytecodeviewer/compilers/JavaCompiler.java index 05141550..6a2afa41 100644 --- a/src/the/bytecode/club/bytecodeviewer/compilers/JavaCompiler.java +++ b/src/the/bytecode/club/bytecodeviewer/compilers/JavaCompiler.java @@ -86,12 +86,42 @@ public class JavaCompiler extends Compiler { Process process = pb.start(); BytecodeViewer.createdProcesses.add(process); + Thread failSafe = new Thread() + { + @Override + public void run() + { + long started = System.currentTimeMillis(); + while(System.currentTimeMillis()-started <= 10_000) + { + try + { + Thread.sleep(100); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + + if(process.isAlive()) + { + System.out.println("Force killing javac process, assuming it's gotten stuck"); + process.destroyForcibly().destroy(); + } + } + }; + failSafe.start(); + + int exitValue = process.waitFor(); + //Read out dir output InputStream is = process.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line; - while ((line = br.readLine()) != null) { + while ((line = br.readLine()) != null) + { log += BytecodeViewer.nl + line; } br.close(); @@ -105,7 +135,6 @@ public class JavaCompiler extends Compiler { } br.close(); - int exitValue = process.waitFor(); log += BytecodeViewer.nl + BytecodeViewer.nl + "Exit Value is " + exitValue; System.out.println(log); diff --git a/src/the/bytecode/club/bytecodeviewer/decompilers/FernFlowerDecompiler.java b/src/the/bytecode/club/bytecodeviewer/decompilers/FernFlowerDecompiler.java index d87fc51b..c0799a03 100644 --- a/src/the/bytecode/club/bytecodeviewer/decompilers/FernFlowerDecompiler.java +++ b/src/the/bytecode/club/bytecodeviewer/decompilers/FernFlowerDecompiler.java @@ -71,7 +71,7 @@ public class FernFlowerDecompiler extends Decompiler { @Override public String decompileClassNode(final ClassNode cn, byte[] b) { - String start = MiscUtils.getUniqueName("", ".class"); + String start = BytecodeViewer.tempDirectory + BytecodeViewer.fs+MiscUtils.getUniqueName("", ".class"); final File tempClass = new File(start + ".class"); @@ -95,7 +95,7 @@ public class FernFlowerDecompiler extends Decompiler { try { ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll( new String[]{BytecodeViewer.getJavaCommand(), "-jar", Resources.findLibrary("fernflower")}, - generateMainMethod(tempClass.getAbsolutePath(), ".") + generateMainMethod(tempClass.getAbsolutePath(), new File(BytecodeViewer.tempDirectory).getAbsolutePath()) )); BytecodeViewer.sm.stopBlocking(); Process p = pb.start(); @@ -106,12 +106,23 @@ public class FernFlowerDecompiler extends Decompiler { } finally { BytecodeViewer.sm.setBlocking(); } - } else - org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler.main( - generateMainMethod(tempClass.getAbsolutePath(), ".")); + } + else + { + try + { + org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler.main(generateMainMethod(tempClass.getAbsolutePath(), new File(BytecodeViewer.tempDirectory).getAbsolutePath())); + } + catch(Exception e) + { + e.printStackTrace(); + } + } tempClass.delete(); + System.out.println(start + ".java"); + final File outputJava = new File(start + ".java"); if (outputJava.exists()) { String s; diff --git a/src/the/bytecode/club/bytecodeviewer/decompilers/SmaliDisassembler.java b/src/the/bytecode/club/bytecodeviewer/decompilers/SmaliDisassembler.java index c4eedf1d..20961052 100644 --- a/src/the/bytecode/club/bytecodeviewer/decompilers/SmaliDisassembler.java +++ b/src/the/bytecode/club/bytecodeviewer/decompilers/SmaliDisassembler.java @@ -43,7 +43,7 @@ public class SmaliDisassembler extends Decompiler { String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp"; - String start = MiscUtils.getUniqueName(fileStart, ".class"); + String start = BytecodeViewer.tempDirectory + BytecodeViewer.fs+MiscUtils.getUniqueName(fileStart, ".class"); final File tempClass = new File(start + ".class"); final File tempZip = new File(start + ".jar"); diff --git a/src/the/bytecode/club/bytecodeviewer/gui/ClassViewer.java b/src/the/bytecode/club/bytecodeviewer/gui/ClassViewer.java index f657b37c..6a7bbf3d 100644 --- a/src/the/bytecode/club/bytecodeviewer/gui/ClassViewer.java +++ b/src/the/bytecode/club/bytecodeviewer/gui/ClassViewer.java @@ -628,6 +628,7 @@ public class ClassViewer extends Viewer { } catch (InterruptedException e1) { } } + final byte[] b = cw.toByteArray(); Thread t1 = new PaneUpdaterThread() { @Override @@ -1722,6 +1723,18 @@ public class ClassViewer extends Viewer { } }; t.start(); + + if(isPanel1Editable() || isPanel2Editable() || isPanel3Editable()) + { + if(!BytecodeViewer.warnForEditing) + { + BytecodeViewer.warnForEditing = true; + if(!BytecodeViewer.viewer.autoCompileOnRefresh.isSelected() && !BytecodeViewer.viewer.autoCompileSmali.isSelected()) + { + BytecodeViewer.showMessage("Make sure to File>Compile (Ctrl + T) whenever you want to test or export your changes.\nYou can set compile automatically on refresh or on save in the settings menu."); + } + } + } } public Object[] getSmali() { diff --git a/src/the/bytecode/club/bytecodeviewer/gui/FileNavigationPane.java b/src/the/bytecode/club/bytecodeviewer/gui/FileNavigationPane.java index 031f8f87..4d0f1558 100644 --- a/src/the/bytecode/club/bytecodeviewer/gui/FileNavigationPane.java +++ b/src/the/bytecode/club/bytecodeviewer/gui/FileNavigationPane.java @@ -92,8 +92,12 @@ public class FileNavigationPane extends VisibleComponent implements final String qt = quickSearch.getText(); quickSearch.setText(""); + if(qt.isEmpty()) //NOPE + return; + String[] path = null; + int found = 0; if (qt.contains(".")) { path = qt.split("\\."); @@ -122,12 +126,18 @@ public class FileNavigationPane extends VisibleComponent implements if (((String) child.getUserObject()).equals(pathName)) { curNode = child; if (isLast) { + System.out.println("Found! " + curNode); + found++; + if(found >= 30) + { + BytecodeViewer.showMessage("Uh oh, there could be more results but you've triggered the 30 classes at once limit. Try refining your search."); + return; + } final TreePath pathn = new TreePath(curNode.getPath()); tree.setSelectionPath(pathn); tree.makeVisible(pathn); tree.scrollPathToVisible(pathn); openPath(pathn); //auto open - System.out.println("Found! " + curNode); break pathLoop; } continue pathLoop; @@ -161,6 +171,12 @@ public class FileNavigationPane extends VisibleComponent implements String fullPathString = fullPath.toString(); if (fullPathString != null && fullPathString.toLowerCase().contains(qt.toLowerCase())) { System.out.println("Found! " + node); + found++; + if(found >= 30) + { + BytecodeViewer.showMessage("Uh oh, there could be more results but you've triggered the 30 classes at once limit. Try refining your search."); + return; + } final TreePath pathn = new TreePath(node.getPath()); tree.setSelectionPath(pathn.getParentPath()); tree.setSelectionPath(pathn); @@ -221,29 +237,33 @@ public class FileNavigationPane extends VisibleComponent implements this.tree.addKeyListener(new KeyListener() { @Override - public void keyReleased(KeyEvent arg0) { - if (arg0.getKeyCode() == KeyEvent.VK_ENTER) { - if (arg0.getSource() instanceof MyTree) { - MyTree tree = (MyTree) arg0.getSource(); - openPath(tree.getSelectionPath()); - } - } else { - cancel = true; - } + public void keyReleased(KeyEvent e) { } @Override public void keyTyped(KeyEvent e) { - quickSearch.grabFocus(); - quickSearch.setText("" + e.getKeyChar()); // fuck - cancel = true; } @Override public void keyPressed(KeyEvent e) { - quickSearch.grabFocus(); - quickSearch.setText("" + e.getKeyChar()); // fuck - cancel = true; + if (e.getKeyCode() == KeyEvent.VK_ENTER) + { + if (e.getSource() instanceof MyTree) + { + MyTree tree = (MyTree) e.getSource(); + openPath(tree.getSelectionPath()); + } + } + else if((int)e.getKeyChar() != 0 && (int)e.getKeyChar() != 65535) + { + quickSearch.grabFocus(); + quickSearch.setText("" + e.getKeyChar()); + cancel = true; + } + else + { + cancel = true; + } } }); diff --git a/src/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java b/src/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java index 571449af..ea6f3a6b 100644 --- a/src/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java +++ b/src/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java @@ -1601,10 +1601,10 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { mnPane_1.add(panel3Hexcode); menuBar.add(mnSettings); - autoCompileSmali.setSelected(true); + autoCompileSmali.setSelected(false); mnSettings.add(autoCompileSmali); - autoCompileOnRefresh.setSelected(true); + autoCompileOnRefresh.setSelected(false); mnSettings.add(autoCompileOnRefresh);