Code Style Cleanup / General Code Improvements

This commit is contained in:
Konloch 2024-09-27 05:51:50 -06:00
parent 3ab993242e
commit 9353c968be

AI 샘플 코드 생성 중입니다

Loading...
84 changed files with 546 additions and 386 deletions

View File

@ -68,7 +68,7 @@ public class Constants
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");
public static final String[] SUPPORTED_FILE_EXTENSIONS = ResourceType.supportedBCVExtensionMap.keySet().toArray(new String[0]); public static final String[] SUPPORTED_FILE_EXTENSIONS = ResourceType.SUPPORTED_BCV_EXTENSION_MAP.keySet().toArray(new String[0]);
public static final int ASM_VERSION = Opcodes.ASM9; public static final int ASM_VERSION = Opcodes.ASM9;
public static final File BCVDir = resolveBCVRoot(); public static final File BCVDir = resolveBCVRoot();

View File

@ -106,6 +106,7 @@ public class GlobalHotKeys
JFileChooser fc = new FileChooser(Configuration.getLastSaveDirectory(), "Select Zip Export", "Zip Archives", "zip"); JFileChooser fc = new FileChooser(Configuration.getLastSaveDirectory(), "Select Zip Export", "Zip Archives", "zip");
int returnVal = fc.showSaveDialog(BytecodeViewer.viewer); int returnVal = fc.showSaveDialog(BytecodeViewer.viewer);
if (returnVal == JFileChooser.APPROVE_OPTION) if (returnVal == JFileChooser.APPROVE_OPTION)
{ {
Configuration.setLastSaveDirectory(fc.getSelectedFile()); Configuration.setLastSaveDirectory(fc.getSelectedFile());
@ -124,6 +125,7 @@ public class GlobalHotKeys
jarExport.start(); jarExport.start();
} }
}, "Resource Export"); }, "Resource Export");
resourceExport.start(); resourceExport.start();
} }

View File

@ -127,32 +127,38 @@ public class Settings
{ {
//build recent files //build recent files
BytecodeViewer.viewer.recentFilesSecondaryMenu.removeAll(); BytecodeViewer.viewer.recentFilesSecondaryMenu.removeAll();
for (String s : recentFiles) for (String s : recentFiles)
{ {
if (!s.isEmpty()) if (!s.isEmpty())
{ {
JMenuItem m = new JMenuItem(s); JMenuItem m = new JMenuItem(s);
m.addActionListener(e -> m.addActionListener(e ->
{ {
JMenuItem m12 = (JMenuItem) e.getSource(); JMenuItem m12 = (JMenuItem) e.getSource();
BytecodeViewer.openFiles(new File[]{new File(m12.getText())}, true); BytecodeViewer.openFiles(new File[]{new File(m12.getText())}, true);
}); });
BytecodeViewer.viewer.recentFilesSecondaryMenu.add(m); BytecodeViewer.viewer.recentFilesSecondaryMenu.add(m);
} }
} }
//build recent plugins //build recent plugins
BytecodeViewer.viewer.recentPluginsSecondaryMenu.removeAll(); BytecodeViewer.viewer.recentPluginsSecondaryMenu.removeAll();
for (String s : recentPlugins) for (String s : recentPlugins)
{ {
if (!s.isEmpty()) if (!s.isEmpty())
{ {
JMenuItem m = new JMenuItem(s); JMenuItem m = new JMenuItem(s);
m.addActionListener(e -> m.addActionListener(e ->
{ {
JMenuItem m1 = (JMenuItem) e.getSource(); JMenuItem m1 = (JMenuItem) e.getSource();
BytecodeViewer.startPlugin(new File(m1.getText())); BytecodeViewer.startPlugin(new File(m1.getText()));
}); });
BytecodeViewer.viewer.recentPluginsSecondaryMenu.add(m); BytecodeViewer.viewer.recentPluginsSecondaryMenu.add(m);
} }
} }

View File

@ -338,11 +338,13 @@ public class SettingsSerializer
BytecodeViewer.viewer.refreshOnChange.setSelected(asBoolean(84)); BytecodeViewer.viewer.refreshOnChange.setSelected(asBoolean(84));
boolean bool = Boolean.parseBoolean(asString(85)); boolean bool = Boolean.parseBoolean(asString(85));
if (bool) if (bool)
{ {
BytecodeViewer.viewer.setExtendedState(JFrame.MAXIMIZED_BOTH); BytecodeViewer.viewer.setExtendedState(JFrame.MAXIMIZED_BOTH);
BytecodeViewer.viewer.isMaximized = true; BytecodeViewer.viewer.isMaximized = true;
} }
//86 is deprecated //86 is deprecated
//87 is deprecated //87 is deprecated
Configuration.lastOpenDirectory = asString(88); Configuration.lastOpenDirectory = asString(88);
@ -388,6 +390,7 @@ public class SettingsSerializer
//line 130 is used for preload //line 130 is used for preload
if (Configuration.language != Language.ENGLISH) if (Configuration.language != Language.ENGLISH)
Configuration.language.setLanguageTranslations(); //load language translations Configuration.language.setLanguageTranslations(); //load language translations
Settings.hasSetLanguageAsSystemLanguage = true; Settings.hasSetLanguageAsSystemLanguage = true;
BytecodeViewer.viewer.viewPane1.setPaneEditable(asBoolean(131)); BytecodeViewer.viewer.viewPane1.setPaneEditable(asBoolean(131));

View File

@ -43,20 +43,23 @@ public class JavaCompiler extends InternalCompiler
@Override @Override
public byte[] compile(String contents, String fullyQualifiedName) public byte[] compile(String contents, String fullyQualifiedName)
{ {
String fileStart = TEMP_DIRECTORY + FS + "temp" + MiscUtils.randomString(12) + FS; final String fileStart = TEMP_DIRECTORY + FS + "temp" + MiscUtils.randomString(12) + FS;
String fileStart2 = TEMP_DIRECTORY + FS + "temp" + MiscUtils.randomString(12) + FS; final String fileStart2 = TEMP_DIRECTORY + FS + "temp" + MiscUtils.randomString(12) + FS;
File java = new File(fileStart + FS + fullyQualifiedName + ".java");
File clazz = new File(fileStart2 + FS + fullyQualifiedName + ".class"); final File javaFile = new File(fileStart + FS + fullyQualifiedName + ".java");
File cp = new File(TEMP_DIRECTORY + FS + "cpath_" + MiscUtils.randomString(12) + ".jar"); final File classFile = new File(fileStart2 + FS + fullyQualifiedName + ".class");
File tempD = new File(fileStart + FS + fullyQualifiedName.substring(0, fullyQualifiedName.length() - final File classPath = new File(TEMP_DIRECTORY + FS + "cpath_" + MiscUtils.randomString(12) + ".jar");
final File tempDirectory = new File(fileStart + FS + fullyQualifiedName.substring(0, fullyQualifiedName.length() -
fullyQualifiedName.split("/")[fullyQualifiedName.split("/").length - 1].length())); fullyQualifiedName.split("/")[fullyQualifiedName.split("/").length - 1].length()));
tempD.mkdirs(); //create the temp directories
tempDirectory.mkdirs();
new File(fileStart2).mkdirs(); new File(fileStart2).mkdirs();
if (Configuration.javac.isEmpty() || !new File(Configuration.javac).exists()) if (Configuration.javac.isEmpty() || !new File(Configuration.javac).exists())
{ {
BytecodeViewer.showMessage("You need to set your Javac path, this requires the JDK to be downloaded." + NL + "(C:/Program Files/Java/JDK_xx/bin/javac.exe)"); BytecodeViewer.showMessage("You need to set your Javac path, this requires the JDK to be downloaded."
+ NL + "(C:/Program Files/Java/JDK_xx/bin/javac.exe)");
ExternalResources.getSingleton().selectJavac(); ExternalResources.getSingleton().selectJavac();
} }
@ -66,8 +69,11 @@ public class JavaCompiler extends InternalCompiler
return null; return null;
} }
DiskWriter.replaceFile(java.getAbsolutePath(), contents, false); //write the file we're assembling to disk
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), cp.getAbsolutePath()); DiskWriter.replaceFile(javaFile.getAbsolutePath(), contents, false);
//write the entire temporary classpath to disk
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), classPath.getAbsolutePath());
boolean cont = true; boolean cont = true;
try try
@ -77,10 +83,10 @@ public class JavaCompiler extends InternalCompiler
if (Configuration.library.isEmpty()) if (Configuration.library.isEmpty())
pb = new ProcessBuilder(Configuration.javac, "-d", fileStart2, pb = new ProcessBuilder(Configuration.javac, "-d", fileStart2,
"-classpath", cp.getAbsolutePath(), java.getAbsolutePath()); "-classpath", classPath.getAbsolutePath(), javaFile.getAbsolutePath());
else else
pb = new ProcessBuilder(Configuration.javac, "-d", fileStart2, pb = new ProcessBuilder(Configuration.javac, "-d", fileStart2,
"-classpath", cp.getAbsolutePath() + System.getProperty("path.separator") + Configuration.library, java.getAbsolutePath()); "-classpath", classPath.getAbsolutePath() + System.getProperty("path.separator") + Configuration.library, javaFile.getAbsolutePath());
Process process = pb.start(); Process process = pb.start();
BytecodeViewer.createdProcesses.add(process); BytecodeViewer.createdProcesses.add(process);
@ -111,6 +117,7 @@ public class JavaCompiler extends InternalCompiler
} }
log.append(NL).append(NL).append(TranslatedStrings.ERROR2).append(NL).append(NL); log.append(NL).append(NL).append(TranslatedStrings.ERROR2).append(NL).append(NL);
try (InputStream is = process.getErrorStream(); try (InputStream is = process.getErrorStream();
InputStreamReader isr = new InputStreamReader(is); InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr)) BufferedReader br = new BufferedReader(isr))
@ -123,7 +130,7 @@ public class JavaCompiler extends InternalCompiler
log.append(NL).append(NL).append(TranslatedStrings.EXIT_VALUE_IS).append(" ").append(exitValue); log.append(NL).append(NL).append(TranslatedStrings.EXIT_VALUE_IS).append(" ").append(exitValue);
System.out.println(log); System.out.println(log);
if (!clazz.exists()) if (!classFile.exists())
throw new Exception(log.toString()); throw new Exception(log.toString());
} }
catch (Exception e) catch (Exception e)
@ -132,12 +139,12 @@ public class JavaCompiler extends InternalCompiler
e.printStackTrace(); e.printStackTrace();
} }
cp.delete(); classPath.delete();
if (cont) if (cont)
try try
{ {
return org.apache.commons.io.FileUtils.readFileToByteArray(clazz); return org.apache.commons.io.FileUtils.readFileToByteArray(classFile);
} }
catch (IOException e) catch (IOException e)
{ {

View File

@ -51,16 +51,19 @@ public class KrakatauAssembler extends InternalCompiler
if (!ExternalResources.getSingleton().hasSetPython2Command()) if (!ExternalResources.getSingleton().hasSetPython2Command())
return null; return null;
File tempD = new File(Constants.TEMP_DIRECTORY + FS + MiscUtils.randomString(32) + FS); final File tempDirectory1 = new File(Constants.TEMP_DIRECTORY + FS + MiscUtils.randomString(32) + FS);
tempD.mkdir(); final File tempDirectory2 = new File(Constants.TEMP_DIRECTORY + FS + MiscUtils.randomString(32) + FS);
final File javaFile = new File(tempDirectory1.getAbsolutePath() + FS + fullyQualifiedName + ".j");
File tempJ = new File(tempD.getAbsolutePath() + FS + fullyQualifiedName + ".j");
DiskWriter.replaceFile(tempJ.getAbsolutePath(), contents, true);
final File tempDirectory = new File(Constants.TEMP_DIRECTORY + FS + MiscUtils.randomString(32) + FS);
tempDirectory.mkdir();
final File tempJar = new File(Constants.TEMP_DIRECTORY + FS + "temp" + MiscUtils.randomString(32) + ".jar"); final File tempJar = new File(Constants.TEMP_DIRECTORY + FS + "temp" + MiscUtils.randomString(32) + ".jar");
//create the temp directories
tempDirectory1.mkdir();
tempDirectory2.mkdir();
//write the file we're assembling to disk
DiskWriter.replaceFile(javaFile.getAbsolutePath(), contents, true);
//write the entire temporary classpath to disk
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath()); JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
StringBuilder log = new StringBuilder(); StringBuilder log = new StringBuilder();
@ -72,7 +75,7 @@ public class KrakatauAssembler extends InternalCompiler
pythonCommands = ArrayUtils.addAll(pythonCommands, "-2"); pythonCommands = ArrayUtils.addAll(pythonCommands, "-2");
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(pythonCommands, "-O", //love you storyyeller <3 ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(pythonCommands, "-O", //love you storyyeller <3
krakatauWorkingDirectory + FS + "assemble.py", "-out", tempDirectory.getAbsolutePath(), tempJ.getAbsolutePath())); krakatauWorkingDirectory + FS + "assemble.py", "-out", tempDirectory2.getAbsolutePath(), javaFile.getAbsolutePath()));
Process process = pb.start(); Process process = pb.start();
BytecodeViewer.createdProcesses.add(process); BytecodeViewer.createdProcesses.add(process);
@ -101,10 +104,15 @@ public class KrakatauAssembler extends InternalCompiler
log.append(NL).append(NL).append(TranslatedStrings.EXIT_VALUE_IS).append(" ").append(exitValue); log.append(NL).append(NL).append(TranslatedStrings.EXIT_VALUE_IS).append(" ").append(exitValue);
System.err.println(log); System.err.println(log);
byte[] b = FileUtils.readFileToByteArray(Objects.requireNonNull(ExternalResources.getSingleton().findFile(tempDirectory, ".class"))); //read the assembled bytes from disk
tempDirectory.delete(); byte[] assembledBytes = FileUtils.readFileToByteArray(Objects.requireNonNull(ExternalResources.getSingleton().findFile(tempDirectory2, ".class")));
//cleanup
tempDirectory2.delete();
tempJar.delete(); tempJar.delete();
return b;
//return the assembled file
return assembledBytes;
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -44,19 +44,21 @@ public class SmaliAssembler extends InternalCompiler
@Override @Override
public byte[] compile(String contents, String fullyQualifiedName) public byte[] compile(String contents, String fullyQualifiedName)
{ {
String fileStart = TEMP_DIRECTORY + FS + "temp"; final String fileStart = TEMP_DIRECTORY + FS + "temp";
int fileNumber = MiscUtils.getClassNumber(fileStart, ".dex"); final int fileNumber = MiscUtils.getClassNumber(fileStart, ".dex");
final File tempSmaliFolder = new File(fileStart + fileNumber + "-smalifolder" + FS); final File tempSmaliFolder = new File(fileStart + fileNumber + "-smalifolder" + FS);
tempSmaliFolder.mkdir();
File tempSmali = new File(tempSmaliFolder.getAbsolutePath() + FS + fileNumber + ".smali"); final File tempSmali = new File(tempSmaliFolder.getAbsolutePath() + FS + fileNumber + ".smali");
File tempDex = new File("./out.dex"); final File tempDex = new File("./out.dex");
File tempJar = new File(fileStart + fileNumber + ".jar"); final File tempJar = new File(fileStart + fileNumber + ".jar");
File tempJarFolder = new File(fileStart + fileNumber + "-jar" + FS); final File tempJarFolder = new File(fileStart + fileNumber + "-jar" + FS);
//create the temp directory
tempSmaliFolder.mkdir();
try try
{ {
//write the file we're assembling to disk
DiskWriter.replaceFile(tempSmali.getAbsolutePath(), contents, false); DiskWriter.replaceFile(tempSmali.getAbsolutePath(), contents, false);
} }
catch (Exception e) catch (Exception e)
@ -107,6 +109,7 @@ public class SmaliAssembler extends InternalCompiler
System.out.println("Saved as: " + outputClass.getAbsolutePath()); System.out.println("Saved as: " + outputClass.getAbsolutePath());
//return the assembled file
return FileUtils.readFileToByteArray(outputClass); return FileUtils.readFileToByteArray(outputClass);
} }
catch (java.lang.NullPointerException ignored) catch (java.lang.NullPointerException ignored)

View File

@ -27,7 +27,7 @@ import org.objectweb.asm.tree.ClassNode;
*/ */
public abstract class InternalDecompiler public abstract class InternalDecompiler
{ {
public abstract String decompileClassNode(ClassNode cn, byte[] b); public abstract String decompileClassNode(ClassNode cn, byte[] bytes);
public abstract void decompileToZip(String sourceJar, String zipName); public abstract void decompileToZip(String sourceJar, String zipName);
} }

View File

@ -37,11 +37,14 @@ public class FieldNodeDecompiler
{ {
String s = getAccessString(f.access); String s = getAccessString(f.access);
sb.append(s); sb.append(s);
if (s.length() > 0) if (s.length() > 0)
sb.append(" "); sb.append(" ");
sb.append(Type.getType(f.desc).getClassName()); sb.append(Type.getType(f.desc).getClassName());
sb.append(" "); sb.append(" ");
sb.append(f.name); sb.append(f.name);
if (f.value != null) if (f.value != null)
{ {
sb.append(" = "); sb.append(" = ");
@ -59,13 +62,16 @@ public class FieldNodeDecompiler
sb.append(")"); sb.append(")");
} }
} }
sb.append(";"); sb.append(";");
return sb; return sb;
} }
private static String getAccessString(int access) private static String getAccessString(int access)
{ {
List<String> tokens = new ArrayList<>(); List<String> tokens = new ArrayList<>();
if ((access & Opcodes.ACC_PUBLIC) != 0) if ((access & Opcodes.ACC_PUBLIC) != 0)
tokens.add("public"); tokens.add("public");
if ((access & Opcodes.ACC_PRIVATE) != 0) if ((access & Opcodes.ACC_PRIVATE) != 0)
@ -84,6 +90,7 @@ public class FieldNodeDecompiler
tokens.add("volatile"); tokens.add("volatile");
if (tokens.size() == 0) if (tokens.size() == 0)
return ""; return "";
// hackery delimeters // hackery delimeters
StringBuilder sb = new StringBuilder(tokens.get(0)); StringBuilder sb = new StringBuilder(tokens.get(0));
for (int i = 1; i < tokens.size(); i++) for (int i = 1; i < tokens.size(); i++)
@ -91,6 +98,7 @@ public class FieldNodeDecompiler
sb.append(" "); sb.append(" ");
sb.append(tokens.get(i)); sb.append(tokens.get(i));
} }
return sb.toString(); return sb.toString();
} }
} }

View File

@ -61,8 +61,6 @@ public class InstructionPrinter implements Opcodes
mNode = m; mNode = m;
labels = new HashMap<>(); labels = new HashMap<>();
precalculateLabelIndexes(m); precalculateLabelIndexes(m);
// matchedInsns = new ArrayList<AbstractInsnNode>(); // ingnored because
// match = false
match = false; match = false;
} }
@ -125,97 +123,39 @@ public class InstructionPrinter implements Opcodes
{ {
String line = ""; String line = "";
if (ain instanceof VarInsnNode) if (ain instanceof VarInsnNode)
{
line = printVarInsnNode((VarInsnNode) ain); line = printVarInsnNode((VarInsnNode) ain);
}
else if (ain instanceof IntInsnNode) else if (ain instanceof IntInsnNode)
{
line = printIntInsnNode((IntInsnNode) ain); line = printIntInsnNode((IntInsnNode) ain);
}
else if (ain instanceof FieldInsnNode) else if (ain instanceof FieldInsnNode)
{
line = printFieldInsnNode((FieldInsnNode) ain); line = printFieldInsnNode((FieldInsnNode) ain);
}
else if (ain instanceof MethodInsnNode) else if (ain instanceof MethodInsnNode)
{
line = printMethodInsnNode((MethodInsnNode) ain); line = printMethodInsnNode((MethodInsnNode) ain);
}
else if (ain instanceof LdcInsnNode) else if (ain instanceof LdcInsnNode)
{
line = printLdcInsnNode((LdcInsnNode) ain); line = printLdcInsnNode((LdcInsnNode) ain);
}
else if (ain instanceof InsnNode) else if (ain instanceof InsnNode)
{
line = printInsnNode((InsnNode) ain); line = printInsnNode((InsnNode) ain);
}
else if (ain instanceof JumpInsnNode) else if (ain instanceof JumpInsnNode)
{
line = printJumpInsnNode((JumpInsnNode) ain); line = printJumpInsnNode((JumpInsnNode) ain);
}
else if (ain instanceof LineNumberNode) else if (ain instanceof LineNumberNode)
{
line = printLineNumberNode((LineNumberNode) ain); line = printLineNumberNode((LineNumberNode) ain);
}
else if (ain instanceof LabelNode) else if (ain instanceof LabelNode)
{
if (firstLabel && BytecodeViewer.viewer.appendBracketsToLabels.isSelected())
info.add("}");
LabelNode label = (LabelNode) ain;
if (mNode.tryCatchBlocks != null)
{
List<TryCatchBlockNode> tcbs = mNode.tryCatchBlocks;
String starting = tcbs.stream().filter(tcb -> tcb.start == label).map(tcb -> "start TCB" + tcbs.indexOf(tcb)).collect(Collectors.joining(", "));
String ending = tcbs.stream().filter(tcb -> tcb.end == label).map(tcb -> "end TCB" + tcbs.indexOf(tcb)).collect(Collectors.joining(", "));
String handlers = tcbs.stream().filter(tcb -> tcb.handler == label).map(tcb -> "handle TCB" + tcbs.indexOf(tcb)).collect(Collectors.joining(", "));
if (!ending.isEmpty())
info.add("// " + ending);
if (!starting.isEmpty())
info.add("// " + starting);
if (!handlers.isEmpty())
info.add("// " + handlers);
}
line = printLabelNode((LabelNode) ain); line = printLabelNode((LabelNode) ain);
if (BytecodeViewer.viewer.appendBracketsToLabels.isSelected())
{
if (!firstLabel)
firstLabel = true;
line += " {";
}
}
else if (ain instanceof TypeInsnNode) else if (ain instanceof TypeInsnNode)
{
line = printTypeInsnNode((TypeInsnNode) ain); line = printTypeInsnNode((TypeInsnNode) ain);
}
else if (ain instanceof FrameNode) else if (ain instanceof FrameNode)
{
line = printFrameNode((FrameNode) ain); line = printFrameNode((FrameNode) ain);
}
else if (ain instanceof IincInsnNode) else if (ain instanceof IincInsnNode)
{
line = printIincInsnNode((IincInsnNode) ain); line = printIincInsnNode((IincInsnNode) ain);
}
else if (ain instanceof TableSwitchInsnNode) else if (ain instanceof TableSwitchInsnNode)
{
line = printTableSwitchInsnNode((TableSwitchInsnNode) ain); line = printTableSwitchInsnNode((TableSwitchInsnNode) ain);
}
else if (ain instanceof LookupSwitchInsnNode) else if (ain instanceof LookupSwitchInsnNode)
{
line = printLookupSwitchInsnNode((LookupSwitchInsnNode) ain); line = printLookupSwitchInsnNode((LookupSwitchInsnNode) ain);
}
else if (ain instanceof InvokeDynamicInsnNode) else if (ain instanceof InvokeDynamicInsnNode)
{
line = printInvokeDynamicInsNode((InvokeDynamicInsnNode) ain); line = printInvokeDynamicInsNode((InvokeDynamicInsnNode) ain);
}
else if (ain instanceof MultiANewArrayInsnNode) else if (ain instanceof MultiANewArrayInsnNode)
{
line = printMultiANewArrayInsNode((MultiANewArrayInsnNode) ain); line = printMultiANewArrayInsNode((MultiANewArrayInsnNode) ain);
}
else else
{
line += "UNADDED OPCODE: " + nameOpcode(ain.getOpcode()) + " " + ain; line += "UNADDED OPCODE: " + nameOpcode(ain.getOpcode()) + " " + ain;
}
return line; return line;
} }
@ -312,11 +252,44 @@ public class InstructionPrinter implements Opcodes
return ""; return "";
} }
protected String printLabelNode(LabelNode label) protected String printOnlyLabelNode(LabelNode label)
{ {
return "L" + resolveLabel(label); return "L" + resolveLabel(label);
} }
protected String printLabelNode(LabelNode label)
{
if (firstLabel && BytecodeViewer.viewer.appendBracketsToLabels.isSelected())
info.add("}");
String line = "";
if (mNode.tryCatchBlocks != null)
{
List<TryCatchBlockNode> tcbs = mNode.tryCatchBlocks;
String starting = tcbs.stream().filter(tcb -> tcb.start == label).map(tcb -> "start TCB" + tcbs.indexOf(tcb)).collect(Collectors.joining(", "));
String ending = tcbs.stream().filter(tcb -> tcb.end == label).map(tcb -> "end TCB" + tcbs.indexOf(tcb)).collect(Collectors.joining(", "));
String handlers = tcbs.stream().filter(tcb -> tcb.handler == label).map(tcb -> "handle TCB" + tcbs.indexOf(tcb)).collect(Collectors.joining(", "));
if (!ending.isEmpty())
info.add("// " + ending);
if (!starting.isEmpty())
info.add("// " + starting);
if (!handlers.isEmpty())
info.add("// " + handlers);
}
line = printOnlyLabelNode(label);
if (BytecodeViewer.viewer.appendBracketsToLabels.isSelected())
{
if (!firstLabel)
firstLabel = true;
line += " {";
}
return line;
}
protected String printTypeInsnNode(TypeInsnNode tin) protected String printTypeInsnNode(TypeInsnNode tin)
{ {
try try
@ -403,6 +376,7 @@ public class InstructionPrinter implements Opcodes
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(nameFrameType(frame.type)).append(" "); sb.append(nameFrameType(frame.type)).append(" ");
sb.append("(Locals"); sb.append("(Locals");
if (frame.local != null && !frame.local.isEmpty()) if (frame.local != null && !frame.local.isEmpty())
{ {
@ -490,15 +464,13 @@ public class InstructionPrinter implements Opcodes
protected int resolveLabel(LabelNode label) protected int resolveLabel(LabelNode label)
{ {
if (labels.containsKey(label)) if (labels.containsKey(label))
{
return labels.get(label); return labels.get(label);
}
else else
{ {
/*int newLabelIndex = labels.size() + 1; //NOTE: Should NEVER enter this state, but if it ever does, here's the fall-back solution
int newLabelIndex = labels.size() + 1;
labels.put(label, newLabelIndex); labels.put(label, newLabelIndex);
return newLabelIndex;*/ return newLabelIndex;
throw new IllegalStateException("LabelNode index not found. (Label not in InsnList?)");
} }
} }

View File

@ -36,7 +36,6 @@ public class InstructionSearcher implements Opcodes
protected InsnList insns; protected InsnList insns;
protected InstructionPattern pattern; protected InstructionPattern pattern;
protected List<AbstractInsnNode[]> matches; protected List<AbstractInsnNode[]> matches;
public InstructionSearcher(InsnList insns, int[] opcodes) public InstructionSearcher(InsnList insns, int[] opcodes)
@ -62,6 +61,7 @@ public class InstructionSearcher implements Opcodes
{ {
if (ain instanceof LineNumberNode || ain instanceof FrameNode) if (ain instanceof LineNumberNode || ain instanceof FrameNode)
continue; continue;
if (pattern.accept(ain)) if (pattern.accept(ain))
{ {
matches.add(pattern.getLastMatch()); matches.add(pattern.getLastMatch());

View File

@ -40,14 +40,17 @@ public class MethodNodeDecompiler
public static PrefixedStringBuilder decompile(PrefixedStringBuilder sb, MethodNode m, ClassNode cn) public static PrefixedStringBuilder decompile(PrefixedStringBuilder sb, MethodNode m, ClassNode cn)
{ {
String className; String className;
if (cn.name.contains("/")) if (cn.name.contains("/"))
className = cn.name.substring(cn.name.lastIndexOf("/") + 1); className = cn.name.substring(cn.name.lastIndexOf("/") + 1);
else else
className = cn.name; className = cn.name;
String s = getAccessString(m.access); String s = getAccessString(m.access);
sb.append(" "); sb.append(" ");
sb.append(s); sb.append(s);
if (s.length() > 0) if (s.length() > 0)
sb.append(" "); sb.append(" ");
@ -73,7 +76,6 @@ public class MethodNodeDecompiler
for (int i = 0; i < argTypes.length; i++) for (int i = 0; i < argTypes.length; i++)
{ {
final Type type = argTypes[i]; final Type type = argTypes[i];
final TypeAndName tan = new TypeAndName(); final TypeAndName tan = new TypeAndName();
final String argName = "arg" + i; final String argName = "arg" + i;
@ -89,10 +91,12 @@ public class MethodNodeDecompiler
} }
int amountOfThrows = m.exceptions.size(); int amountOfThrows = m.exceptions.size();
if (amountOfThrows > 0) if (amountOfThrows > 0)
{ {
sb.append(" throws "); sb.append(" throws ");
sb.append(m.exceptions.get(0));// exceptions is list<string> sb.append(m.exceptions.get(0));// exceptions is list<string>
for (int i = 1; i < amountOfThrows; i++) for (int i = 1; i < amountOfThrows; i++)
{ {
sb.append(", "); sb.append(", ");
@ -109,7 +113,6 @@ public class MethodNodeDecompiler
} }
else else
{ {
sb.append(" {"); sb.append(" {");
if (BytecodeViewer.viewer.debugHelpers.isSelected()) if (BytecodeViewer.viewer.debugHelpers.isSelected())
@ -161,10 +164,12 @@ public class MethodNodeDecompiler
sb.append(" handled by L"); sb.append(" handled by L");
sb.append(insnPrinter.resolveLabel(o.handler)); sb.append(insnPrinter.resolveLabel(o.handler));
sb.append(": "); sb.append(": ");
if (o.type != null) if (o.type != null)
sb.append(o.type); sb.append(o.type);
else else
sb.append("Type is null."); sb.append("Type is null.");
sb.append(NL); sb.append(NL);
} }
@ -174,8 +179,10 @@ public class MethodNodeDecompiler
sb.append(insn); sb.append(insn);
sb.append(NL); sb.append(NL);
} }
sb.append(" }" + NL); sb.append(" }" + NL);
} }
return sb; return sb;
} }
@ -194,6 +201,7 @@ public class MethodNodeDecompiler
sb.append(">"); sb.append(">");
sb.append(NL); sb.append(NL);
} }
sb.append(NL); sb.append(NL);
} }
} }
@ -203,7 +211,8 @@ public class MethodNodeDecompiler
if (o instanceof LocalVariableNode) if (o instanceof LocalVariableNode)
{ {
LocalVariableNode lvn = (LocalVariableNode) o; LocalVariableNode lvn = (LocalVariableNode) o;
return "index=" + lvn.index + " , name=" + lvn.name + " , desc=" + lvn.desc + ", sig=" + lvn.signature + ", start=L" + insnPrinter.resolveLabel(lvn.start) + ", end=L" + insnPrinter.resolveLabel(lvn.end); return "index=" + lvn.index + " , name=" + lvn.name + " , desc=" + lvn.desc + ", sig=" + lvn.signature
+ ", start=L" + insnPrinter.resolveLabel(lvn.start) + ", end=L" + insnPrinter.resolveLabel(lvn.end);
} }
else if (o instanceof AnnotationNode) else if (o instanceof AnnotationNode)
{ {
@ -212,6 +221,7 @@ public class MethodNodeDecompiler
sb.append("desc = "); sb.append("desc = ");
sb.append(an.desc); sb.append(an.desc);
sb.append(" , values = "); sb.append(" , values = ");
if (an.values != null) if (an.values != null)
{ {
sb.append(Arrays.toString(an.values.toArray())); sb.append(Arrays.toString(an.values.toArray()));
@ -220,10 +230,13 @@ public class MethodNodeDecompiler
{ {
sb.append("[]"); sb.append("[]");
} }
return sb.toString(); return sb.toString();
} }
if (o == null) if (o == null)
return ""; return "";
return o.toString(); return o.toString();
} }
@ -258,6 +271,7 @@ public class MethodNodeDecompiler
tokens.add("varargs"); tokens.add("varargs");
if (tokens.isEmpty()) if (tokens.isEmpty())
return ""; return "";
// hackery delimeters // hackery delimeters
StringBuilder sb = new StringBuilder(tokens.get(0)); StringBuilder sb = new StringBuilder(tokens.get(0));
for (int i = 1; i < tokens.size(); i++) for (int i = 1; i < tokens.size(); i++)
@ -265,6 +279,7 @@ public class MethodNodeDecompiler
sb.append(" "); sb.append(" ");
sb.append(tokens.get(i)); sb.append(tokens.get(i));
} }
return sb.toString(); return sb.toString();
} }
} }

View File

@ -36,15 +36,11 @@ public class PrefixedStringBuilder
public PrefixedStringBuilder append(String s) public PrefixedStringBuilder append(String s)
{ {
sb.append(s); sb.append(s);
if (s.contains("\n") && (prefix != null) && (prefix.length() > 0))// insert
// the // insert the prefix at every new line, overridable
// prefix if (s.contains("\n") && (prefix != null) && (prefix.length() > 0))
// at
// every
// new
// line,
// overridable
sb.append(prefix); sb.append(prefix);
return this; return this;
} }

View File

@ -34,7 +34,7 @@ import java.io.StringWriter;
public class ASMTextifierDisassembler extends InternalDecompiler public class ASMTextifierDisassembler extends InternalDecompiler
{ {
@Override @Override
public String decompileClassNode(ClassNode cn, byte[] b) public String decompileClassNode(ClassNode cn, byte[] bytes)
{ {
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();
cn.accept(new TraceClassVisitor(null, new Textifier(), new PrintWriter(writer))); cn.accept(new TraceClassVisitor(null, new Textifier(), new PrintWriter(writer)));

View File

@ -34,7 +34,7 @@ import java.io.StringWriter;
public class ASMifierGenerator extends InternalDecompiler public class ASMifierGenerator extends InternalDecompiler
{ {
@Override @Override
public String decompileClassNode(ClassNode cn, byte[] b) public String decompileClassNode(ClassNode cn, byte[] bytes)
{ {
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();
cn.accept(new TraceClassVisitor(null, new ASMifier(), new PrintWriter(writer))); cn.accept(new TraceClassVisitor(null, new ASMifier(), new PrintWriter(writer)));

View File

@ -32,7 +32,7 @@ import java.util.ArrayList;
public class BytecodeDisassembler extends InternalDecompiler public class BytecodeDisassembler extends InternalDecompiler
{ {
@Override @Override
public String decompileClassNode(ClassNode cn, byte[] b) public String decompileClassNode(ClassNode cn, byte[] bytes)
{ {
return ClassNodeDecompiler.decompile(new PrefixedStringBuilder(), new ArrayList<>(), cn).toString(); return ClassNodeDecompiler.decompile(new PrefixedStringBuilder(), new ArrayList<>(), cn).toString();
} }

View File

@ -59,9 +59,9 @@ public class CFRDecompiler extends InternalDecompiler
private static final String CLASS_SUFFIX = ".class"; private static final String CLASS_SUFFIX = ".class";
@Override @Override
public String decompileClassNode(ClassNode cn, byte[] content) public String decompileClassNode(ClassNode cn, byte[] bytes)
{ {
return decompile(cn, cn.name, content); return decompile(cn, cn.name, bytes);
} }
private String decompile(ClassNode cn, String name, byte[] content) private String decompile(ClassNode cn, String name, byte[] content)
@ -93,7 +93,10 @@ public class CFRDecompiler extends InternalDecompiler
@Override @Override
public void decompileToZip(String sourceJar, String outJar) public void decompileToZip(String sourceJar, String outJar)
{ {
try (JarFile jfile = new JarFile(new File(sourceJar)); FileOutputStream dest = new FileOutputStream(outJar); BufferedOutputStream buffDest = new BufferedOutputStream(dest); ZipOutputStream out = new ZipOutputStream(buffDest)) try (JarFile jfile = new JarFile(new File(sourceJar));
FileOutputStream dest = new FileOutputStream(outJar);
BufferedOutputStream buffDest = new BufferedOutputStream(dest);
ZipOutputStream out = new ZipOutputStream(buffDest))
{ {
byte[] data = new byte[1024]; byte[] data = new byte[1024];
@ -105,6 +108,7 @@ public class CFRDecompiler extends InternalDecompiler
if (entry.getName().endsWith(CLASS_SUFFIX)) if (entry.getName().endsWith(CLASS_SUFFIX))
{ {
JarEntry etn = new JarEntry(entry.getName().replace(CLASS_SUFFIX, ".java")); JarEntry etn = new JarEntry(entry.getName().replace(CLASS_SUFFIX, ".java"));
if (history.add(etn)) if (history.add(etn))
{ {
out.putNextEntry(etn); out.putNextEntry(etn);
@ -203,6 +207,7 @@ public class CFRDecompiler extends InternalDecompiler
options.put("recovertypehints", String.valueOf(BytecodeViewer.viewer.recoveryTypehInts.isSelected())); options.put("recovertypehints", String.valueOf(BytecodeViewer.viewer.recoveryTypehInts.isSelected()));
options.put("forcereturningifs", String.valueOf(BytecodeViewer.viewer.forceTurningIFs.isSelected())); options.put("forcereturningifs", String.valueOf(BytecodeViewer.viewer.forceTurningIFs.isSelected()));
options.put("forloopaggcapture", String.valueOf(BytecodeViewer.viewer.forLoopAGGCapture.isSelected())); options.put("forloopaggcapture", String.valueOf(BytecodeViewer.viewer.forLoopAGGCapture.isSelected()));
return new OptionsImpl(options); return new OptionsImpl(options);
} }
@ -226,11 +231,15 @@ public class CFRDecompiler extends InternalDecompiler
{ {
if (classFilePath.equals(this.classFilePath) && content != null) if (classFilePath.equals(this.classFilePath) && content != null)
return Pair.make(content, classFilePath); return Pair.make(content, classFilePath);
if (container == null) if (container == null)
return super.getClassFileContent(classFilePath); return super.getClassFileContent(classFilePath);
byte[] data = container.resourceClassBytes.get(classFilePath); byte[] data = container.resourceClassBytes.get(classFilePath);
if (data == null) if (data == null)
return super.getClassFileContent(classFilePath); return super.getClassFileContent(classFilePath);
return Pair.make(data, classFilePath); return Pair.make(data, classFilePath);
} }
@ -259,6 +268,7 @@ public class CFRDecompiler extends InternalDecompiler
{ {
return x -> dumpDecompiled.accept((SinkReturns.Decompiled) x); return x -> dumpDecompiled.accept((SinkReturns.Decompiled) x);
} }
return ignore -> return ignore ->
{ {
}; };

View File

@ -65,7 +65,7 @@ public class FernFlowerDecompiler extends InternalDecompiler
} }
@Override @Override
public String decompileClassNode(ClassNode cn, byte[] b) public String decompileClassNode(ClassNode cn, byte[] bytes)
{ {
String start = TEMP_DIRECTORY + FS + MiscUtils.getUniqueName("", ".class"); String start = TEMP_DIRECTORY + FS + MiscUtils.getUniqueName("", ".class");
@ -74,7 +74,7 @@ public class FernFlowerDecompiler extends InternalDecompiler
String exception = ""; String exception = "";
try (FileOutputStream fos = new FileOutputStream(tempClass)) try (FileOutputStream fos = new FileOutputStream(tempClass))
{ {
fos.write(b); fos.write(bytes);
} }
catch (IOException e) catch (IOException e)
{ {
@ -154,7 +154,26 @@ public class FernFlowerDecompiler extends InternalDecompiler
private String[] generateMainMethod(String className, String folder) private String[] generateMainMethod(String className, String folder)
{ {
return new String[]{"-rbr=" + r(BytecodeViewer.viewer.rbr.isSelected()), "-rsy=" + r(BytecodeViewer.viewer.rsy.isSelected()), "-din=" + r(BytecodeViewer.viewer.din.isSelected()), "-dc4=" + r(BytecodeViewer.viewer.dc4.isSelected()), "-das=" + r(BytecodeViewer.viewer.das.isSelected()), "-hes=" + r(BytecodeViewer.viewer.hes.isSelected()), "-hdc=" + r(BytecodeViewer.viewer.hdc.isSelected()), "-dgs=" + r(BytecodeViewer.viewer.dgs.isSelected()), "-ner=" + r(BytecodeViewer.viewer.ner.isSelected()), "-den=" + r(BytecodeViewer.viewer.den.isSelected()), "-rgn=" + r(BytecodeViewer.viewer.rgn.isSelected()), "-bto=" + r(BytecodeViewer.viewer.bto.isSelected()), "-nns=" + r(BytecodeViewer.viewer.nns.isSelected()), "-uto=" + r(BytecodeViewer.viewer.uto.isSelected()), "-udv=" + r(BytecodeViewer.viewer.udv.isSelected()), "-rer=" + r(BytecodeViewer.viewer.rer.isSelected()), "-fdi=" + r(BytecodeViewer.viewer.fdi.isSelected()), "-asc=" + r(BytecodeViewer.viewer.asc.isSelected()), "-ren=" + r(BytecodeViewer.viewer.ren.isSelected()), className, folder}; return new String[]{"-rbr=" + r(BytecodeViewer.viewer.rbr.isSelected()),
"-rsy=" + r(BytecodeViewer.viewer.rsy.isSelected()),
"-din=" + r(BytecodeViewer.viewer.din.isSelected()),
"-dc4=" + r(BytecodeViewer.viewer.dc4.isSelected()),
"-das=" + r(BytecodeViewer.viewer.das.isSelected()),
"-hes=" + r(BytecodeViewer.viewer.hes.isSelected()),
"-hdc=" + r(BytecodeViewer.viewer.hdc.isSelected()),
"-dgs=" + r(BytecodeViewer.viewer.dgs.isSelected()),
"-ner=" + r(BytecodeViewer.viewer.ner.isSelected()),
"-den=" + r(BytecodeViewer.viewer.den.isSelected()),
"-rgn=" + r(BytecodeViewer.viewer.rgn.isSelected()),
"-bto=" + r(BytecodeViewer.viewer.bto.isSelected()),
"-nns=" + r(BytecodeViewer.viewer.nns.isSelected()),
"-uto=" + r(BytecodeViewer.viewer.uto.isSelected()),
"-udv=" + r(BytecodeViewer.viewer.udv.isSelected()),
"-rer=" + r(BytecodeViewer.viewer.rer.isSelected()),
"-fdi=" + r(BytecodeViewer.viewer.fdi.isSelected()),
"-asc=" + r(BytecodeViewer.viewer.asc.isSelected()),
"-ren=" + r(BytecodeViewer.viewer.ren.isSelected()),
className, folder};
} }
private String r(boolean b) private String r(boolean b)

View File

@ -42,10 +42,8 @@ import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.JAD
*/ */
public class JADXDecompiler extends InternalDecompiler public class JADXDecompiler extends InternalDecompiler
{ {
private final Random r = new Random();
@Override @Override
public String decompileClassNode(ClassNode cn, byte[] b) public String decompileClassNode(ClassNode cn, byte[] bytes)
{ {
String fileStart = TEMP_DIRECTORY + FS; String fileStart = TEMP_DIRECTORY + FS;
@ -54,23 +52,23 @@ public class JADXDecompiler extends InternalDecompiler
try (FileOutputStream fos = new FileOutputStream(tempClass)) try (FileOutputStream fos = new FileOutputStream(tempClass))
{ {
fos.write(b); fos.write(bytes);
} }
catch (IOException e) catch (IOException e)
{ {
BytecodeViewer.handleException(e); BytecodeViewer.handleException(e);
} }
File fuckery = new File(fuckery(fileStart)); File freeDirectory = new File(findUnusedFile(fileStart));
fuckery.mkdirs(); freeDirectory.mkdirs();
try try
{ {
JadxArgs args = new JadxArgs(); JadxArgs args = new JadxArgs();
args.setInputFile(tempClass); args.setInputFile(tempClass);
args.setOutDir(fuckery); args.setOutDir(freeDirectory);
args.setOutDirSrc(fuckery); args.setOutDirSrc(freeDirectory);
args.setOutDirRes(fuckery); args.setOutDirRes(freeDirectory);
JadxDecompiler jadx = new JadxDecompiler(args); JadxDecompiler jadx = new JadxDecompiler(args);
jadx.load(); jadx.load();
@ -86,8 +84,8 @@ public class JADXDecompiler extends InternalDecompiler
tempClass.delete(); tempClass.delete();
if (fuckery.exists()) if (freeDirectory.exists())
return findFile(MiscUtils.listFiles(fuckery)); return findFile(MiscUtils.listFiles(freeDirectory));
if (exception.isEmpty()) if (exception.isEmpty())
exception = "Decompiled source file not found!"; exception = "Decompiled source file not found!";
@ -95,29 +93,29 @@ public class JADXDecompiler extends InternalDecompiler
return JADX + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; return JADX + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception;
} }
//TODO remove public String findUnusedFile(String start)
public String fuckery(String start)
{ {
int failSafe = 0; long index = 0;
while (failSafe++ <= 42069)
while (true)
{ {
File f = new File(start + r.nextInt(Integer.MAX_VALUE)); File f = new File(start + index);
if (!f.exists()) if (!f.exists())
return f.toString(); return f.toString();
} }
return null;
} }
public String findFile(File[] fA) public String findFile(File[] fileArray)
{ {
for (File f : fA) for (File f : fileArray)
{ {
if (f.isDirectory()) if (f.isDirectory())
return findFile(MiscUtils.listFiles(f)); return findFile(MiscUtils.listFiles(f));
else else
{ {
String s; String s;
try try
{ {
s = DiskReader.loadAsString(f.getAbsolutePath()); s = DiskReader.loadAsString(f.getAbsolutePath());
@ -131,6 +129,7 @@ public class JADXDecompiler extends InternalDecompiler
return JADX + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; return JADX + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception;
} }
return s; return s;
} }
} }
@ -141,5 +140,6 @@ public class JADXDecompiler extends InternalDecompiler
@Override @Override
public void decompileToZip(String sourceJar, String zipName) public void decompileToZip(String sourceJar, String zipName)
{ {
//TODO
} }
} }

View File

@ -50,9 +50,10 @@ public class JDGUIDecompiler extends InternalDecompiler
{ {
@Override @Override
public String decompileClassNode(ClassNode cn, byte[] b) public String decompileClassNode(ClassNode cn, byte[] bytes)
{ {
String exception; String exception;
try try
{ {
final File tempDirectory = new File(Constants.TEMP_DIRECTORY + FS + MiscUtils.randomString(32) + FS); final File tempDirectory = new File(Constants.TEMP_DIRECTORY + FS + MiscUtils.randomString(32) + FS);
@ -75,14 +76,13 @@ public class JDGUIDecompiler extends InternalDecompiler
try (FileOutputStream fos = new FileOutputStream(tempClass)) try (FileOutputStream fos = new FileOutputStream(tempClass))
{ {
fos.write(b); fos.write(bytes);
} }
catch (IOException e) catch (IOException e)
{ {
BytecodeViewer.handleException(e); BytecodeViewer.handleException(e);
} }
String pathToClass = tempClass.getAbsolutePath().replace('/', File.separatorChar).replace('\\', File.separatorChar); String pathToClass = tempClass.getAbsolutePath().replace('/', File.separatorChar).replace('\\', File.separatorChar);
String directoryPath = JDGUIClassFileUtil.ExtractDirectoryPath(pathToClass); String directoryPath = JDGUIClassFileUtil.ExtractDirectoryPath(pathToClass);
String internalPath = JDGUIClassFileUtil.ExtractInternalPath(directoryPath, pathToClass); String internalPath = JDGUIClassFileUtil.ExtractInternalPath(directoryPath, pathToClass);
@ -104,8 +104,6 @@ public class JDGUIDecompiler extends InternalDecompiler
DirectoryLoader loader = new DirectoryLoader(new File(directoryPath)); DirectoryLoader loader = new DirectoryLoader(new File(directoryPath));
//PrintStream ps = new PrintStream("test.html");
//HtmlPrinter printer = new HtmlPrinter(ps);
org.jd.core.v1.api.Decompiler decompiler = new ClassFileToJavaSourceDecompiler(); org.jd.core.v1.api.Decompiler decompiler = new ClassFileToJavaSourceDecompiler();
try (PrintStream ps = new PrintStream(tempJava.getAbsolutePath()); PlainTextPrinter printer = new PlainTextPrinter(preferences, ps)) try (PrintStream ps = new PrintStream(tempJava.getAbsolutePath()); PlainTextPrinter printer = new PlainTextPrinter(preferences, ps))
@ -130,5 +128,6 @@ public class JDGUIDecompiler extends InternalDecompiler
@Override @Override
public void decompileToZip(String sourceJar, String zipName) public void decompileToZip(String sourceJar, String zipName)
{ {
//TODO
} }
} }

View File

@ -49,20 +49,21 @@ import static the.bytecode.club.bytecodeviewer.api.ExceptionUI.SEND_STACKTRACE_T
public class JavapDisassembler extends InternalDecompiler public class JavapDisassembler extends InternalDecompiler
{ {
@Override @Override
public String decompileClassNode(ClassNode cn, byte[] b) public String decompileClassNode(ClassNode cn, byte[] bytes)
{ {
if (!ExternalResources.getSingleton().hasJavaToolsSet()) if (!ExternalResources.getSingleton().hasJavaToolsSet())
return "Set Java Tools Path!"; return "Set Java Tools Path!";
return synchronizedDecompilation(cn, b); return synchronizedDecompilation(cn, bytes);
} }
private synchronized String synchronizedDecompilation(ClassNode cn, byte[] b) private synchronized String synchronizedDecompilation(ClassNode cn, byte[] b)
{ {
final File tempDirectory = new File(Constants.TEMP_DIRECTORY + FS + MiscUtils.randomString(32) + FS); final File tempDirectory = new File(Constants.TEMP_DIRECTORY + FS + MiscUtils.randomString(32) + FS);
tempDirectory.mkdir();
final File tempClass = new File(Constants.TEMP_DIRECTORY + FS + "temp" + MiscUtils.randomString(32) + ".class"); final File tempClass = new File(Constants.TEMP_DIRECTORY + FS + "temp" + MiscUtils.randomString(32) + ".class");
tempDirectory.mkdir();
DiskWriter.replaceFileBytes(tempClass.getAbsolutePath(), b, false); DiskWriter.replaceFileBytes(tempClass.getAbsolutePath(), b, false);
JFrameConsolePrintStream sysOutBuffer = null; JFrameConsolePrintStream sysOutBuffer = null;

View File

@ -64,12 +64,14 @@ public class KrakatauDecompiler extends InternalDecompiler
return ";" + Arrays.stream(files).filter(File::isFile).map(File::getAbsolutePath).collect(Collectors.joining(";")); return ";" + Arrays.stream(files).filter(File::isFile).map(File::getAbsolutePath).collect(Collectors.joining(";"));
} }
public String decompileClassNode(File krakatauTempJar, File krakatauTempDir, ClassNode cn) @Override
public String decompileClassNode(ClassNode cn, byte[] bytes)
{ {
if (!ExternalResources.getSingleton().hasSetPython2Command()) if (!ExternalResources.getSingleton().hasSetPython2Command())
return TranslatedStrings.YOU_NEED_TO_SET_YOUR_PYTHON_2_PATH.toString(); return TranslatedStrings.YOU_NEED_TO_SET_YOUR_PYTHON_2_PATH.toString();
ExternalResources.getSingleton().rtCheck(); ExternalResources.getSingleton().rtCheck();
if (Configuration.rt.isEmpty()) if (Configuration.rt.isEmpty())
{ {
BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B); BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B);
@ -82,74 +84,23 @@ public class KrakatauDecompiler extends InternalDecompiler
return TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + " " + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B; return TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + " " + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B;
} }
String s = ExceptionUI.SEND_STACKTRACE_TO_NL; final File tempDirectory = new File(Constants.TEMP_DIRECTORY + FS + MiscUtils.randomString(32) + FS);
final File tempJar = new File(Constants.TEMP_DIRECTORY + FS + "temp" + MiscUtils.randomString(32) + ".jar");
try tempDirectory.mkdir();
{
String[] pythonCommands = new String[]{Configuration.python2};
if (Configuration.python2Extra)
pythonCommands = ArrayUtils.addAll(pythonCommands, "-2");
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(pythonCommands, "-O", //love you storyyeller <3 JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
krakatauWorkingDirectory + FS + "decompile.py", "-skip", //love you storyyeller <3
"-nauto", "-path", Configuration.rt + ";" + krakatauTempJar.getAbsolutePath() + buildCLIArguments(), "-out", krakatauTempDir.getAbsolutePath(), cn.name + ".class"));
Process process = pb.start(); return decompileClassNode(tempJar, tempDirectory, cn);
BytecodeViewer.createdProcesses.add(process);
StringBuilder log = new StringBuilder(TranslatedStrings.PROCESS2 + NL + NL);
//Read out dir output
try (InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr))
{
String line;
while ((line = br.readLine()) != null)
{
log.append(NL).append(line);
}
} }
log.append(NL).append(NL).append(TranslatedStrings.ERROR2).append(NL).append(NL); public String decompileClassNode(File tempJar, File tempDir, ClassNode cn)
try (InputStream is = process.getErrorStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr))
{ {
String line;
while ((line = br.readLine()) != null)
{
log.append(NL).append(line);
}
}
int exitValue = process.waitFor();
log.append(NL).append(NL).append(TranslatedStrings.EXIT_VALUE_IS).append(" ").append(exitValue);
s = log.toString();
//if the motherfucker failed this'll fail, aka wont set.
s = DiskReader.loadAsString(krakatauTempDir.getAbsolutePath() + FS + cn.name + ".java");
}
catch (Exception e)
{
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
e.printStackTrace();
s += NL + ExceptionUI.SEND_STACKTRACE_TO_NL + sw;
}
return s;
}
@Override
public String decompileClassNode(ClassNode cn, byte[] b)
{
//TODO look into transforming through krakatau as a zip rather than direct classfile
if (!ExternalResources.getSingleton().hasSetPython2Command()) if (!ExternalResources.getSingleton().hasSetPython2Command())
return TranslatedStrings.YOU_NEED_TO_SET_YOUR_PYTHON_2_PATH.toString(); return TranslatedStrings.YOU_NEED_TO_SET_YOUR_PYTHON_2_PATH.toString();
ExternalResources.getSingleton().rtCheck();
if (Configuration.rt.isEmpty()) if (Configuration.rt.isEmpty())
{ {
BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B); BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B);
@ -158,17 +109,11 @@ public class KrakatauDecompiler extends InternalDecompiler
if (Configuration.rt.isEmpty()) if (Configuration.rt.isEmpty())
{ {
BytecodeViewer.showMessage("You need to set RT.jar!"); BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B);
return "Set your paths"; return TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + " " + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B;
} }
String s = ExceptionUI.SEND_STACKTRACE_TO_NL; String returnString = ExceptionUI.SEND_STACKTRACE_TO_NL;
final File tempDirectory = new File(Constants.TEMP_DIRECTORY + FS + MiscUtils.randomString(32) + FS);
tempDirectory.mkdir();
final File tempJar = new File(Constants.TEMP_DIRECTORY + FS + "temp" + MiscUtils.randomString(32) + ".jar");
JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
try try
{ {
@ -178,7 +123,8 @@ public class KrakatauDecompiler extends InternalDecompiler
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(pythonCommands, "-O", //love you storyyeller <3 ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(pythonCommands, "-O", //love you storyyeller <3
krakatauWorkingDirectory + FS + "decompile.py", "-skip", //love you storyyeller <3 krakatauWorkingDirectory + FS + "decompile.py", "-skip", //love you storyyeller <3
"-nauto", "-path", Configuration.rt + ";" + tempJar.getAbsolutePath() + buildCLIArguments(), "-out", tempDirectory.getAbsolutePath(), cn.name + ".class")); "-nauto", "-path", Configuration.rt + ";" + tempJar.getAbsolutePath() + buildCLIArguments(),
"-out", tempDir.getAbsolutePath(), cn.name + ".class"));
Process process = pb.start(); Process process = pb.start();
BytecodeViewer.createdProcesses.add(process); BytecodeViewer.createdProcesses.add(process);
@ -212,22 +158,20 @@ public class KrakatauDecompiler extends InternalDecompiler
int exitValue = process.waitFor(); int exitValue = process.waitFor();
log.append(NL).append(NL).append(TranslatedStrings.EXIT_VALUE_IS).append(" ").append(exitValue); log.append(NL).append(NL).append(TranslatedStrings.EXIT_VALUE_IS).append(" ").append(exitValue);
s = log.toString(); returnString = log.toString();
//if the motherfucker failed this'll fail, aka wont set. // update the string on a successful disassemble
s = DiskReader.loadAsString(tempDirectory.getAbsolutePath() + FS + cn.name + ".java"); returnString = DiskReader.loadAsString(tempDir.getAbsolutePath() + FS + cn.name + ".java");
tempDirectory.delete();
tempJar.delete();
} }
catch (Exception e) catch (Exception e)
{ {
StringWriter sw = new StringWriter(); StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw)); e.printStackTrace(new PrintWriter(sw));
e.printStackTrace(); e.printStackTrace();
s += NL + ExceptionUI.SEND_STACKTRACE_TO_NL + sw; returnString += NL + ExceptionUI.SEND_STACKTRACE_TO_NL + sw;
} }
return s; return returnString;
} }
@Override @Override
@ -237,18 +181,19 @@ public class KrakatauDecompiler extends InternalDecompiler
return; return;
ExternalResources.getSingleton().rtCheck(); ExternalResources.getSingleton().rtCheck();
if (Configuration.rt.isEmpty()) if (Configuration.rt.isEmpty())
{ {
BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B); BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B);
ExternalResources.getSingleton().selectJRERTLibrary(); ExternalResources.getSingleton().selectJRERTLibrary();
} }
String ran = MiscUtils.randomString(32); final String ran = MiscUtils.randomString(32);
final File tempDirectory = new File(Constants.TEMP_DIRECTORY + FS + ran + FS); final File tempDirectory = new File(Constants.TEMP_DIRECTORY + FS + ran + FS);
tempDirectory.mkdir();
final File tempJar = new File(sourceJar); final File tempJar = new File(sourceJar);
tempDirectory.mkdir();
try try
{ {
String[] pythonCommands = new String[]{Configuration.python2}; String[] pythonCommands = new String[]{Configuration.python2};

View File

@ -45,12 +45,12 @@ import static the.bytecode.club.bytecodeviewer.Constants.*;
public class KrakatauDisassembler extends InternalDecompiler public class KrakatauDisassembler extends InternalDecompiler
{ {
@Override @Override
public String decompileClassNode(ClassNode cn, byte[] b) public String decompileClassNode(ClassNode cn, byte[] bytes)
{ {
if (!ExternalResources.getSingleton().hasSetPython2Command()) if (!ExternalResources.getSingleton().hasSetPython2Command())
return TranslatedStrings.YOU_NEED_TO_SET_YOUR_PYTHON_2_PATH.toString(); return TranslatedStrings.YOU_NEED_TO_SET_YOUR_PYTHON_2_PATH.toString();
String s = ExceptionUI.SEND_STACKTRACE_TO_NL; String returnString = ExceptionUI.SEND_STACKTRACE_TO_NL;
final File tempDirectory = new File(Constants.TEMP_DIRECTORY + FS + MiscUtils.randomString(32) + FS); final File tempDirectory = new File(Constants.TEMP_DIRECTORY + FS + MiscUtils.randomString(32) + FS);
tempDirectory.mkdir(); tempDirectory.mkdir();
@ -98,19 +98,20 @@ public class KrakatauDisassembler extends InternalDecompiler
int exitValue = process.waitFor(); int exitValue = process.waitFor();
log.append(NL).append(NL).append(TranslatedStrings.EXIT_VALUE_IS).append(" ").append(exitValue); log.append(NL).append(NL).append(TranslatedStrings.EXIT_VALUE_IS).append(" ").append(exitValue);
s = log.toString(); returnString = log.toString();
// if the motherfucker failed this'll fail, aka won't set. // update the string on a successful disassemble
s = DiskReader.loadAsString(tempDirectory.getAbsolutePath() + FS + cn.name + ".j"); returnString = DiskReader.loadAsString(tempDirectory.getAbsolutePath() + FS + cn.name + ".j");
} }
catch (Exception e) catch (Exception e)
{ {
StringWriter sw = new StringWriter(); StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw)); e.printStackTrace(new PrintWriter(sw));
e.printStackTrace(); e.printStackTrace();
s += NL + ExceptionUI.SEND_STACKTRACE_TO_NL + sw; returnString += NL + ExceptionUI.SEND_STACKTRACE_TO_NL + sw;
} }
return s;
return returnString;
} }
@Override @Override
@ -132,7 +133,8 @@ public class KrakatauDisassembler extends InternalDecompiler
pythonCommands = ArrayUtils.addAll(pythonCommands, "-2"); pythonCommands = ArrayUtils.addAll(pythonCommands, "-2");
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(pythonCommands, "-O", //love you storyyeller <3 ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(pythonCommands, "-O", //love you storyyeller <3
krakatauWorkingDirectory + FS + "disassemble.py", "-path", Configuration.rt + ";" + tempJar.getAbsolutePath(), "-out", tempDirectory.getAbsolutePath(), tempJar.getAbsolutePath())); krakatauWorkingDirectory + FS + "disassemble.py", "-path", Configuration.rt + ";" + tempJar.getAbsolutePath(),
"-out", tempDirectory.getAbsolutePath(), tempJar.getAbsolutePath()));
Process process = pb.start(); Process process = pb.start();
BytecodeViewer.createdProcesses.add(process); BytecodeViewer.createdProcesses.add(process);

View File

@ -75,18 +75,17 @@ public class ProcyonDecompiler extends InternalDecompiler
} }
@Override @Override
public String decompileClassNode(ClassNode cn, byte[] b) public String decompileClassNode(ClassNode cn, byte[] bytes)
{ {
String exception; String exception;
try try
{ {
String fileStart = TEMP_DIRECTORY + FS + "temp"; final String fileStart = TEMP_DIRECTORY + FS + "temp";
final File tempClass = new File(MiscUtils.getUniqueName(fileStart, ".class") + ".class"); final File tempClass = new File(MiscUtils.getUniqueName(fileStart, ".class") + ".class");
try (FileOutputStream fos = new FileOutputStream(tempClass)) try (FileOutputStream fos = new FileOutputStream(tempClass))
{ {
fos.write(b); fos.write(bytes);
} }
catch (IOException e) catch (IOException e)
{ {
@ -104,6 +103,7 @@ public class ProcyonDecompiler extends InternalDecompiler
decompilationOptions.setFullDecompilation(true); decompilationOptions.setFullDecompilation(true);
TypeDefinition resolvedType; TypeDefinition resolvedType;
if (type == null || ((resolvedType = type.resolve()) == null)) if (type == null || ((resolvedType = type.resolve()) == null))
throw new Exception("Unable to resolve type."); throw new Exception("Unable to resolve type.");
@ -142,7 +142,10 @@ public class ProcyonDecompiler extends InternalDecompiler
*/ */
private void doSaveJarDecompiled(File inFile, File outFile) throws Exception private void doSaveJarDecompiled(File inFile, File outFile) throws Exception
{ {
try (JarFile jfile = new JarFile(inFile); FileOutputStream dest = new FileOutputStream(outFile); BufferedOutputStream buffDest = new BufferedOutputStream(dest); ZipOutputStream out = new ZipOutputStream(buffDest)) try (JarFile jfile = new JarFile(inFile);
FileOutputStream dest = new FileOutputStream(outFile);
BufferedOutputStream buffDest = new BufferedOutputStream(dest);
ZipOutputStream out = new ZipOutputStream(buffDest))
{ {
byte[] data = new byte[1024]; byte[] data = new byte[1024];
DecompilerSettings settings = getDecompilerSettings(); DecompilerSettings settings = getDecompilerSettings();
@ -157,24 +160,30 @@ public class ProcyonDecompiler extends InternalDecompiler
Enumeration<JarEntry> ent = jfile.entries(); Enumeration<JarEntry> ent = jfile.entries();
Set<JarEntry> history = new HashSet<>(); Set<JarEntry> history = new HashSet<>();
while (ent.hasMoreElements()) while (ent.hasMoreElements())
{ {
JarEntry entry = ent.nextElement(); JarEntry entry = ent.nextElement();
if (entry.getName().endsWith(".class")) if (entry.getName().endsWith(".class"))
{ {
JarEntry etn = new JarEntry(entry.getName().replace(".class", ".java")); JarEntry etn = new JarEntry(entry.getName().replace(".class", ".java"));
if (history.add(etn)) if (history.add(etn))
{ {
out.putNextEntry(etn); out.putNextEntry(etn);
try try
{ {
String internalName = StringUtilities.removeRight(entry.getName(), ".class"); String internalName = StringUtilities.removeRight(entry.getName(), ".class");
TypeReference type = metadataSystem.lookupType(internalName); TypeReference type = metadataSystem.lookupType(internalName);
TypeDefinition resolvedType; TypeDefinition resolvedType;
if ((type == null) || ((resolvedType = type.resolve()) == null)) if ((type == null) || ((resolvedType = type.resolve()) == null))
{ {
throw new Exception("Unable to resolve type."); throw new Exception("Unable to resolve type.");
} }
Writer writer = new OutputStreamWriter(out); Writer writer = new OutputStreamWriter(out);
settings.getLanguage().decompileType(resolvedType, new PlainTextOutput(writer), decompilationOptions); settings.getLanguage().decompileType(resolvedType, new PlainTextOutput(writer), decompilationOptions);
writer.flush(); writer.flush();
@ -190,10 +199,13 @@ public class ProcyonDecompiler extends InternalDecompiler
try try
{ {
JarEntry etn = new JarEntry(entry.getName()); JarEntry etn = new JarEntry(entry.getName());
if (history.add(etn)) if (history.add(etn))
continue; continue;
history.add(etn); history.add(etn);
out.putNextEntry(etn); out.putNextEntry(etn);
try (InputStream in = jfile.getInputStream(entry)) try (InputStream in = jfile.getInputStream(entry))
{ {
if (in != null) if (in != null)
@ -214,14 +226,12 @@ public class ProcyonDecompiler extends InternalDecompiler
{ {
// some jars contain duplicate pom.xml entries: ignore it // some jars contain duplicate pom.xml entries: ignore it
if (!ze.getMessage().contains("duplicate")) if (!ze.getMessage().contains("duplicate"))
{
throw ze; throw ze;
} }
} }
} }
} }
} }
}
/** /**
* @author DeathMarine * @author DeathMarine
@ -229,28 +239,26 @@ public class ProcyonDecompiler extends InternalDecompiler
public static final class LuytenTypeLoader implements ITypeLoader public static final class LuytenTypeLoader implements ITypeLoader
{ {
private final List<ITypeLoader> _typeLoaders; private final List<ITypeLoader> typeLoaders;
public LuytenTypeLoader() public LuytenTypeLoader()
{ {
_typeLoaders = new ArrayList<>(); typeLoaders = new ArrayList<>();
_typeLoaders.add(new InputTypeLoader()); typeLoaders.add(new InputTypeLoader());
} }
public List<ITypeLoader> getTypeLoaders() public List<ITypeLoader> getTypeLoaders()
{ {
return _typeLoaders; return typeLoaders;
} }
@Override @Override
public boolean tryLoadType(String internalName, Buffer buffer) public boolean tryLoadType(String internalName, Buffer buffer)
{ {
for (ITypeLoader typeLoader : _typeLoaders) for (ITypeLoader typeLoader : typeLoaders)
{ {
if (typeLoader.tryLoadType(internalName, buffer)) if (typeLoader.tryLoadType(internalName, buffer))
{
return true; return true;
}
buffer.reset(); buffer.reset();
} }

View File

@ -44,21 +44,20 @@ import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.*;
public class SmaliDisassembler extends InternalDecompiler public class SmaliDisassembler extends InternalDecompiler
{ {
@Override @Override
public String decompileClassNode(ClassNode cn, byte[] b) public String decompileClassNode(ClassNode cn, byte[] bytes)
{ {
String exception = ""; final String fileStart = TEMP_DIRECTORY + FS + "temp";
String fileStart = TEMP_DIRECTORY + FS + "temp"; final String start = MiscUtils.getUniqueName(fileStart, ".class");
String start = MiscUtils.getUniqueName(fileStart, ".class");
final File tempClass = new File(start + ".class"); final File tempClass = new File(start + ".class");
final File tempDex = new File(start + ".dex"); final File tempDex = new File(start + ".dex");
final File tempDexOut = new File(start + "-out"); final File tempDexOut = new File(start + "-out");
final File tempSmali = new File(start + "-smali"); //output directory final File tempSmali = new File(start + "-smali"); //output directory
String exception = "";
try (FileOutputStream fos = new FileOutputStream(tempClass)) try (FileOutputStream fos = new FileOutputStream(tempClass))
{ {
fos.write(b); fos.write(bytes);
} }
catch (IOException e) catch (IOException e)
{ {

View File

@ -40,7 +40,9 @@ public class JDGUIClassFileUtil
{ {
String directoryPath; String directoryPath;
try (FileInputStream fis = new FileInputStream(pathToClass); BufferedInputStream bis = new BufferedInputStream(fis); DataInputStream dis = new DataInputStream(bis)) try (FileInputStream fis = new FileInputStream(pathToClass);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis))
{ {
int magic = dis.readInt(); int magic = dis.readInt();
if (magic != ClassFileReader.JAVA_MAGIC_NUMBER) if (magic != ClassFileReader.JAVA_MAGIC_NUMBER)

View File

@ -59,6 +59,7 @@ public class DecompilerViewComponent
{ {
if (type == JAVA || type == JAVA_NON_EDITABLE || type == JAVA_AND_BYTECODE) if (type == JAVA || type == JAVA_NON_EDITABLE || type == JAVA_AND_BYTECODE)
menu.add(java); menu.add(java);
if (type == BYTECODE || type == JAVA_AND_BYTECODE || type == BYTECODE_NON_EDITABLE) if (type == BYTECODE || type == JAVA_AND_BYTECODE || type == BYTECODE_NON_EDITABLE)
menu.add(bytecode); menu.add(bytecode);
@ -75,6 +76,7 @@ public class DecompilerViewComponent
{ {
if (type == JAVA || type == JAVA_NON_EDITABLE || type == JAVA_AND_BYTECODE) if (type == JAVA || type == JAVA_NON_EDITABLE || type == JAVA_AND_BYTECODE)
group.add(java); group.add(java);
if (type == BYTECODE || type == JAVA_AND_BYTECODE || type == BYTECODE_NON_EDITABLE) if (type == BYTECODE || type == JAVA_AND_BYTECODE || type == BYTECODE_NON_EDITABLE)
group.add(bytecode); group.add(bytecode);
} }

View File

@ -57,11 +57,13 @@ public class ExportJar extends JFrame
btnNewButton.addActionListener(arg0 -> btnNewButton.addActionListener(arg0 ->
{ {
BytecodeViewer.updateBusyStatus(true); BytecodeViewer.updateBusyStatus(true);
Thread t = new Thread(() -> Thread t = new Thread(() ->
{ {
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), jarPath, manifest.getText()); JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), jarPath, manifest.getText());
BytecodeViewer.updateBusyStatus(false); BytecodeViewer.updateBusyStatus(false);
}, "Jar Export"); }, "Jar Export");
t.start(); t.start();
dispose(); dispose();
}); });

View File

@ -151,6 +151,7 @@ public class ExtendedJOptionPane
private static JDialog createNewJDialog(Component parentComponent, JOptionPane pane, String title, int style, OnCreate onCreate) private static JDialog createNewJDialog(Component parentComponent, JOptionPane pane, String title, int style, OnCreate onCreate)
{ {
JDialog dialog = pane.createDialog(parentComponent, title); JDialog dialog = pane.createDialog(parentComponent, title);
if (JDialog.isDefaultLookAndFeelDecorated()) if (JDialog.isDefaultLookAndFeelDecorated())
{ {
boolean supportsWindowDecorations = UIManager.getLookAndFeel().getSupportsWindowDecorations(); boolean supportsWindowDecorations = UIManager.getLookAndFeel().getSupportsWindowDecorations();

View File

@ -45,6 +45,7 @@ public class FileChooser extends JFileChooser
Set<String> extensionSet = new HashSet<>(Arrays.asList(extensions)); Set<String> extensionSet = new HashSet<>(Arrays.asList(extensions));
setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
try try
{ {
setSelectedFile(file); setSelectedFile(file);

View File

@ -144,7 +144,8 @@ public class JFrameConsole extends JFrame
String trimmed = s.substring(0, max); String trimmed = s.substring(0, max);
if (!trimmed.startsWith("WARNING: Skipping")) if (!trimmed.startsWith("WARNING: Skipping"))
trimmed = ("WARNING: Skipping " + skipped + " chars, allowing " + max + "\n\r") + "Full log saved to: " + tempFile.getAbsolutePath() + "\n\r\n\r" + trimmed; trimmed = ("WARNING: Skipping " + skipped + " chars, allowing " + max + "\n\r")
+ "Full log saved to: " + tempFile.getAbsolutePath() + "\n\r\n\r" + trimmed;
return trimmed; return trimmed;
} }

View File

@ -48,6 +48,7 @@ public class MethodsRenderer extends JLabel implements ListCellRenderer<Object>
MethodParser methods; MethodParser methods;
List<MethodParser> methodParsers = bytecodeViewPanelUpdater.viewer.methods; List<MethodParser> methodParsers = bytecodeViewPanelUpdater.viewer.methods;
BytecodeViewPanel bytecodeViewPanel = bytecodeViewPanelUpdater.bytecodeViewPanel; BytecodeViewPanel bytecodeViewPanel = bytecodeViewPanelUpdater.bytecodeViewPanel;
try try
{ {
methods = methodParsers.get(bytecodeViewPanel.decompiler.ordinal()); methods = methodParsers.get(bytecodeViewPanel.decompiler.ordinal());
@ -56,8 +57,10 @@ public class MethodsRenderer extends JLabel implements ListCellRenderer<Object>
{ {
methods = methodParsers.get(bytecodeViewPanel.panelIndex); methods = methodParsers.get(bytecodeViewPanel.panelIndex);
} }
MethodParser.Method method = methods.getMethod(methodIndex); MethodParser.Method method = methods.getMethod(methodIndex);
setText(method.toString()); setText(method.toString());
return this; return this;
} }
} }

View File

@ -47,6 +47,7 @@ public class MultipleChoiceDialog
dialog.setVisible(true); dialog.setVisible(true);
Object obj = pane.getValue(); Object obj = pane.getValue();
int result = -1; int result = -1;
for (int k = 0; k < options.length; k++) for (int k = 0; k < options.length; k++)
if (options[k].equals(obj)) if (options[k].equals(obj))
result = k; result = k;

View File

@ -71,6 +71,7 @@ public class MyErrorStripe extends JPanel
float lineCount = textArea.getLineCount(); float lineCount = textArea.getLineCount();
int lineHeight = textArea.getLineHeight(); int lineHeight = textArea.getLineHeight();
int linesPerVisibleRect = h / lineHeight; int linesPerVisibleRect = h / lineHeight;
return Math.round((h - 1) * line / Math.max(lineCount, linesPerVisibleRect)); return Math.round((h - 1) * line / Math.max(lineCount, linesPerVisibleRect));
} }
@ -81,6 +82,7 @@ public class MyErrorStripe extends JPanel
int lineHeight = textArea.getLineHeight(); int lineHeight = textArea.getLineHeight();
int linesPerVisibleRect = h / lineHeight; int linesPerVisibleRect = h / lineHeight;
int lineCount = textArea.getLineCount(); int lineCount = textArea.getLineCount();
if (y < h) if (y < h)
{ {
float at = y / (float) h; float at = y / (float) h;
@ -119,6 +121,7 @@ public class MyErrorStripe extends JPanel
for (DocumentRange range : occurrences) for (DocumentRange range : occurrences)
{ {
int line; int line;
try try
{ {
line = textArea.getLineOfOffset(range.getStartOffset()); line = textArea.getLineOfOffset(range.getStartOffset());
@ -131,6 +134,7 @@ public class MyErrorStripe extends JPanel
ParserNotice notice = new MarkedOccurrenceNotice(range, color); ParserNotice notice = new MarkedOccurrenceNotice(range, color);
Integer key = line; Integer key = line;
Marker m = markerMap.get(key); Marker m = markerMap.get(key);
if (m == null) if (m == null)
{ {
m = new Marker(notice); m = new Marker(notice);
@ -201,6 +205,7 @@ public class MyErrorStripe extends JPanel
public void mouseClicked(@NotNull MouseEvent e) public void mouseClicked(@NotNull MouseEvent e)
{ {
Component source = (Component) e.getSource(); Component source = (Component) e.getSource();
if (source instanceof MyErrorStripe.Marker) if (source instanceof MyErrorStripe.Marker)
{ {
Marker m = (Marker) source; Marker m = (Marker) source;
@ -209,6 +214,7 @@ public class MyErrorStripe extends JPanel
} }
int line = yToLine(e.getY()); int line = yToLine(e.getY());
if (line > -1) if (line > -1)
{ {
try try
@ -353,6 +359,7 @@ public class MyErrorStripe extends JPanel
protected void paintComponent(Graphics g) protected void paintComponent(Graphics g)
{ {
final ParserNotice notice = getHighestPriorityNotice(); final ParserNotice notice = getHighestPriorityNotice();
if (notice != null) if (notice != null)
paintParserNoticeMarker((Graphics2D) g, notice, getWidth(), getHeight()); paintParserNoticeMarker((Graphics2D) g, notice, getWidth(), getHeight());
} }
@ -362,6 +369,7 @@ public class MyErrorStripe extends JPanel
ParserNotice pn = notices.get(0); ParserNotice pn = notices.get(0);
int offs = pn.getOffset(); int offs = pn.getOffset();
int len = pn.getLength(); int len = pn.getLength();
if (offs > -1 && len > -1) // These values are optional if (offs > -1 && len > -1) // These values are optional
{ {
DocumentRange range = new DocumentRange(offs, offs + len); DocumentRange range = new DocumentRange(offs, offs + len);
@ -370,6 +378,7 @@ public class MyErrorStripe extends JPanel
else else
{ {
int line = pn.getLine(); int line = pn.getLine();
try try
{ {
offs = textArea.getLineStartOffset(line); offs = textArea.getLineStartOffset(line);

View File

@ -72,6 +72,7 @@ public class RSyntaxTextAreaHighlighterEx extends RSyntaxTextAreaHighlighter
{ {
int start = info.getStartOffset(); int start = info.getStartOffset();
int end = info.getEndOffset() + 1; // HACK int end = info.getEndOffset() + 1; // HACK
if (start <= end) if (start <= end)
{ {
// Occasionally a Marked Occurrence can have a lost end offset // Occasionally a Marked Occurrence can have a lost end offset
@ -116,6 +117,7 @@ public class RSyntaxTextAreaHighlighterEx extends RSyntaxTextAreaHighlighter
if (notice != null) if (notice != null)
{ {
color = notice.getColor(); color = notice.getColor();
if (color == null) if (color == null)
color = DEFAULT_PARSER_NOTICE_COLOR; color = DEFAULT_PARSER_NOTICE_COLOR;
} }

View File

@ -111,6 +111,7 @@ public class RunOptions extends JFrame
printToCommandLine.setBounds(6, 315, 232, 23); printToCommandLine.setBounds(6, 315, 232, 23);
getContentPane().add(printToCommandLine); getContentPane().add(printToCommandLine);
this.setLocationRelativeTo(null); this.setLocationRelativeTo(null);
btnNewButton.addActionListener(arg0 -> btnNewButton.addActionListener(arg0 ->
{ {
PluginManager.runPlugin(new EZInjection(accessModifiers.isSelected(), injectHooks.isSelected(), debugMethodCalls.isSelected(), invokeMethod.isSelected(), mainMethodFQN.getText(), false, false, debugClasses.getText(), this.socksProxy.getText(), forceProxy.isSelected(), launchReflectionKit.isSelected(), console.isSelected(), printToCommandLine.isSelected())); PluginManager.runPlugin(new EZInjection(accessModifiers.isSelected(), injectHooks.isSelected(), debugMethodCalls.isSelected(), invokeMethod.isSelected(), mainMethodFQN.getText(), false, false, debugClasses.getText(), this.socksProxy.getText(), forceProxy.isSelected(), launchReflectionKit.isSelected(), console.isSelected(), printToCommandLine.isSelected()));

View File

@ -49,6 +49,7 @@ public class SettingsDialog extends JScrollPane
return; return;
List<JMenuItem> options = new ArrayList<>(); List<JMenuItem> options = new ArrayList<>();
for (Component child : menu.getMenuComponents()) for (Component child : menu.getMenuComponents())
{ {
if (!(child instanceof JMenuItem)) if (!(child instanceof JMenuItem))
@ -83,6 +84,7 @@ public class SettingsDialog extends JScrollPane
private void buildPanel() private void buildPanel()
{ {
display.setLayout(new BoxLayout(display, BoxLayout.Y_AXIS)); display.setLayout(new BoxLayout(display, BoxLayout.Y_AXIS));
for (JMenuItem menuItem : options) for (JMenuItem menuItem : options)
display.add(menuItem); display.add(menuItem);
} }

View File

@ -42,7 +42,9 @@ public class TextAreaSearchPanel extends JPanel
public TextAreaSearchPanel(JTextArea textArea) public TextAreaSearchPanel(JTextArea textArea)
{ {
super(new BorderLayout()); super(new BorderLayout());
this.textArea = textArea; this.textArea = textArea;
setup(); setup();
setVisible(true); setVisible(true);
} }

View File

@ -35,7 +35,9 @@ public class WaitBusyIcon extends JMenuItemIcon
public WaitBusyIcon() public WaitBusyIcon()
{ {
super(new RotatableIcon(IconResources.busyIcon)); super(new RotatableIcon(IconResources.busyIcon));
animator = new RotatableIconAnimator(8, (RotatableIcon) getIcon(), this); animator = new RotatableIconAnimator(8, (RotatableIcon) getIcon(), this);
addHierarchyListener(e -> addHierarchyListener(e ->
{ {
if ((e.getChangeFlags() & HierarchyEvent.PARENT_CHANGED) != 0) if ((e.getChangeFlags() & HierarchyEvent.PARENT_CHANGED) != 0)

View File

@ -90,6 +90,7 @@ public class GoToAction extends AbstractAction
if (localMember.line == line && localMember.columnStart - 1 <= column && localMember.columnEnd >= column) if (localMember.line == line && localMember.columnStart - 1 <= column && localMember.columnEnd >= column)
{ {
Element root = textArea.getDocument().getDefaultRootElement(); Element root = textArea.getDocument().getDefaultRootElement();
if (localMember.decRef.equals("declaration")) if (localMember.decRef.equals("declaration"))
{ {
int startOffset = root.getElement(localMember.line - 1).getStartOffset() + (localMember.columnStart - 1); int startOffset = root.getElement(localMember.line - 1).getStartOffset() + (localMember.columnStart - 1);
@ -115,6 +116,7 @@ public class GoToAction extends AbstractAction
if (method.line == line && method.columnStart - 1 <= column && method.columnEnd >= column) if (method.line == line && method.columnStart - 1 <= column && method.columnEnd >= column)
{ {
Element root = textArea.getDocument().getDefaultRootElement(); Element root = textArea.getDocument().getDefaultRootElement();
if (method.decRef.equalsIgnoreCase("declaration")) if (method.decRef.equalsIgnoreCase("declaration"))
{ {
int startOffset = root.getElement(method.line - 1).getStartOffset() + (method.columnStart - 1); int startOffset = root.getElement(method.line - 1).getStartOffset() + (method.columnStart - 1);
@ -131,7 +133,6 @@ public class GoToAction extends AbstractAction
} }
}); });
open(textArea, false, false, true); open(textArea, false, false, true);
} }
} }
@ -144,6 +145,7 @@ public class GoToAction extends AbstractAction
{ {
name = clazz.owner; name = clazz.owner;
Element root = textArea.getDocument().getDefaultRootElement(); Element root = textArea.getDocument().getDefaultRootElement();
if (clazz.type.equals("declaration")) if (clazz.type.equals("declaration"))
{ {
int startOffset = root.getElement(clazz.line - 1).getStartOffset() + (clazz.columnStart - 1); int startOffset = root.getElement(clazz.line - 1).getStartOffset() + (clazz.columnStart - 1);
@ -173,6 +175,7 @@ public class GoToAction extends AbstractAction
return null; return null;
ResourceContainer resourceContainer = BytecodeViewer.getFileContainer(container.getParentContainer()); ResourceContainer resourceContainer = BytecodeViewer.getFileContainer(container.getParentContainer());
if (resourceContainer == null) if (resourceContainer == null)
return null; return null;
@ -188,6 +191,7 @@ public class GoToAction extends AbstractAction
{ {
ClassMethodLocation classMethodLocation = container.getMethodLocationsFor(lexeme).get(0); ClassMethodLocation classMethodLocation = container.getMethodLocationsFor(lexeme).get(0);
ClassReferenceLocation classReferenceLocation = null; ClassReferenceLocation classReferenceLocation = null;
try try
{ {
classReferenceLocation = container.getClassReferenceLocationsFor(classMethodLocation.owner).get(0); classReferenceLocation = container.getClassReferenceLocationsFor(classMethodLocation.owner).get(0);
@ -200,10 +204,12 @@ public class GoToAction extends AbstractAction
return null; return null;
String packagePath = classReferenceLocation.packagePath; String packagePath = classReferenceLocation.packagePath;
if (packagePath.startsWith("java") || packagePath.startsWith("javax") || packagePath.startsWith("com.sun")) if (packagePath.startsWith("java") || packagePath.startsWith("javax") || packagePath.startsWith("com.sun"))
return null; return null;
String resourceName = packagePath + "/" + classMethodLocation.owner; String resourceName = packagePath + "/" + classMethodLocation.owner;
if (resourceContainer.resourceClasses.containsKey(resourceName)) if (resourceContainer.resourceClasses.containsKey(resourceName))
{ {
BytecodeViewer.viewer.workPane.addClassResource(resourceContainer, resourceName + ".class"); BytecodeViewer.viewer.workPane.addClassResource(resourceContainer, resourceName + ".class");
@ -216,10 +222,12 @@ public class GoToAction extends AbstractAction
{ {
ClassReferenceLocation classReferenceLocation = container.getClassReferenceLocationsFor(lexeme).get(0); ClassReferenceLocation classReferenceLocation = container.getClassReferenceLocationsFor(lexeme).get(0);
String packagePath = classReferenceLocation.packagePath; String packagePath = classReferenceLocation.packagePath;
if (packagePath.startsWith("java") || packagePath.startsWith("javax") || packagePath.startsWith("com.sun")) if (packagePath.startsWith("java") || packagePath.startsWith("javax") || packagePath.startsWith("com.sun"))
return null; return null;
String resourceName = packagePath + "/" + lexeme; String resourceName = packagePath + "/" + lexeme;
if (resourceContainer.resourceClasses.containsKey(resourceName)) if (resourceContainer.resourceClasses.containsKey(resourceName))
{ {
BytecodeViewer.viewer.workPane.addClassResource(resourceContainer, resourceName + ".class"); BytecodeViewer.viewer.workPane.addClassResource(resourceContainer, resourceName + ".class");
@ -240,9 +248,11 @@ public class GoToAction extends AbstractAction
token = TokenUtil.getToken(textArea, token); token = TokenUtil.getToken(textArea, token);
String lexeme = token.getLexeme(); String lexeme = token.getLexeme();
ClassFileContainer classFileContainer; ClassFileContainer classFileContainer;
if (isClass) if (isClass)
{ {
classFileContainer = openClass(lexeme, false, false); classFileContainer = openClass(lexeme, false, false);
if (classFileContainer == null) if (classFileContainer == null)
return; return;
@ -253,9 +263,7 @@ public class GoToAction extends AbstractAction
classReference.forEach(classReferenceLocation -> classReference.forEach(classReferenceLocation ->
{ {
if (classReferenceLocation.type.equals("declaration")) if (classReferenceLocation.type.equals("declaration"))
{
moveCursor(classReferenceLocation.line, classReferenceLocation.columnStart); moveCursor(classReferenceLocation.line, classReferenceLocation.columnStart);
}
}); });
} }
}); });
@ -273,9 +281,7 @@ public class GoToAction extends AbstractAction
fields.forEach(classFieldLocation -> fields.forEach(classFieldLocation ->
{ {
if (classFieldLocation.type.equals("declaration")) if (classFieldLocation.type.equals("declaration"))
{
moveCursor(classFieldLocation.line, classFieldLocation.columnStart); moveCursor(classFieldLocation.line, classFieldLocation.columnStart);
}
}); });
} }
}); });
@ -283,6 +289,7 @@ public class GoToAction extends AbstractAction
else if (isMethod) else if (isMethod)
{ {
classFileContainer = openClass(lexeme, false, true); classFileContainer = openClass(lexeme, false, true);
if (classFileContainer == null) if (classFileContainer == null)
return; return;
@ -293,14 +300,13 @@ public class GoToAction extends AbstractAction
methods.forEach(method -> methods.forEach(method ->
{ {
if (method.decRef.equalsIgnoreCase("declaration")) if (method.decRef.equalsIgnoreCase("declaration"))
{
moveCursor(method.line, method.columnStart); moveCursor(method.line, method.columnStart);
}
}); });
} }
}); });
} }
}, "Open Class"); }, "Open Class");
thread.start(); thread.start();
} }
@ -352,6 +358,7 @@ public class GoToAction extends AbstractAction
if (caretListener instanceof BytecodeViewPanelUpdater.MarkerCaretListener) if (caretListener instanceof BytecodeViewPanelUpdater.MarkerCaretListener)
{ {
BytecodeViewPanelUpdater.MarkerCaretListener markerCaretListener = (BytecodeViewPanelUpdater.MarkerCaretListener) caretListener; BytecodeViewPanelUpdater.MarkerCaretListener markerCaretListener = (BytecodeViewPanelUpdater.MarkerCaretListener) caretListener;
markerCaretListener.caretUpdate(new CaretEvent(panel.textArea) markerCaretListener.caretUpdate(new CaretEvent(panel.textArea)
{ {
@Override @Override

View File

@ -63,7 +63,7 @@ public class ResourceListIconRenderer extends DefaultTreeCellRenderer
boolean iconSet = false; boolean iconSet = false;
//guess file type based on extension //guess file type based on extension
ResourceType knownResourceType = onlyName.contains(":") ? null : ResourceType.extensionMap.get(FilenameUtils.getExtension(onlyName).toLowerCase()); ResourceType knownResourceType = onlyName.contains(":") ? null : ResourceType.EXTENSION_MAP.get(FilenameUtils.getExtension(onlyName).toLowerCase());
//set the icon to a known file type //set the icon to a known file type
if (knownResourceType != null if (knownResourceType != null

View File

@ -24,5 +24,6 @@ package the.bytecode.club.bytecodeviewer.gui.resourcesearch;
*/ */
public enum SearchRadius public enum SearchRadius
{ {
All_Classes, Current_Class All_Classes,
Current_Class
} }

View File

@ -27,7 +27,11 @@ import the.bytecode.club.bytecodeviewer.searching.impl.*;
*/ */
public enum SearchType public enum SearchType
{ {
Strings(new LDCSearch()), Regex(new RegexSearch()), MethodCall(new MethodCallSearch()), FieldCall(new FieldCallSearch()), MemberWithAnnotation(new MemberWithAnnotationSearch()); Strings(new LDCSearch()),
Regex(new RegexSearch()),
MethodCall(new MethodCallSearch()),
FieldCall(new FieldCallSearch()),
MemberWithAnnotation(new MemberWithAnnotationSearch());
public final SearchPanel panel; public final SearchPanel panel;

View File

@ -107,6 +107,7 @@ public class DecompilerSelectionPane
//build the action commands //build the action commands
none.setActionCommand(Decompiler.NONE.name()); none.setActionCommand(Decompiler.NONE.name());
hexcode.setActionCommand(Decompiler.HEXCODE_VIEWER.name()); hexcode.setActionCommand(Decompiler.HEXCODE_VIEWER.name());
for (DecompilerViewComponent component : components) for (DecompilerViewComponent component : components)
{ {
for (Decompiler decompiler : component.getDecompilers()) for (Decompiler decompiler : component.getDecompilers())
@ -123,6 +124,7 @@ public class DecompilerSelectionPane
//auto-save on decompiler change //auto-save on decompiler change
Enumeration<AbstractButton> it = group.getElements(); Enumeration<AbstractButton> it = group.getElements();
while (it.hasMoreElements()) while (it.hasMoreElements())
{ {
AbstractButton button = it.nextElement(); AbstractButton button = it.nextElement();
@ -140,14 +142,18 @@ public class DecompilerSelectionPane
menu.add(new JSeparator()); menu.add(new JSeparator());
menu.add(procyon.getMenu()); menu.add(procyon.getMenu());
menu.add(CFR.getMenu()); menu.add(CFR.getMenu());
if (!Configuration.jadxGroupedWithSmali) if (!Configuration.jadxGroupedWithSmali)
menu.add(JADX.getMenu()); menu.add(JADX.getMenu());
menu.add(JD.getMenu()); menu.add(JD.getMenu());
menu.add(fern.getMenu()); menu.add(fern.getMenu());
menu.add(krakatau.getMenu()); menu.add(krakatau.getMenu());
menu.add(new JSeparator()); menu.add(new JSeparator());
if (Configuration.jadxGroupedWithSmali) if (Configuration.jadxGroupedWithSmali)
menu.add(JADX.getMenu()); menu.add(JADX.getMenu());
menu.add(smali.getMenu()); menu.add(smali.getMenu());
menu.add(new JSeparator()); menu.add(new JSeparator());
menu.add(bytecode.getMenu()); menu.add(bytecode.getMenu());
@ -166,6 +172,7 @@ public class DecompilerSelectionPane
public void setSelectedDecompiler(Decompiler decompiler) public void setSelectedDecompiler(Decompiler decompiler)
{ {
Enumeration<AbstractButton> it = group.getElements(); Enumeration<AbstractButton> it = group.getElements();
while (it.hasMoreElements()) while (it.hasMoreElements())
{ {
AbstractButton button = it.nextElement(); AbstractButton button = it.nextElement();

View File

@ -36,10 +36,9 @@ public class TabComponent extends JPanel
public TabComponent(JTabbedPane pane) public TabComponent(JTabbedPane pane)
{ {
super(new FlowLayout(FlowLayout.LEFT, 0, 0)); super(new FlowLayout(FlowLayout.LEFT, 0, 0));
if (pane == null) if (pane == null)
{
throw new NullPointerException("TabbedPane is null"); throw new NullPointerException("TabbedPane is null");
}
this.pane = pane; this.pane = pane;
@ -50,9 +49,7 @@ public class TabComponent extends JPanel
{ {
int i = pane.indexOfTabComponent(TabComponent.this); int i = pane.indexOfTabComponent(TabComponent.this);
if (i != -1) if (i != -1)
{
return pane.getTitleAt(i); return pane.getTitleAt(i);
}
return null; return null;
} }
@ -102,14 +99,10 @@ public class TabComponent extends JPanel
return; return;
if (pane.indexOfTabComponent(TabComponent.this) != 0) if (pane.indexOfTabComponent(TabComponent.this) != 0)
{
removeTab(0); removeTab(0);
}
else else
{
removeTab(1); removeTab(1);
} }
}
}); });
setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0)); setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));

View File

@ -82,7 +82,7 @@ public class FileViewer extends ResourceViewer
// (If none selected, try Pane2, Pane3, default to Procyon) // (If none selected, try Pane2, Pane3, default to Procyon)
//check by file extension to display image //check by file extension to display image
if (!onlyName.contains(":") && ResourceType.imageExtensionMap.containsKey(FilenameUtils.getExtension(onlyName)) && !hexViewerOnly) if (!onlyName.contains(":") && ResourceType.IMAGE_EXTENSION_MAP.containsKey(FilenameUtils.getExtension(onlyName)) && !hexViewerOnly)
{ {
canRefresh = true; canRefresh = true;

View File

@ -32,6 +32,7 @@ public abstract class AbstractJTabbedPanePopupMenuHandler extends JTabbedPanePop
public AbstractJTabbedPanePopupMenuHandler(JTabbedPane tabbedPane) public AbstractJTabbedPanePopupMenuHandler(JTabbedPane tabbedPane)
{ {
super(tabbedPane); super(tabbedPane);
registerPopupEventListener(this); registerPopupEventListener(this);
} }
@ -39,6 +40,7 @@ public abstract class AbstractJTabbedPanePopupMenuHandler extends JTabbedPanePop
public void onTabPopupEvent(JTabbedPane tabbedPane, int index, TabPopupEvent e) public void onTabPopupEvent(JTabbedPane tabbedPane, int index, TabPopupEvent e)
{ {
JPopupMenu popupMenu = toBuildTabPopupMenu(tabbedPane, e.getPopupOnTab()); JPopupMenu popupMenu = toBuildTabPopupMenu(tabbedPane, e.getPopupOnTab());
popupTabMenuWithEvent(popupMenu, e); popupTabMenuWithEvent(popupMenu, e);
} }

View File

@ -84,14 +84,11 @@ public class JTabbedPaneCloser
do do
{ {
Component c = this.tabbedPane.getComponentAt(i); Component c = this.tabbedPane.getComponentAt(i);
if (c != component) if (c != component)
{
removeTabs.add(c); removeTabs.add(c);
}
else else
{
break; break;
}
} while (i++ < count); } while (i++ < count);
for (Component c : removeTabs) for (Component c : removeTabs)

View File

@ -54,6 +54,7 @@ public class JTabbedPanePopupMenuTabsCloser extends AbstractJTabbedPanePopupMenu
public JPopupMenu toBuildTabPopupMenu(JTabbedPane tabbedPane, Component popupOnTab) public JPopupMenu toBuildTabPopupMenu(JTabbedPane tabbedPane, Component popupOnTab)
{ {
JPopupMenu popUpMenu = new JPopupMenu(); JPopupMenu popUpMenu = new JPopupMenu();
if (closeConfiguration.isClose()) if (closeConfiguration.isClose())
addItemCloseTab(popUpMenu, popupOnTab); addItemCloseTab(popUpMenu, popupOnTab);

View File

@ -23,15 +23,20 @@ import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.malwarescanner.impl.*; import the.bytecode.club.bytecodeviewer.malwarescanner.impl.*;
/** /**
* All of the installed malware scan modules * All the installed malware scan modules
* *
* @author Konloch * @author Konloch
* @since 6/27/2021 * @since 6/27/2021
*/ */
public enum MalwareScanModule public enum MalwareScanModule
{ {
URL_SCANNER("Scan String URLs", new URLScanner(), true), REFLECTION_SCANNER("Scan Java Reflection", new ReflectionScanner(), false), JAVA_RUNTIME_SCANNER("Scan Java Runtime", new JavaRuntimeScanner(), true), JAVA_NET_SCANNER("Scan Java Net", new JavaNetScanner(), false), JAVA_IO_SCANNER("Scan Java IO", new JavaIOScanner(), false), AWT_ROBOT_SCANNER("Scan AWT Robot", new AWTRobotScanner(), true), NULL_SECURITY_MANAGER("Scan Null SecurityManager", new NullSecurityManagerScanner(), true), URL_SCANNER("Scan String URLs", new URLScanner(), true),
; REFLECTION_SCANNER("Scan Java Reflection", new ReflectionScanner(), false),
JAVA_RUNTIME_SCANNER("Scan Java Runtime", new JavaRuntimeScanner(), true),
JAVA_NET_SCANNER("Scan Java Net", new JavaNetScanner(), false),
JAVA_IO_SCANNER("Scan Java IO", new JavaIOScanner(), false),
AWT_ROBOT_SCANNER("Scan AWT Robot", new AWTRobotScanner(), true),
NULL_SECURITY_MANAGER("Scan Null SecurityManager", new NullSecurityManagerScanner(), true);
static static
{ {

View File

@ -53,6 +53,7 @@ public class AWTRobotScanner extends MalwareCodeScanner
if (instruction instanceof MethodInsnNode) if (instruction instanceof MethodInsnNode)
{ {
final MethodInsnNode min = (MethodInsnNode) instruction; final MethodInsnNode min = (MethodInsnNode) instruction;
if (min.owner.startsWith("java/awt/Robot")) if (min.owner.startsWith("java/awt/Robot"))
foundMethod(scan, instructionToString(instruction) + " at " + methodToString(cn, method) + NL); foundMethod(scan, instructionToString(instruction) + " at " + methodToString(cn, method) + NL);
} }

View File

@ -47,6 +47,7 @@ public class JavaIOScanner extends MalwareCodeScanner
if (instruction instanceof MethodInsnNode) if (instruction instanceof MethodInsnNode)
{ {
final MethodInsnNode min = (MethodInsnNode) instruction; final MethodInsnNode min = (MethodInsnNode) instruction;
if (min.owner.startsWith("java/io")) if (min.owner.startsWith("java/io"))
foundMethod(scan, instructionToString(instruction) + " at " + methodToString(cn, method) + NL); foundMethod(scan, instructionToString(instruction) + " at " + methodToString(cn, method) + NL);
} }

View File

@ -48,6 +48,7 @@ public class JavaNetScanner extends MalwareCodeScanner
if (instruction instanceof MethodInsnNode) if (instruction instanceof MethodInsnNode)
{ {
final MethodInsnNode min = (MethodInsnNode) instruction; final MethodInsnNode min = (MethodInsnNode) instruction;
if (min.owner.startsWith("java/net")) if (min.owner.startsWith("java/net"))
foundMethod(scan, instructionToString(instruction) + " at " + methodToString(cn, method) + NL); foundMethod(scan, instructionToString(instruction) + " at " + methodToString(cn, method) + NL);
} }

View File

@ -53,6 +53,7 @@ public class JavaRuntimeScanner extends MalwareCodeScanner
if (instruction instanceof MethodInsnNode) if (instruction instanceof MethodInsnNode)
{ {
final MethodInsnNode min = (MethodInsnNode) instruction; final MethodInsnNode min = (MethodInsnNode) instruction;
if (min.owner.startsWith("java/lang/Runtime")) if (min.owner.startsWith("java/lang/Runtime"))
foundMethod(scan, instructionToString(instruction) + " at " + methodToString(cn, method) + NL); foundMethod(scan, instructionToString(instruction) + " at " + methodToString(cn, method) + NL);
} }

View File

@ -57,11 +57,11 @@ public class NullSecurityManagerScanner extends MalwareCodeScanner
final String owner = min.owner; final String owner = min.owner;
final String name = min.name; final String name = min.name;
if (lastInstruction == OpCode.ACONST_NULL.getCode() && owner.equals("java/lang/System") && name.equals("setSecurityManager")) if (lastInstruction == OpCode.ACONST_NULL.getCode()
{ && owner.equals("java/lang/System")
&& name.equals("setSecurityManager"))
found(scan, "Security Manager set to null at method " + methodToString(cn, method) + NL); found(scan, "Security Manager set to null at method " + methodToString(cn, method) + NL);
} }
}
lastInstruction = instruction.getOpcode(); lastInstruction = instruction.getOpcode();
} }
@ -70,6 +70,7 @@ public class NullSecurityManagerScanner extends MalwareCodeScanner
public void scanningClass(MalwareScan scan, ClassNode cn) public void scanningClass(MalwareScan scan, ClassNode cn)
{ {
lastInstruction = 0; lastInstruction = 0;
super.scanningClass(scan, cn); super.scanningClass(scan, cn);
} }
} }

View File

@ -50,6 +50,7 @@ public class ReflectionScanner extends MalwareCodeScanner
if (instruction instanceof MethodInsnNode) if (instruction instanceof MethodInsnNode)
{ {
final MethodInsnNode min = (MethodInsnNode) instruction; final MethodInsnNode min = (MethodInsnNode) instruction;
if (min.owner.startsWith("java/lang/reflect")) if (min.owner.startsWith("java/lang/reflect"))
foundMethod(scan, instructionToString(instruction) + " at " + methodToString(cn, method) + NL); foundMethod(scan, instructionToString(instruction) + " at " + methodToString(cn, method) + NL);
} }

View File

@ -34,12 +34,18 @@ import java.util.List;
public abstract class JavaObfuscator extends Thread public abstract class JavaObfuscator extends Thread
{ {
public static int MAX_STRING_LENGTH = 25;
public static int MIN_STRING_LENGTH = 5;
private final List<String> names = new ArrayList<>();
@Override @Override
public void run() public void run()
{ {
BytecodeViewer.updateBusyStatus(true); BytecodeViewer.updateBusyStatus(true);
Configuration.runningObfuscation = true; Configuration.runningObfuscation = true;
obfuscate(); obfuscate();
BytecodeViewer.refactorer.run(); BytecodeViewer.refactorer.run();
Configuration.runningObfuscation = false; Configuration.runningObfuscation = false;
BytecodeViewer.updateBusyStatus(false); BytecodeViewer.updateBusyStatus(false);
@ -48,24 +54,16 @@ public abstract class JavaObfuscator extends Thread
public int getStringLength() public int getStringLength()
{ {
if (BytecodeViewer.viewer.obfuscatorGroup.isSelected(BytecodeViewer.viewer.strongObf.getModel())) if (BytecodeViewer.viewer.obfuscatorGroup.isSelected(BytecodeViewer.viewer.strongObf.getModel()))
{
return MAX_STRING_LENGTH; return MAX_STRING_LENGTH;
} else // if(BytecodeViewer.viewer.obfuscatorGroup.isSelected(BytecodeViewer.viewer.lightObf.getModel()))
else
{ // if(BytecodeViewer.viewer.obfuscatorGroup.isSelected(BytecodeViewer.viewer.lightObf.getModel()))
// {
return MIN_STRING_LENGTH; return MIN_STRING_LENGTH;
} }
}
public static int MAX_STRING_LENGTH = 25;
public static int MIN_STRING_LENGTH = 5;
private final List<String> names = new ArrayList<>();
protected String generateUniqueName(int length) protected String generateUniqueName(int length)
{ {
boolean found = false; boolean found = false;
String name = ""; String name = "";
while (!found) while (!found)
{ {
String nameTry = MiscUtils.randomString(1) + MiscUtils.randomStringNum(length - 1); String nameTry = MiscUtils.randomString(1) + MiscUtils.randomStringNum(length - 1);
@ -79,6 +77,7 @@ public abstract class JavaObfuscator extends Thread
found = true; found = true;
} }
} }
return name; return name;
} }

View File

@ -37,6 +37,7 @@ public class RenameClasses extends JavaObfuscator
int stringLength = getStringLength(); int stringLength = getStringLength();
System.out.println("Obfuscating class names..."); System.out.println("Obfuscating class names...");
for (ClassNode c : BytecodeViewer.getLoadedClasses()) for (ClassNode c : BytecodeViewer.getLoadedClasses())
{ {
String newName = generateUniqueName(stringLength); String newName = generateUniqueName(stringLength);

View File

@ -38,6 +38,7 @@ public class RenameFields extends JavaObfuscator
int stringLength = getStringLength(); int stringLength = getStringLength();
System.out.println("Obfuscating fields names..."); System.out.println("Obfuscating fields names...");
for (ClassNode c : BytecodeViewer.getLoadedClasses()) for (ClassNode c : BytecodeViewer.getLoadedClasses())
{ {
for (Object o : c.fields.toArray()) for (Object o : c.fields.toArray())

View File

@ -39,6 +39,7 @@ public class RenameMethods extends JavaObfuscator
int stringLength = getStringLength(); int stringLength = getStringLength();
System.out.println("Obfuscating method names..."); System.out.println("Obfuscating method names...");
for (ClassNode c : BytecodeViewer.getLoadedClasses()) for (ClassNode c : BytecodeViewer.getLoadedClasses())
{ {
for (Object o : c.methods.toArray()) for (Object o : c.methods.toArray())

View File

@ -47,6 +47,7 @@ public class RefactorMapper extends Remapper
sortedFields = new HashMap<>(); sortedFields = new HashMap<>();
mappingList = new ArrayList<>(); mappingList = new ArrayList<>();
builder = new StringBuilder(); builder = new StringBuilder();
for (MappingData hook : hookMap.getClasses()) for (MappingData hook : hookMap.getClasses())
{ {
if (hook.getObfuscatedName().contains("$")) if (hook.getObfuscatedName().contains("$"))
@ -56,6 +57,7 @@ public class RefactorMapper extends Remapper
sortedClasses.put(obfuscatedName, hook); sortedClasses.put(obfuscatedName, hook);
sortedClasses.put(refactoredName, hook); sortedClasses.put(refactoredName, hook);
} }
for (MethodMappingData hook : hookMap.getMethods()) for (MethodMappingData hook : hookMap.getMethods())
{ {
String obfuscatedName = hook.getMethodName().getObfuscatedName(); String obfuscatedName = hook.getMethodName().getObfuscatedName();
@ -63,6 +65,7 @@ public class RefactorMapper extends Remapper
String obfuscatedCname = hook.getMethodOwner(); String obfuscatedCname = hook.getMethodOwner();
sortedMethods.put(obfuscatedCname + "$$$$" + obfuscatedName + "$$$$" + obfuscatedDesc, hook); sortedMethods.put(obfuscatedCname + "$$$$" + obfuscatedName + "$$$$" + obfuscatedDesc, hook);
} }
for (FieldMappingData hook : hookMap.getFields()) for (FieldMappingData hook : hookMap.getFields())
{ {
String obfuscatedName = hook.getName().getObfuscatedName(); String obfuscatedName = hook.getName().getObfuscatedName();
@ -83,6 +86,7 @@ public class RefactorMapper extends Remapper
return sortedClasses.get(type).getRefactoredName(); return sortedClasses.get(type).getRefactoredName();
} }
return type; return type;
} }
@ -90,6 +94,7 @@ public class RefactorMapper extends Remapper
public String mapFieldName(String owner, String name, String desc) public String mapFieldName(String owner, String name, String desc)
{ {
String obfKey = owner + "$$$$" + name + "$$$$" + desc; String obfKey = owner + "$$$$" + name + "$$$$" + desc;
if (sortedFields.containsKey(obfKey)) if (sortedFields.containsKey(obfKey))
{ {
String map = owner + "." + name + " --> " + owner + sortedFields.get(obfKey).getName().getRefactoredName() + "\n"; String map = owner + "." + name + " --> " + owner + sortedFields.get(obfKey).getName().getRefactoredName() + "\n";
@ -97,6 +102,7 @@ public class RefactorMapper extends Remapper
mappingList.add(map); mappingList.add(map);
name = sortedFields.get(obfKey).getName().getRefactoredName(); name = sortedFields.get(obfKey).getName().getRefactoredName();
} }
return name; return name;
} }
@ -104,6 +110,7 @@ public class RefactorMapper extends Remapper
public String mapMethodName(String owner, String name, String desc) public String mapMethodName(String owner, String name, String desc)
{ {
String obfKey = owner + "$$$$" + name + "$$$$" + desc; String obfKey = owner + "$$$$" + name + "$$$$" + desc;
if (sortedMethods.containsKey(obfKey)) if (sortedMethods.containsKey(obfKey))
{ {
String map = owner + "." + name + " --> " + owner + sortedMethods.get(obfKey).getMethodName().getRefactoredName() + "\n"; String map = owner + "." + name + " --> " + owner + sortedMethods.get(obfKey).getMethodName().getRefactoredName() + "\n";
@ -111,6 +118,7 @@ public class RefactorMapper extends Remapper
mappingList.add(map); mappingList.add(map);
name = sortedMethods.get(obfKey).getMethodName().getRefactoredName(); name = sortedMethods.get(obfKey).getMethodName().getRefactoredName();
} }
return name; return name;
} }
@ -120,6 +128,7 @@ public class RefactorMapper extends Remapper
{ {
builder.append(map); builder.append(map);
} }
System.out.println(builder.toString()); System.out.println(builder.toString());
} }
} }

View File

@ -60,9 +60,11 @@ public class Refactorer
cr.accept(cn, 0); cr.accept(cn, 0);
//refactored.put(oldName, cn); //refactored.put(oldName, cn);
} }
/*for (Map.Entry<String, ClassNode> factor : refactored.entrySet()) { /*for (Map.Entry<String, ClassNode> factor : refactored.entrySet()) {
BytecodeViewer.relocate(factor.getKey(), factor.getValue()); BytecodeViewer.relocate(factor.getKey(), factor.getValue());
}*/ }*/
mapper.printMap(); mapper.printMap();
} }

View File

@ -56,22 +56,26 @@ public abstract class Remapper extends org.objectweb.asm.commons.Remapper
public String mapDesc(String desc) public String mapDesc(String desc)
{ {
Type t = Type.getType(desc); Type t = Type.getType(desc);
switch (t.getSort()) switch (t.getSort())
{ {
case Type.ARRAY: case Type.ARRAY:
StringBuilder s = new StringBuilder(mapDesc(t.getElementType().getDescriptor())); StringBuilder s = new StringBuilder(mapDesc(t.getElementType().getDescriptor()));
for (int i = 0; i < t.getDimensions(); ++i) for (int i = 0; i < t.getDimensions(); ++i)
{ {
s.insert(0, '['); s.insert(0, '[');
} }
return s.toString(); return s.toString();
case Type.OBJECT: case Type.OBJECT:
String newType = map(t.getInternalName()); String newType = map(t.getInternalName());
if (newType != null) if (newType != null)
{
return 'L' + newType + ';'; return 'L' + newType + ';';
} }
}
return desc; return desc;
} }
@ -81,17 +85,22 @@ public abstract class Remapper extends org.objectweb.asm.commons.Remapper
{ {
case Type.ARRAY: case Type.ARRAY:
StringBuilder s = new StringBuilder(mapDesc(t.getElementType().getDescriptor())); StringBuilder s = new StringBuilder(mapDesc(t.getElementType().getDescriptor()));
for (int i = 0; i < t.getDimensions(); ++i) for (int i = 0; i < t.getDimensions(); ++i)
{ {
s.insert(0, '['); s.insert(0, '[');
} }
return Type.getType(s.toString()); return Type.getType(s.toString());
case Type.OBJECT: case Type.OBJECT:
s = new StringBuilder(map(t.getInternalName())); s = new StringBuilder(map(t.getInternalName()));
return Type.getObjectType(s.toString()); return Type.getObjectType(s.toString());
case Type.METHOD: case Type.METHOD:
return Type.getMethodType(mapMethodDesc(t.getDescriptor())); return Type.getMethodType(mapMethodDesc(t.getDescriptor()));
} }
return t; return t;
} }
@ -99,9 +108,8 @@ public abstract class Remapper extends org.objectweb.asm.commons.Remapper
public String mapType(String type) public String mapType(String type)
{ {
if (type == null) if (type == null)
{
return null; return null;
}
return mapType(Type.getObjectType(type)).getInternalName(); return mapType(Type.getObjectType(type)).getInternalName();
} }
@ -110,24 +118,26 @@ public abstract class Remapper extends org.objectweb.asm.commons.Remapper
{ {
String[] newTypes = null; String[] newTypes = null;
boolean needMapping = false; boolean needMapping = false;
for (int i = 0; i < types.length; i++) for (int i = 0; i < types.length; i++)
{ {
String type = types[i]; String type = types[i];
String newType = map(type); String newType = map(type);
if (newType != null && newTypes == null) if (newType != null && newTypes == null)
{ {
newTypes = new String[types.length]; newTypes = new String[types.length];
if (i > 0) if (i > 0)
{
System.arraycopy(types, 0, newTypes, 0, i); System.arraycopy(types, 0, newTypes, 0, i);
}
needMapping = true; needMapping = true;
} }
if (needMapping) if (needMapping)
{
newTypes[i] = newType == null ? type : newType; newTypes[i] = newType == null ? type : newType;
} }
}
return needMapping ? newTypes : types; return needMapping ? newTypes : types;
} }
@ -135,22 +145,24 @@ public abstract class Remapper extends org.objectweb.asm.commons.Remapper
public String mapMethodDesc(String desc) public String mapMethodDesc(String desc)
{ {
if ("()V".equals(desc)) if ("()V".equals(desc))
{
return desc; return desc;
}
Type[] args = Type.getArgumentTypes(desc); Type[] args = Type.getArgumentTypes(desc);
StringBuilder sb = new StringBuilder("("); StringBuilder sb = new StringBuilder("(");
for (Type arg : args) for (Type arg : args)
{ {
sb.append(mapDesc(arg.getDescriptor())); sb.append(mapDesc(arg.getDescriptor()));
} }
Type returnType = Type.getReturnType(desc); Type returnType = Type.getReturnType(desc);
if (returnType == Type.VOID_TYPE) if (returnType == Type.VOID_TYPE)
{ {
sb.append(")V"); sb.append(")V");
return sb.toString(); return sb.toString();
} }
sb.append(')').append(mapDesc(returnType.getDescriptor())); sb.append(')').append(mapDesc(returnType.getDescriptor()));
return sb.toString(); return sb.toString();
} }
@ -159,14 +171,14 @@ public abstract class Remapper extends org.objectweb.asm.commons.Remapper
public Object mapValue(Object value) public Object mapValue(Object value)
{ {
if (value instanceof Type) if (value instanceof Type)
{
return mapType((Type) value); return mapType((Type) value);
}
if (value instanceof Handle) if (value instanceof Handle)
{ {
Handle h = (Handle) value; Handle h = (Handle) value;
return new Handle(h.getTag(), mapType(h.getOwner()), mapMethodName(h.getOwner(), h.getName(), h.getDesc()), mapMethodDesc(h.getDesc()), h.getTag() == Opcodes.H_INVOKEINTERFACE); return new Handle(h.getTag(), mapType(h.getOwner()), mapMethodName(h.getOwner(), h.getName(), h.getDesc()), mapMethodDesc(h.getDesc()), h.getTag() == Opcodes.H_INVOKEINTERFACE);
} }
return value; return value;
} }
@ -179,20 +191,17 @@ public abstract class Remapper extends org.objectweb.asm.commons.Remapper
public String mapSignature(String signature, boolean typeSignature) public String mapSignature(String signature, boolean typeSignature)
{ {
if (signature == null) if (signature == null)
{
return null; return null;
}
SignatureReader r = new SignatureReader(signature); SignatureReader r = new SignatureReader(signature);
SignatureWriter w = new SignatureWriter(); SignatureWriter w = new SignatureWriter();
SignatureVisitor a = createSignatureRemapper(w); SignatureVisitor a = createSignatureRemapper(w);
if (typeSignature) if (typeSignature)
{
r.acceptType(a); r.acceptType(a);
}
else else
{
r.accept(a); r.accept(a);
}
return w.toString(); return w.toString();
} }

View File

@ -106,9 +106,11 @@ public class RemappingMethodAdapter extends LocalVariablesSorter
Object t = entries[i]; Object t = entries[i];
newEntries[i++] = t instanceof String ? remapper.mapType((String) t) : t; newEntries[i++] = t instanceof String ? remapper.mapType((String) t) : t;
} while (i < n); } while (i < n);
return newEntries; return newEntries;
} }
} }
return entries; return entries;
} }
@ -127,6 +129,7 @@ public class RemappingMethodAdapter extends LocalVariablesSorter
super.visitMethodInsn(opcode, owner, name, desc); super.visitMethodInsn(opcode, owner, name, desc);
return; return;
} }
doVisitMethodInsn(opcode, owner, name, desc, opcode == Opcodes.INVOKEINTERFACE); doVisitMethodInsn(opcode, owner, name, desc, opcode == Opcodes.INVOKEINTERFACE);
} }
@ -138,6 +141,7 @@ public class RemappingMethodAdapter extends LocalVariablesSorter
super.visitMethodInsn(opcode, owner, name, desc, itf); super.visitMethodInsn(opcode, owner, name, desc, itf);
return; return;
} }
doVisitMethodInsn(opcode, owner, name, desc, itf); doVisitMethodInsn(opcode, owner, name, desc, itf);
} }
@ -150,10 +154,8 @@ public class RemappingMethodAdapter extends LocalVariablesSorter
// IMPORTANT: THIS ASSUMES THAT visitMethodInsn IS NOT OVERRIDDEN IN // IMPORTANT: THIS ASSUMES THAT visitMethodInsn IS NOT OVERRIDDEN IN
// LocalVariableSorter. // LocalVariableSorter.
if (mv != null) if (mv != null)
{
mv.visitMethodInsn(opcode, remapper.mapType(owner), remapper.mapMethodName(owner, name, desc), remapper.mapMethodDesc(desc), itf); mv.visitMethodInsn(opcode, remapper.mapType(owner), remapper.mapMethodName(owner, name, desc), remapper.mapMethodDesc(desc), itf);
} }
}
@Override @Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs)
@ -162,6 +164,7 @@ public class RemappingMethodAdapter extends LocalVariablesSorter
{ {
bsmArgs[i] = remapper.mapValue(bsmArgs[i]); bsmArgs[i] = remapper.mapValue(bsmArgs[i]);
} }
super.visitInvokeDynamicInsn(remapper.mapInvokeDynamicMethodName(name, desc), remapper.mapMethodDesc(desc), (Handle) remapper.mapValue(bsm), bsmArgs); super.visitInvokeDynamicInsn(remapper.mapInvokeDynamicMethodName(name, desc), remapper.mapMethodDesc(desc), (Handle) remapper.mapValue(bsm), bsmArgs);
} }

View File

@ -90,7 +90,9 @@ public class FieldMappingData
return false; return false;
if (getClass() != obj.getClass()) if (getClass() != obj.getClass())
return false; return false;
FieldMappingData other = (FieldMappingData) obj; FieldMappingData other = (FieldMappingData) obj;
if (desc == null) if (desc == null)
{ {
if (other.desc != null) if (other.desc != null)
@ -98,6 +100,7 @@ public class FieldMappingData
} }
else if (!desc.equals(other.desc)) else if (!desc.equals(other.desc))
return false; return false;
if (fieldOwner == null) if (fieldOwner == null)
{ {
if (other.fieldOwner != null) if (other.fieldOwner != null)
@ -105,10 +108,9 @@ public class FieldMappingData
} }
else if (!fieldOwner.equals(other.fieldOwner)) else if (!fieldOwner.equals(other.fieldOwner))
return false; return false;
if (name == null) if (name == null)
{
return other.name == null; return other.name == null;
}
else else
return name.equals(other.name); return name.equals(other.name);
} }

View File

@ -76,7 +76,9 @@ public class MappingData
return false; return false;
if (getClass() != obj.getClass()) if (getClass() != obj.getClass())
return false; return false;
MappingData other = (MappingData) obj; MappingData other = (MappingData) obj;
if (obfuscatedName == null) if (obfuscatedName == null)
{ {
if (other.obfuscatedName != null) if (other.obfuscatedName != null)
@ -84,10 +86,9 @@ public class MappingData
} }
else if (!obfuscatedName.equals(other.obfuscatedName)) else if (!obfuscatedName.equals(other.obfuscatedName))
return false; return false;
if (refactoredName == null) if (refactoredName == null)
{
return other.refactoredName == null; return other.refactoredName == null;
}
else else
return refactoredName.equals(other.refactoredName); return refactoredName.equals(other.refactoredName);
} }

View File

@ -90,7 +90,9 @@ public class MethodMappingData
return false; return false;
if (getClass() != obj.getClass()) if (getClass() != obj.getClass())
return false; return false;
MethodMappingData other = (MethodMappingData) obj; MethodMappingData other = (MethodMappingData) obj;
if (methodDesc == null) if (methodDesc == null)
{ {
if (other.methodDesc != null) if (other.methodDesc != null)
@ -98,6 +100,7 @@ public class MethodMappingData
} }
else if (!methodDesc.equals(other.methodDesc)) else if (!methodDesc.equals(other.methodDesc))
return false; return false;
if (methodName == null) if (methodName == null)
{ {
if (other.methodName != null) if (other.methodName != null)
@ -105,10 +108,9 @@ public class MethodMappingData
} }
else if (!methodName.equals(other.methodName)) else if (!methodName.equals(other.methodName))
return false; return false;
if (methodOwner == null) if (methodOwner == null)
{
return other.methodOwner == null; return other.methodOwner == null;
}
else else
return methodOwner.equals(other.methodOwner); return methodOwner.equals(other.methodOwner);
} }

View File

@ -42,7 +42,9 @@ public class RenameClasses extends JavaObfuscator
BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish" + "."); BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish" + ".");
return; return;
} }
new RenameClasses().start(); new RenameClasses().start();
BytecodeViewer.viewer.workPane.refreshClass.doClick(); BytecodeViewer.viewer.workPane.refreshClass.doClick();
BytecodeViewer.viewer.resourcePane.tree.updateUI(); BytecodeViewer.viewer.resourcePane.tree.updateUI();
} }
@ -61,7 +63,8 @@ public class RenameClasses extends JavaObfuscator
for (MethodNode o : c.methods) for (MethodNode o : c.methods)
{ {
/* As we dont want to rename any main-classes */ /* As we dont want to rename any main-classes */
if (o.name.equals("main") && o.desc.equals("([Ljava/lang/String;)V") || o.name.equals("init") && c.superName.equals("java/applet/Applet")) if (o.name.equals("main") && o.desc.equals("([Ljava/lang/String;)V")
|| o.name.equals("init") && c.superName.equals("java/applet/Applet"))
continue classLoop; continue classLoop;
/* As we dont want to rename native dll methods */ /* As we dont want to rename native dll methods */

View File

@ -42,7 +42,9 @@ public class RenameFields extends JavaObfuscator
BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish."); BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish.");
return; return;
} }
new RenameFields().start(); new RenameFields().start();
BytecodeViewer.viewer.workPane.refreshClass.doClick(); BytecodeViewer.viewer.workPane.refreshClass.doClick();
BytecodeViewer.viewer.resourcePane.tree.updateUI(); BytecodeViewer.viewer.resourcePane.tree.updateUI();
} }

View File

@ -43,7 +43,9 @@ public class RenameMethods extends JavaObfuscator
BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish" + "."); BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish" + ".");
return; return;
} }
new RenameMethods().start(); new RenameMethods().start();
BytecodeViewer.viewer.workPane.refreshClass.doClick(); BytecodeViewer.viewer.workPane.refreshClass.doClick();
BytecodeViewer.viewer.resourcePane.tree.updateUI(); BytecodeViewer.viewer.resourcePane.tree.updateUI();
} }

View File

@ -219,14 +219,13 @@ public class AllatoriStringDecrypter extends Plugin
if (i instanceof MethodInsnNode) if (i instanceof MethodInsnNode)
{ {
MethodInsnNode methodi = ((MethodInsnNode) i); MethodInsnNode methodi = ((MethodInsnNode) i);
if ("currentThread".equals(methodi.name)) // find code form this instruction if ("currentThread".equals(methodi.name)) // find code form this instruction
{ {
insn = i; insn = i;
break; break;
} }
} }
} }
if (insn == null) if (insn == null)
@ -241,6 +240,7 @@ public class AllatoriStringDecrypter extends Plugin
if ("hashCode".equals(methodi.name)) // to this instruction if ("hashCode".equals(methodi.name)) // to this instruction
break; break;
} }
removeInsn = insn; removeInsn = insn;
insn = insn.getNext(); insn = insn.getNext();
iList.remove(removeInsn); // and remove it iList.remove(removeInsn); // and remove it

View File

@ -75,6 +75,7 @@ public class ReplaceStrings extends Plugin
if (v instanceof String) if (v instanceof String)
{ {
String s = (String) v; String s = (String) v;
if (contains) if (contains)
{ {
if (s.contains(originalLDC)) if (s.contains(originalLDC))
@ -92,6 +93,7 @@ public class ReplaceStrings extends Plugin
for (int i = 0; i < ((String[]) v).length; i++) for (int i = 0; i < ((String[]) v).length; i++)
{ {
String s = ((String[]) v)[i]; String s = ((String[]) v)[i];
if (contains) if (contains)
{ {
if (s.contains(originalLDC)) if (s.contains(originalLDC))
@ -118,6 +120,7 @@ public class ReplaceStrings extends Plugin
{ {
MethodNode m = (MethodNode) o; MethodNode m = (MethodNode) o;
InsnList iList = m.instructions; InsnList iList = m.instructions;
for (AbstractInsnNode a : iList.toArray()) for (AbstractInsnNode a : iList.toArray())
{ {
if (a instanceof LdcInsnNode) if (a instanceof LdcInsnNode)
@ -125,6 +128,7 @@ public class ReplaceStrings extends Plugin
if (((LdcInsnNode) a).cst instanceof String) if (((LdcInsnNode) a).cst instanceof String)
{ {
final String s = (String) ((LdcInsnNode) a).cst; final String s = (String) ((LdcInsnNode) a).cst;
if (contains) if (contains)
{ {
if (s.contains(originalLDC)) if (s.contains(originalLDC))

View File

@ -38,6 +38,7 @@ public class ViewAPKAndroidPermissions extends Plugin
frame.setVisible(true); frame.setVisible(true);
byte[] encodedAndroidManifest = activeContainer.getFileContents("AndroidManifest.xml"); byte[] encodedAndroidManifest = activeContainer.getFileContents("AndroidManifest.xml");
if (encodedAndroidManifest == null) if (encodedAndroidManifest == null)
{ {
frame.appendText("This plugin only works on valid Android APKs"); frame.appendText("This plugin only works on valid Android APKs");
@ -45,6 +46,7 @@ public class ViewAPKAndroidPermissions extends Plugin
} }
byte[] decodedAndroidManifest = activeContainer.getFileContents("Decoded Resources/AndroidManifest.xml"); byte[] decodedAndroidManifest = activeContainer.getFileContents("Decoded Resources/AndroidManifest.xml");
if (decodedAndroidManifest != null) if (decodedAndroidManifest != null)
{ {
String manifest = new String(decodedAndroidManifest, StandardCharsets.UTF_8); String manifest = new String(decodedAndroidManifest, StandardCharsets.UTF_8);

View File

@ -39,6 +39,7 @@ public class ViewManifest extends Plugin
//TODO android APKs may have AndroidManifests that can be viewed normally, this should be checked //TODO android APKs may have AndroidManifests that can be viewed normally, this should be checked
byte[] encodedAndroidManifest = activeContainer.getFileContents("AndroidManifest.xml"); byte[] encodedAndroidManifest = activeContainer.getFileContents("AndroidManifest.xml");
if (encodedAndroidManifest != null) if (encodedAndroidManifest != null)
{ {
frame.appendText("Android APK Manifest:\r"); frame.appendText("Android APK Manifest:\r");
@ -50,6 +51,7 @@ public class ViewManifest extends Plugin
} }
byte[] jarManifest = activeContainer.getFileContents("META-INF/MANIFEST.MF"); byte[] jarManifest = activeContainer.getFileContents("META-INF/MANIFEST.MF");
if (jarManifest != null) if (jarManifest != null)
{ {
if (!frame.getTextArea().getText().isEmpty()) if (!frame.getTextArea().getText().isEmpty())

View File

@ -52,11 +52,13 @@ public class ZStringArrayDecrypter extends Plugin
if (dialog.promptChoice() == 0) if (dialog.promptChoice() == 0)
{ {
boolean needsWarning = false; boolean needsWarning = false;
for (Class<?> cn : Objects.requireNonNull(BCV.loadClassesIntoClassLoader())) for (Class<?> cn : Objects.requireNonNull(BCV.loadClassesIntoClassLoader()))
{ {
try try
{ {
Field[] fields = cn.getDeclaredFields(); Field[] fields = cn.getDeclaredFields();
for (Field field : fields) for (Field field : fields)
{ {
if (field.getName().equals("z")) if (field.getName().equals("z"))
@ -81,9 +83,8 @@ public class ZStringArrayDecrypter extends Plugin
} }
if (needsWarning) if (needsWarning)
{ BytecodeViewer.showMessage("Some classes failed to decrypt, if you'd like to decrypt all of them"
BytecodeViewer.showMessage("Some classes failed to decrypt, if you'd like to decrypt all of them" + NL + "makes sure you include ALL the libraries it requires."); + NL + "makes sure you include ALL the libraries it requires.");
}
gui.setText(out.toString()); gui.setText(out.toString());
gui.setVisible(true); gui.setVisible(true);

View File

@ -56,15 +56,11 @@ public class CompiledJavaPluginLaunchStrategy implements PluginLaunchStrategy
if (Objects.equals(cn.superName, PLUGIN_CLASS_NAME)) if (Objects.equals(cn.superName, PLUGIN_CLASS_NAME))
{ {
if (pdata == null) if (pdata == null)
{
pdata = d; pdata = d;
}
else else
{
throw new RuntimeException("Multiple plugin subclasses."); throw new RuntimeException("Multiple plugin subclasses.");
} }
} }
}
LoadingClassLoader cl = new LoadingClassLoader(pdata, set); LoadingClassLoader cl = new LoadingClassLoader(pdata, set);
Plugin p = cl.pluginKlass.getDeclaredConstructor().newInstance(); Plugin p = cl.pluginKlass.getDeclaredConstructor().newInstance();
@ -92,9 +88,11 @@ public class CompiledJavaPluginLaunchStrategy implements PluginLaunchStrategy
try try
{ {
String name = entry.getName(); String name = entry.getName();
if (name.endsWith(".class")) if (name.endsWith(".class"))
{ {
byte[] bytes = MiscUtils.getBytes(jis); byte[] bytes = MiscUtils.getBytes(jis);
if (FileHeaderUtils.doesFileHeaderMatch(bytes, FileHeaderUtils.JAVA_CLASS_FILE_HEADER)) if (FileHeaderUtils.doesFileHeaderMatch(bytes, FileHeaderUtils.JAVA_CLASS_FILE_HEADER))
{ {
try try
@ -174,20 +172,20 @@ public class CompiledJavaPluginLaunchStrategy implements PluginLaunchStrategy
public static class LoadingClassLoader extends ClassLoader public static class LoadingClassLoader extends ClassLoader
{ {
private final LoadedNodeData data; private final LoadedNodeData data;
private final Map<String, LoadedNodeData> cache; private final Map<String, LoadedNodeData> nodeCache;
private final Map<String, Class<?>> ccache; private final Map<String, Class<?>> classCache;
private final Class<? extends Plugin> pluginKlass; private final Class<? extends Plugin> pluginKlass;
public LoadingClassLoader(LoadedNodeData data, Set<LoadedNodeData> set) throws Throwable public LoadingClassLoader(LoadedNodeData data, Set<LoadedNodeData> set) throws Throwable
{ {
this.data = data; this.data = data;
cache = new HashMap<>(); nodeCache = new HashMap<>();
ccache = new HashMap<>(); classCache = new HashMap<>();
for (LoadedNodeData d : set) for (LoadedNodeData d : set)
{ {
cache.put(d.node.name, d); nodeCache.put(d.node.name, d);
} }
@SuppressWarnings("unchecked") Class<? extends Plugin> pluginKlass = (Class<? extends Plugin>) loadClass(data.node.name.replace("/", ".")); @SuppressWarnings("unchecked") Class<? extends Plugin> pluginKlass = (Class<? extends Plugin>) loadClass(data.node.name.replace("/", "."));
@ -205,15 +203,16 @@ public class CompiledJavaPluginLaunchStrategy implements PluginLaunchStrategy
System.out.println("finding " + name); System.out.println("finding " + name);
if (ccache.containsKey(name)) if (classCache.containsKey(name))
return ccache.get(name); return classCache.get(name);
LoadedNodeData data = nodeCache.get(name);
LoadedNodeData data = cache.get(name);
if (data != null) if (data != null)
{ {
byte[] bytes = data.bytes; byte[] bytes = data.bytes;
Class<?> klass = defineClass(data.node.name.replace("/", "."), bytes, 0, bytes.length); Class<?> klass = defineClass(data.node.name.replace("/", "."), bytes, 0, bytes.length);
ccache.put(name, klass); classCache.put(name, klass);
return klass; return klass;
} }

View File

@ -70,7 +70,8 @@ public class ResourceDecompiling
if (!BytecodeViewer.autoCompileSuccessful()) if (!BytecodeViewer.autoCompileSuccessful())
return; return;
final JFileChooser fc = new FileChooser(Configuration.getLastSaveDirectory(), "Select Zip Export", "Zip Archives", "zip"); final JFileChooser fc = new FileChooser(Configuration.getLastSaveDirectory(),
"Select Zip Export", "Zip Archives", "zip");
//if the user doesn't select a file then we should stop while we're ahead //if the user doesn't select a file then we should stop while we're ahead
if (fc.showSaveDialog(BytecodeViewer.viewer) != JFileChooser.APPROVE_OPTION) if (fc.showSaveDialog(BytecodeViewer.viewer) != JFileChooser.APPROVE_OPTION)
@ -87,7 +88,8 @@ public class ResourceDecompiling
return; return;
//this temporary jar file will be used to store the classes while BCV performs decompilation //this temporary jar file will be used to store the classes while BCV performs decompilation
File temporaryTargetJar = MiscUtils.deleteExistingFile(new File(TEMP_DIRECTORY + FS + "temp_" + MiscUtils.getRandomizedName() + ".jar")); File temporaryTargetJar = MiscUtils.deleteExistingFile(new File(TEMP_DIRECTORY + FS
+ "temp_" + MiscUtils.getRandomizedName() + ".jar"));
//extract all the loaded classes imported into BCV to the temporary target jar //extract all the loaded classes imported into BCV to the temporary target jar
JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), temporaryTargetJar.getAbsolutePath()); JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), temporaryTargetJar.getAbsolutePath());
@ -254,7 +256,8 @@ public class ResourceDecompiling
BytecodeViewer.updateBusyStatus(true); BytecodeViewer.updateBusyStatus(true);
//decompile all opened classes to zip //decompile all opened classes to zip
decompiler.getDecompiler().decompileToZip(targetJar.getAbsolutePath(), saveAll ? MiscUtils.append(outputZip, "-" + decompiler.getDecompilerNameProgrammic() + ".zip") : outputZip.getAbsolutePath()); decompiler.getDecompiler().decompileToZip(targetJar.getAbsolutePath(), saveAll ? MiscUtils.append(outputZip,
"-" + decompiler.getDecompilerNameProgrammic() + ".zip") : outputZip.getAbsolutePath());
//signal to the user that BCV is finished performing that action //signal to the user that BCV is finished performing that action
BytecodeViewer.updateBusyStatus(false); BytecodeViewer.updateBusyStatus(false);
@ -266,7 +269,8 @@ public class ResourceDecompiling
BytecodeViewer.updateBusyStatus(true); BytecodeViewer.updateBusyStatus(true);
//decompile the currently opened resource and save it to the specified file //decompile the currently opened resource and save it to the specified file
DiskWriter.replaceFile(saveAll ? MiscUtils.append(outputFile, "-" + decompiler.getDecompilerNameProgrammic() + ".java") : outputFile.getAbsolutePath(), BCV.decompileCurrentlyOpenedClassNode(decompiler), false); DiskWriter.replaceFile(saveAll ? MiscUtils.append(outputFile,
"-" + decompiler.getDecompilerNameProgrammic() + ".java") : outputFile.getAbsolutePath(), BCV.decompileCurrentlyOpenedClassNode(decompiler), false);
//signal to the user that BCV is finished performing that action //signal to the user that BCV is finished performing that action
BytecodeViewer.updateBusyStatus(false); BytecodeViewer.updateBusyStatus(false);

View File

@ -38,18 +38,18 @@ public enum ResourceType
ZIP_ARCHIVE(IconResources.zipIcon, "zip"), ZIP_ARCHIVE(IconResources.zipIcon, "zip"),
ANDROID_ARCHIVE(IconResources.androidIcon, "apk", "wapk", "dex", "xapk"), ANDROID_ARCHIVE(IconResources.androidIcon, "apk", "wapk", "dex", "xapk"),
IMAGE_FILE(IconResources.imageIcon, "png", "jpg", "jpeg", "bmp", "wbmp", "gif", "tif", "webp"), IMAGE_FILE(IconResources.imageIcon, "png", "jpg", "jpeg", "bmp", "wbmp", "gif", "tif", "webp"),
CONFIG_TEXT_FILE(IconResources.configIcon, "properties", "xml", "jsp", "mf", "config", "csv", "yml", "yaml", "ini", "json", "sql", "gradle", "dockerfile", "htaccess", "plugin", "attachprovider", "transportservice", "connector"), CONFIG_TEXT_FILE(IconResources.configIcon, "properties", "xml", "jsp", "mf", "config", "csv", "yml", "yaml", "ini",
"json", "sql", "gradle", "dockerfile", "htaccess", "plugin", "attachprovider", "transportservice", "connector"),
JAVA_FILE(IconResources.javaIcon, "java"), JAVA_FILE(IconResources.javaIcon, "java"),
TEXT_FILE(IconResources.textIcon, "txt", "md", "log", "html", "css"), TEXT_FILE(IconResources.textIcon, "txt", "md", "log", "html", "css"),
CPP_FILE(IconResources.cplusplusIcon, "c", "cpp", "h"), CPP_FILE(IconResources.cplusplusIcon, "c", "cpp", "h"),
CSHARP_FILE(IconResources.csharpIcon, "cs"), CSHARP_FILE(IconResources.csharpIcon, "cs"),
BAT_FILE(IconResources.batIcon, "bat", "batch"), BAT_FILE(IconResources.batIcon, "bat", "batch"),
SH_FILE(IconResources.shIcon, "sh", "bash"), SH_FILE(IconResources.shIcon, "sh", "bash");
;
public static final Map<String, ResourceType> extensionMap = new HashMap<>(); public static final Map<String, ResourceType> EXTENSION_MAP = new HashMap<>();
public static final Map<String, ResourceType> imageExtensionMap = new HashMap<>(); public static final Map<String, ResourceType> IMAGE_EXTENSION_MAP = new HashMap<>();
public static final Map<String, ResourceType> supportedBCVExtensionMap = new HashMap<>(); public static final Map<String, ResourceType> SUPPORTED_BCV_EXTENSION_MAP = new HashMap<>();
private final Icon icon; private final Icon icon;
private final String[] extensions; private final String[] extensions;
@ -60,21 +60,21 @@ public enum ResourceType
//add all extensions //add all extensions
for (ResourceType t : values()) for (ResourceType t : values())
for (String extension : t.extensions) for (String extension : t.extensions)
extensionMap.put(extension, t); EXTENSION_MAP.put(extension, t);
//add image extensions //add image extensions
for (String extension : IMAGE_FILE.extensions) for (String extension : IMAGE_FILE.extensions)
imageExtensionMap.put(extension, IMAGE_FILE); IMAGE_EXTENSION_MAP.put(extension, IMAGE_FILE);
//add extensions BCV can be opened with //add extensions BCV can be opened with
for (String extension : CLASS_FILE.extensions) for (String extension : CLASS_FILE.extensions)
supportedBCVExtensionMap.put(extension, CLASS_FILE); SUPPORTED_BCV_EXTENSION_MAP.put(extension, CLASS_FILE);
for (String extension : JAVA_ARCHIVE.extensions) for (String extension : JAVA_ARCHIVE.extensions)
supportedBCVExtensionMap.put(extension, JAVA_ARCHIVE); SUPPORTED_BCV_EXTENSION_MAP.put(extension, JAVA_ARCHIVE);
for (String extension : ZIP_ARCHIVE.extensions) for (String extension : ZIP_ARCHIVE.extensions)
supportedBCVExtensionMap.put(extension, ZIP_ARCHIVE); SUPPORTED_BCV_EXTENSION_MAP.put(extension, ZIP_ARCHIVE);
for (String extension : ANDROID_ARCHIVE.extensions) for (String extension : ANDROID_ARCHIVE.extensions)
supportedBCVExtensionMap.put(extension, ANDROID_ARCHIVE); SUPPORTED_BCV_EXTENSION_MAP.put(extension, ANDROID_ARCHIVE);
} }
ResourceType(Icon icon, String... extensions) ResourceType(Icon icon, String... extensions)

View File

@ -64,7 +64,8 @@ public class JarUtils
ResourceContainer container = new ResourceContainer(jarFile); ResourceContainer container = new ResourceContainer(jarFile);
Map<String, byte[]> files = new LinkedHashMap<>(); Map<String, byte[]> files = new LinkedHashMap<>();
try (FileInputStream fis = new FileInputStream(jarFile); ZipInputStream jis = new ZipInputStream(fis)) try (FileInputStream fis = new FileInputStream(jarFile);
ZipInputStream jis = new ZipInputStream(fis))
{ {
ZipEntry entry; ZipEntry entry;
while ((entry = jis.getNextEntry()) != null) while ((entry = jis.getNextEntry()) != null)
@ -184,7 +185,8 @@ public class JarUtils
public static List<ClassNode> loadClasses(File jarFile) throws IOException public static List<ClassNode> loadClasses(File jarFile) throws IOException
{ {
List<ClassNode> classes = new ArrayList<>(); List<ClassNode> classes = new ArrayList<>();
try (FileInputStream fis = new FileInputStream(jarFile); ZipInputStream jis = new ZipInputStream(fis)) try (FileInputStream fis = new FileInputStream(jarFile);
ZipInputStream jis = new ZipInputStream(fis))
{ {
ZipEntry entry; ZipEntry entry;
while ((entry = jis.getNextEntry()) != null) while ((entry = jis.getNextEntry()) != null)
@ -405,7 +407,8 @@ public class JarUtils
*/ */
public static void saveAsJar(List<ClassNode> nodeList, String path) public static void saveAsJar(List<ClassNode> nodeList, String path)
{ {
try (FileOutputStream fos = new FileOutputStream(path); JarOutputStream out = new JarOutputStream(fos)) try (FileOutputStream fos = new FileOutputStream(path);
JarOutputStream out = new JarOutputStream(fos))
{ {
List<String> noDupe = new ArrayList<>(); List<String> noDupe = new ArrayList<>();
for (ClassNode cn : nodeList) for (ClassNode cn : nodeList)

View File

@ -56,8 +56,10 @@ public class MiscUtils
public static String randomString(int len) public static String randomString(int len)
{ {
StringBuilder sb = new StringBuilder(len); StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
sb.append(AB.charAt(RND.nextInt(AB.length()))); sb.append(AB.charAt(RND.nextInt(AB.length())));
return sb.toString(); return sb.toString();
} }
@ -70,9 +72,11 @@ public class MiscUtils
{ {
boolean generated = false; boolean generated = false;
String name = ""; String name = "";
while (!generated) while (!generated)
{ {
String randomizedName = MiscUtils.randomString(25); String randomizedName = MiscUtils.randomString(25);
if (!CREATED_RANDOMIZED_NAMES.contains(randomizedName)) if (!CREATED_RANDOMIZED_NAMES.contains(randomizedName))
{ {
CREATED_RANDOMIZED_NAMES.add(randomizedName); CREATED_RANDOMIZED_NAMES.add(randomizedName);
@ -80,6 +84,7 @@ public class MiscUtils
generated = true; generated = true;
} }
} }
return name; return name;
} }
@ -87,7 +92,8 @@ public class MiscUtils
{ {
//Read out dir output //Read out dir output
try (InputStream is = process.getInputStream(); try (InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr)) InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr))
{ {
String line; String line;
while ((line = br.readLine()) != null) while ((line = br.readLine()) != null)
@ -117,8 +123,10 @@ public class MiscUtils
public static String randomStringNum(int len) public static String randomStringNum(int len)
{ {
StringBuilder sb = new StringBuilder(len); StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
sb.append(AN.charAt(RND.nextInt(AN.length()))); sb.append(AN.charAt(RND.nextInt(AN.length())));
return sb.toString(); return sb.toString();
} }
@ -135,10 +143,12 @@ public class MiscUtils
boolean b = true; boolean b = true;
File f; File f;
String m; String m;
while (b) while (b)
{ {
m = MiscUtils.randomString(32); m = MiscUtils.randomString(32);
f = new File(start + m + ext); f = new File(start + m + ext);
if (!f.exists()) if (!f.exists())
{ {
s = start + m; s = start + m;
@ -159,14 +169,17 @@ public class MiscUtils
{ {
boolean b = true; boolean b = true;
int i = 0; int i = 0;
while (b) while (b)
{ {
File tempF = new File(start + i + ext); File tempF = new File(start + i + ext);
if (!tempF.exists()) if (!tempF.exists())
b = false; b = false;
else else
i++; i++;
} }
return i; return i;
} }
@ -186,14 +199,17 @@ public class MiscUtils
public static String append(File file, String extension) public static String append(File file, String extension)
{ {
String path = file.getAbsolutePath(); String path = file.getAbsolutePath();
if (!path.endsWith(extension)) if (!path.endsWith(extension))
path += extension; path += extension;
return path; return path;
} }
public static int fileContainersHash(List<ResourceContainer> resourceContainers) public static int fileContainersHash(List<ResourceContainer> resourceContainers)
{ {
StringBuilder block = new StringBuilder(); StringBuilder block = new StringBuilder();
for (ResourceContainer container : resourceContainers) for (ResourceContainer container : resourceContainers)
{ {
block.append(container.name); block.append(container.name);
@ -246,6 +262,7 @@ public class MiscUtils
public static void deduplicateAndTrim(List<String> list, int maxLength) public static void deduplicateAndTrim(List<String> list, int maxLength)
{ {
List<String> temporaryList = new ArrayList<>(); List<String> temporaryList = new ArrayList<>();
for (String s : list) for (String s : list)
if (!s.isEmpty() && !temporaryList.contains(s)) if (!s.isEmpty() && !temporaryList.contains(s))
temporaryList.add(s); temporaryList.add(s);
@ -265,6 +282,7 @@ public class MiscUtils
{ {
double ascii = 0; double ascii = 0;
double other = 0; double other = 0;
for (byte b : data) for (byte b : data)
{ {
if (b == 0x09 || b == 0x0A || b == 0x0C || b == 0x0D || (b >= 0x20 && b <= 0x7E)) if (b == 0x09 || b == 0x0A || b == 0x0C || b == 0x0D || (b >= 0x20 && b <= 0x7E))
@ -272,6 +290,7 @@ public class MiscUtils
else else
other++; other++;
} }
return other != 0 && other / (ascii + other) > 0.25; return other != 0 && other / (ascii + other) > 0.25;
} }
@ -345,9 +364,9 @@ public class MiscUtils
{ {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) try (ByteArrayOutputStream baos = new ByteArrayOutputStream())
{ {
byte[] buffer = new byte[1024]; byte[] buffer = new byte[1024];
int a; int a;
while ((a = is.read(buffer)) != -1) while ((a = is.read(buffer)) != -1)
baos.write(buffer, 0, a); baos.write(buffer, 0, a);
@ -359,9 +378,11 @@ public class MiscUtils
{ {
if (file == null) if (file == null)
return new File[0]; return new File[0];
File[] list = file.listFiles(); File[] list = file.listFiles();
if (list != null) if (list != null)
return list; return list;
return new File[0]; return new File[0];
} }

View File

@ -41,11 +41,14 @@ public class NewlineOutputStream extends FilterOutputStream
public NewlineOutputStream(OutputStream os) public NewlineOutputStream(OutputStream os)
{ {
super(os); super(os);
if (newline == null) if (newline == null)
{ {
String s = Constants.NL; String s = Constants.NL;
if (s == null || s.length() <= 0) if (s == null || s.length() <= 0)
s = "\n"; s = "\n";
newline = s.getBytes(StandardCharsets.ISO_8859_1); // really us-ascii newline = s.getBytes(StandardCharsets.ISO_8859_1); // really us-ascii
} }
} }
@ -66,6 +69,7 @@ public class NewlineOutputStream extends FilterOutputStream
{ {
out.write(b); out.write(b);
} }
lastByte = b; lastByte = b;
} }

View File

@ -33,7 +33,37 @@ public enum SyntaxLanguage
XML(SyntaxConstants.SYNTAX_STYLE_XML, (n, c) -> n.endsWith(".xml") || c.startsWith("<?xml") || c.startsWith("<xml")), XML(SyntaxConstants.SYNTAX_STYLE_XML, (n, c) -> n.endsWith(".xml") || c.startsWith("<?xml") || c.startsWith("<xml")),
PYTHON(SyntaxConstants.SYNTAX_STYLE_PYTHON, (n, c) -> n.endsWith(".py") || n.endsWith(".python")), PYTHON(SyntaxConstants.SYNTAX_STYLE_PYTHON, (n, c) -> n.endsWith(".py") || n.endsWith(".python")),
RUBY(SyntaxConstants.SYNTAX_STYLE_RUBY, (n, c) -> n.endsWith(".rb") || n.endsWith(".ruby")), RUBY(SyntaxConstants.SYNTAX_STYLE_RUBY, (n, c) -> n.endsWith(".rb") || n.endsWith(".ruby")),
JAVA(SyntaxConstants.SYNTAX_STYLE_JAVA, (n, c) -> n.endsWith(".java")), HTML(SyntaxConstants.SYNTAX_STYLE_HTML, (n, c) -> n.endsWith(".html")), CSS(SyntaxConstants.SYNTAX_STYLE_CSS, (n, c) -> n.endsWith(".css")), PROPERTIES(SyntaxConstants.SYNTAX_STYLE_PROPERTIES_FILE, (n, c) -> n.endsWith(".properties") || n.endsWith(".mf") || n.endsWith(".sf") || n.endsWith(".plugin") || n.endsWith(".attachprovider") || n.endsWith(".transportservice") || n.endsWith(".connector")), PHP(SyntaxConstants.SYNTAX_STYLE_PHP, (n, c) -> n.endsWith(".php") || c.startsWith("<?php")), JS(SyntaxConstants.SYNTAX_STYLE_JAVASCRIPT, (n, c) -> n.endsWith(".js")), BATCH(SyntaxConstants.SYNTAX_STYLE_WINDOWS_BATCH, (n, c) -> n.endsWith(".bat")), SHELL(SyntaxConstants.SYNTAX_STYLE_UNIX_SHELL, (n, c) -> n.endsWith(".sh")), C(SyntaxConstants.SYNTAX_STYLE_C, (n, c) -> n.endsWith(".c") || n.endsWith(".h")), CPP(SyntaxConstants.SYNTAX_STYLE_CPLUSPLUS, (n, c) -> n.endsWith(".cpp") || n.endsWith(".hpp")), SCALA(SyntaxConstants.SYNTAX_STYLE_SCALA, (n, c) -> n.endsWith(".scala")), CLOJURE(SyntaxConstants.SYNTAX_STYLE_CLOJURE, (n, c) -> n.endsWith(".clojure")), GROOVY(SyntaxConstants.SYNTAX_STYLE_GROOVY, (n, c) -> n.endsWith(".groovy") || n.endsWith(".gradle")), LUA(SyntaxConstants.SYNTAX_STYLE_LUA, (n, c) -> n.endsWith(".lua")), SQL(SyntaxConstants.SYNTAX_STYLE_SQL, (n, c) -> n.endsWith(".sql")), JSON(SyntaxConstants.SYNTAX_STYLE_JSON, (n, c) -> n.endsWith(".json")), JSP(SyntaxConstants.SYNTAX_STYLE_JSP, (n, c) -> n.endsWith(".jsp")), YAML(SyntaxConstants.SYNTAX_STYLE_YAML, (n, c) -> n.endsWith(".yml") || n.endsWith(".yaml")), CS(SyntaxConstants.SYNTAX_STYLE_CSHARP, (n, c) -> n.endsWith(".cs")), CSV(SyntaxConstants.SYNTAX_STYLE_CSV, (n, c) -> n.endsWith(".csv")), DOCKER(SyntaxConstants.SYNTAX_STYLE_DOCKERFILE, (n, c) -> n.endsWith(".dockerfile")), DART(SyntaxConstants.SYNTAX_STYLE_DART, (n, c) -> n.endsWith(".dart")), GO(SyntaxConstants.SYNTAX_STYLE_GO, (n, c) -> n.endsWith(".go")), HTACCESS(SyntaxConstants.SYNTAX_STYLE_HTACCESS, (n, c) -> n.endsWith(".htaccess")), INI(SyntaxConstants.SYNTAX_STYLE_INI, (n, c) -> n.endsWith(".ini")), KOTLIN(SyntaxConstants.SYNTAX_STYLE_KOTLIN, (n, c) -> n.endsWith(".kt") || n.endsWith(".kts")), LATEX(SyntaxConstants.SYNTAX_STYLE_LATEX, (n, c) -> n.endsWith(".tex")), MARKDOWN(SyntaxConstants.SYNTAX_STYLE_MARKDOWN, (n, c) -> n.endsWith(".md")), PERL(SyntaxConstants.SYNTAX_STYLE_PERL, (n, c) -> n.endsWith(".pl")), TYPESCRIPT(SyntaxConstants.SYNTAX_STYLE_TYPESCRIPT, (n, c) -> n.endsWith(".ts")), NONE(SyntaxConstants.SYNTAX_STYLE_NONE, (n, c) -> false); JAVA(SyntaxConstants.SYNTAX_STYLE_JAVA, (n, c) -> n.endsWith(".java")),
HTML(SyntaxConstants.SYNTAX_STYLE_HTML, (n, c) -> n.endsWith(".html")),
CSS(SyntaxConstants.SYNTAX_STYLE_CSS, (n, c) -> n.endsWith(".css")),
PROPERTIES(SyntaxConstants.SYNTAX_STYLE_PROPERTIES_FILE, (n, c) -> n.endsWith(".properties") || n.endsWith(".mf") || n.endsWith(".sf") || n.endsWith(".plugin") || n.endsWith(".attachprovider") || n.endsWith(".transportservice") || n.endsWith(".connector")),
PHP(SyntaxConstants.SYNTAX_STYLE_PHP, (n, c) -> n.endsWith(".php") || c.startsWith("<?php")),
JS(SyntaxConstants.SYNTAX_STYLE_JAVASCRIPT, (n, c) -> n.endsWith(".js")),
BATCH(SyntaxConstants.SYNTAX_STYLE_WINDOWS_BATCH, (n, c) -> n.endsWith(".bat")),
SHELL(SyntaxConstants.SYNTAX_STYLE_UNIX_SHELL, (n, c) -> n.endsWith(".sh")),
C(SyntaxConstants.SYNTAX_STYLE_C, (n, c) -> n.endsWith(".c") || n.endsWith(".h")),
CPP(SyntaxConstants.SYNTAX_STYLE_CPLUSPLUS, (n, c) -> n.endsWith(".cpp") || n.endsWith(".hpp")),
SCALA(SyntaxConstants.SYNTAX_STYLE_SCALA, (n, c) -> n.endsWith(".scala")),
CLOJURE(SyntaxConstants.SYNTAX_STYLE_CLOJURE, (n, c) -> n.endsWith(".clojure")),
GROOVY(SyntaxConstants.SYNTAX_STYLE_GROOVY, (n, c) -> n.endsWith(".groovy") || n.endsWith(".gradle")),
LUA(SyntaxConstants.SYNTAX_STYLE_LUA, (n, c) -> n.endsWith(".lua")),
SQL(SyntaxConstants.SYNTAX_STYLE_SQL, (n, c) -> n.endsWith(".sql")),
JSON(SyntaxConstants.SYNTAX_STYLE_JSON, (n, c) -> n.endsWith(".json")),
JSP(SyntaxConstants.SYNTAX_STYLE_JSP, (n, c) -> n.endsWith(".jsp")),
YAML(SyntaxConstants.SYNTAX_STYLE_YAML, (n, c) -> n.endsWith(".yml") || n.endsWith(".yaml")),
CS(SyntaxConstants.SYNTAX_STYLE_CSHARP, (n, c) -> n.endsWith(".cs")),
CSV(SyntaxConstants.SYNTAX_STYLE_CSV, (n, c) -> n.endsWith(".csv")),
DOCKER(SyntaxConstants.SYNTAX_STYLE_DOCKERFILE, (n, c) -> n.endsWith(".dockerfile")),
DART(SyntaxConstants.SYNTAX_STYLE_DART, (n, c) -> n.endsWith(".dart")),
GO(SyntaxConstants.SYNTAX_STYLE_GO, (n, c) -> n.endsWith(".go")),
HTACCESS(SyntaxConstants.SYNTAX_STYLE_HTACCESS, (n, c) -> n.endsWith(".htaccess")),
INI(SyntaxConstants.SYNTAX_STYLE_INI, (n, c) -> n.endsWith(".ini")),
KOTLIN(SyntaxConstants.SYNTAX_STYLE_KOTLIN, (n, c) -> n.endsWith(".kt") || n.endsWith(".kts")),
LATEX(SyntaxConstants.SYNTAX_STYLE_LATEX, (n, c) -> n.endsWith(".tex")),
MARKDOWN(SyntaxConstants.SYNTAX_STYLE_MARKDOWN, (n, c) -> n.endsWith(".md")),
PERL(SyntaxConstants.SYNTAX_STYLE_PERL, (n, c) -> n.endsWith(".pl")),
TYPESCRIPT(SyntaxConstants.SYNTAX_STYLE_TYPESCRIPT, (n, c) -> n.endsWith(".ts")),
NONE(SyntaxConstants.SYNTAX_STYLE_NONE, (n, c) -> false);
public static final SyntaxLanguage[] VALUES = values(); public static final SyntaxLanguage[] VALUES = values();
@ -68,20 +98,19 @@ public enum SyntaxLanguage
for (SyntaxLanguage lang : VALUES) for (SyntaxLanguage lang : VALUES)
{ {
if (lang.isLanguage(fileName, content)) if (lang.isLanguage(fileName, content))
{
return lang; return lang;
} }
}
return NONE; return NONE;
} }
public static void setLanguage(RSyntaxTextArea area, String fileName) public static void setLanguage(RSyntaxTextArea area, String fileName)
{ {
String type = FILE_TYPE_UTIL.guessContentType(new File(fileName)); String type = FILE_TYPE_UTIL.guessContentType(new File(fileName));
if (type == null || type.equals(SyntaxConstants.SYNTAX_STYLE_NONE)) if (type == null || type.equals(SyntaxConstants.SYNTAX_STYLE_NONE))
{
type = FILE_TYPE_UTIL.guessContentType(area); type = FILE_TYPE_UTIL.guessContentType(area);
}
area.setSyntaxEditingStyle(type); area.setSyntaxEditingStyle(type);
} }
} }

View File

@ -50,12 +50,8 @@ public class WindowStateChangeAdapter extends WindowAdapter
}*/ }*/
if ((oldState & Frame.MAXIMIZED_BOTH) == 0 && (newState & Frame.MAXIMIZED_BOTH) != 0) if ((oldState & Frame.MAXIMIZED_BOTH) == 0 && (newState & Frame.MAXIMIZED_BOTH) != 0)
{
mainViewerGUI.isMaximized = true; mainViewerGUI.isMaximized = true;
}
else if ((oldState & Frame.MAXIMIZED_BOTH) != 0 && (newState & Frame.MAXIMIZED_BOTH) == 0) else if ((oldState & Frame.MAXIMIZED_BOTH) != 0 && (newState & Frame.MAXIMIZED_BOTH) == 0)
{
mainViewerGUI.isMaximized = false; mainViewerGUI.isMaximized = false;
} }
}
} }

View File

@ -44,12 +44,14 @@ public final class ZipUtils
public static void unzipFilesToPath(String jarPath, String destinationDir) throws IOException public static void unzipFilesToPath(String jarPath, String destinationDir) throws IOException
{ {
String canonicalDestDir = new File(destinationDir).getCanonicalPath(); String canonicalDestDir = new File(destinationDir).getCanonicalPath();
if (!canonicalDestDir.endsWith(File.separator)) if (!canonicalDestDir.endsWith(File.separator))
{ {
canonicalDestDir += File.separator; canonicalDestDir += File.separator;
} }
File file = new File(jarPath); File file = new File(jarPath);
try (JarFile jar = new JarFile(file)) try (JarFile jar = new JarFile(file))
{ {
@ -82,6 +84,7 @@ public final class ZipUtils
} }
File parent = f.getParentFile(); File parent = f.getParentFile();
if (!parent.exists()) if (!parent.exists())
{ {
parent.mkdirs(); parent.mkdirs();
@ -110,6 +113,7 @@ public final class ZipUtils
{ {
ZipEntry ze = new ZipEntry(inputFile.getName()); ZipEntry ze = new ZipEntry(inputFile.getName());
zos.putNextEntry(ze); zos.putNextEntry(ze);
try (FileInputStream in = new FileInputStream(inputFile)) try (FileInputStream in = new FileInputStream(inputFile))
{ {
int len; int len;
@ -156,14 +160,18 @@ public final class ZipUtils
{ {
byte[] buf = new byte[1024]; byte[] buf = new byte[1024];
int len; int len;
try (FileInputStream in = new FileInputStream(srcFile)) try (FileInputStream in = new FileInputStream(srcFile))
{ {
ZipEntry entry; ZipEntry entry;
if (ignore == null) if (ignore == null)
entry = new ZipEntry(path + "/" + folder.getName()); entry = new ZipEntry(path + "/" + folder.getName());
else else
entry = new ZipEntry(path.replace(ignore, "BCV_Krakatau") + "/" + folder.getName()); entry = new ZipEntry(path.replace(ignore, "BCV_Krakatau") + "/" + folder.getName());
zip.putNextEntry(entry); zip.putNextEntry(entry);
while ((len = in.read(buf)) > 0) while ((len = in.read(buf)) > 0)
{ {
zip.write(buf, 0, len); zip.write(buf, 0, len);
@ -194,6 +202,7 @@ public final class ZipUtils
{ {
byte[] buf = new byte[1024]; byte[] buf = new byte[1024];
int len; int len;
try (FileInputStream in = new FileInputStream(srcFile)) try (FileInputStream in = new FileInputStream(srcFile))
{ {
ZipEntry entry; ZipEntry entry;
@ -216,15 +225,11 @@ public final class ZipUtils
for (String fileName : Objects.requireNonNull(folder.list())) for (String fileName : Objects.requireNonNull(folder.list()))
{ {
if (path.isEmpty()) if (path.isEmpty())
{
addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip, ignore); addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip, ignore);
}
else else
{
addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip, ignore); addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip, ignore);
} }
} }
}
public static void addFolderToZipAPKTool(String path, String srcFolder, ZipOutputStream zip) throws Exception public static void addFolderToZipAPKTool(String path, String srcFolder, ZipOutputStream zip) throws Exception
{ {
@ -233,13 +238,9 @@ public final class ZipUtils
for (String fileName : Objects.requireNonNull(folder.list())) for (String fileName : Objects.requireNonNull(folder.list()))
{ {
if (path.isEmpty()) if (path.isEmpty())
{
addFileToZipAPKTool(folder.getName(), srcFolder + "/" + fileName, zip); addFileToZipAPKTool(folder.getName(), srcFolder + "/" + fileName, zip);
}
else else
{
addFileToZipAPKTool(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip); addFileToZipAPKTool(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip);
} }
} }
}
} }