2021-07-04 06:18:06 +00:00
|
|
|
package the.bytecode.club.bytecodeviewer.decompilers.impl;
|
2015-11-11 04:16:45 +00:00
|
|
|
|
2018-01-31 15:03:53 +00:00
|
|
|
import java.io.BufferedReader;
|
|
|
|
import java.io.File;
|
|
|
|
import java.io.InputStream;
|
|
|
|
import java.io.InputStreamReader;
|
|
|
|
import java.io.PrintWriter;
|
|
|
|
import java.io.StringWriter;
|
2021-06-22 13:23:36 +00:00
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.stream.Collectors;
|
2018-01-31 15:03:53 +00:00
|
|
|
import me.konloch.kontainer.io.DiskReader;
|
2021-07-12 13:59:26 +00:00
|
|
|
import org.apache.commons.lang3.ArrayUtils;
|
2015-11-19 03:30:59 +00:00
|
|
|
import org.objectweb.asm.tree.ClassNode;
|
|
|
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
2021-06-21 11:13:11 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.Configuration;
|
2021-06-21 09:45:31 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.Constants;
|
2021-07-11 16:52:07 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
|
2021-07-04 06:18:06 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.decompilers.InternalDecompiler;
|
2021-07-11 12:33:18 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.resources.ExternalResources;
|
2021-07-17 20:51:00 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
2019-04-17 06:45:15 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.util.JarUtils;
|
|
|
|
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
|
|
|
|
import the.bytecode.club.bytecodeviewer.util.ZipUtils;
|
2021-08-26 21:59:07 +00:00
|
|
|
|
|
|
|
import static the.bytecode.club.bytecodeviewer.Constants.fs;
|
|
|
|
import static the.bytecode.club.bytecodeviewer.Constants.krakatauWorkingDirectory;
|
|
|
|
import static the.bytecode.club.bytecodeviewer.Constants.nl;
|
2015-11-11 04:16:45 +00:00
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
|
|
|
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
|
|
|
|
* *
|
|
|
|
* This program is free software: you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
* This program is distributed in the hope that it will be useful, *
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
|
|
* GNU General Public License for more details. *
|
|
|
|
* *
|
|
|
|
* You should have received a copy of the GNU General Public License *
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
/**
|
2018-01-31 15:03:53 +00:00
|
|
|
* Krakatau Java Decompiler Wrapper, requires Python 2.7
|
2015-11-11 04:16:45 +00:00
|
|
|
*
|
2018-01-31 15:41:24 +00:00
|
|
|
* @author Konloch
|
2015-11-11 04:16:45 +00:00
|
|
|
*/
|
|
|
|
|
2021-06-26 01:13:46 +00:00
|
|
|
public class KrakatauDecompiler extends InternalDecompiler
|
|
|
|
{
|
2021-07-18 19:11:34 +00:00
|
|
|
public String buildCLIArguments()
|
|
|
|
{
|
2021-06-21 11:13:11 +00:00
|
|
|
if (Configuration.library.isEmpty())
|
2018-01-31 15:41:24 +00:00
|
|
|
return "";
|
2021-06-22 13:23:36 +00:00
|
|
|
|
|
|
|
File dir = new File(Configuration.library);
|
|
|
|
if (!dir.exists())
|
|
|
|
return "";
|
|
|
|
if (!dir.isDirectory())
|
2021-06-21 11:13:11 +00:00
|
|
|
return ";" + Configuration.library;
|
2021-06-22 13:23:36 +00:00
|
|
|
|
|
|
|
File[] files = dir.listFiles();
|
|
|
|
if (files == null || files.length == 0)
|
|
|
|
return "";
|
|
|
|
|
|
|
|
return ";" + Arrays.stream(files).filter(File::isFile)
|
|
|
|
.map(File::getAbsolutePath).collect(Collectors.joining(";"));
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
|
|
|
|
2021-07-11 12:33:18 +00:00
|
|
|
public String decompileClassNode(File krakatauTempJar, File krakatauTempDir, ClassNode cn)
|
|
|
|
{
|
2021-07-12 13:59:26 +00:00
|
|
|
if(!ExternalResources.getSingleton().hasSetPython2Command())
|
2021-07-17 20:51:00 +00:00
|
|
|
return TranslatedStrings.YOU_NEED_TO_SET_YOUR_PYTHON_2_PATH.toString();
|
2019-04-13 03:42:04 +00:00
|
|
|
|
2021-07-11 12:33:18 +00:00
|
|
|
ExternalResources.getSingleton().rtCheck();
|
2021-07-18 19:11:34 +00:00
|
|
|
if (Configuration.rt.isEmpty())
|
|
|
|
{
|
2021-07-18 09:11:45 +00:00
|
|
|
BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A
|
|
|
|
+ "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B);
|
2021-07-11 12:33:18 +00:00
|
|
|
ExternalResources.getSingleton().selectJRERTLibrary();
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
|
|
|
|
2021-07-18 19:11:34 +00:00
|
|
|
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);
|
|
|
|
return TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A
|
|
|
|
+ " " + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B;
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
|
|
|
|
2021-07-11 16:52:07 +00:00
|
|
|
String s = ExceptionUI.SEND_STACKTRACE_TO_NL;
|
2019-04-17 06:45:15 +00:00
|
|
|
|
|
|
|
try {
|
2021-07-12 13:59:26 +00:00
|
|
|
String[] pythonCommands = new String[]{Configuration.python2};
|
2021-07-19 18:28:47 +00:00
|
|
|
if(Configuration.python2Extra)
|
|
|
|
pythonCommands = ArrayUtils.addAll(pythonCommands, "-2");
|
2021-07-12 13:59:26 +00:00
|
|
|
|
|
|
|
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(
|
|
|
|
pythonCommands,
|
2019-04-17 06:45:15 +00:00
|
|
|
"-O", //love you storyyeller <3
|
2021-06-21 09:45:31 +00:00
|
|
|
krakatauWorkingDirectory + fs + "decompile.py",
|
2019-04-17 06:45:15 +00:00
|
|
|
"-skip", //love you storyyeller <3
|
|
|
|
"-nauto",
|
|
|
|
"-path",
|
2021-07-18 19:11:34 +00:00
|
|
|
Configuration.rt + ";" + krakatauTempJar.getAbsolutePath() + buildCLIArguments(),
|
2019-04-17 06:45:15 +00:00
|
|
|
"-out",
|
|
|
|
krakatauTempDir.getAbsolutePath(),
|
|
|
|
cn.name + ".class"
|
2021-07-12 13:59:26 +00:00
|
|
|
));
|
2019-04-17 06:45:15 +00:00
|
|
|
|
|
|
|
Process process = pb.start();
|
|
|
|
BytecodeViewer.createdProcesses.add(process);
|
|
|
|
|
2021-07-17 20:51:00 +00:00
|
|
|
StringBuilder log = new StringBuilder(TranslatedStrings.PROCESS2 + nl + nl);
|
2021-07-25 16:54:08 +00:00
|
|
|
|
|
|
|
//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);
|
|
|
|
}
|
2019-04-17 06:45:15 +00:00
|
|
|
}
|
|
|
|
|
2021-07-17 20:51:00 +00:00
|
|
|
log.append(nl).append(nl).append(TranslatedStrings.ERROR2).append(nl).append(nl);
|
2021-07-25 16:54:08 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2019-04-17 06:45:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int exitValue = process.waitFor();
|
2021-07-25 16:54:08 +00:00
|
|
|
log.append(nl).append(nl).append(TranslatedStrings.EXIT_VALUE_IS).append(" ").append(exitValue);
|
2021-04-12 22:31:22 +00:00
|
|
|
s = log.toString();
|
2019-04-17 06:45:15 +00:00
|
|
|
|
|
|
|
//if the motherfucker failed this'll fail, aka wont set.
|
2021-06-21 09:45:31 +00:00
|
|
|
s = DiskReader.loadAsString(krakatauTempDir.getAbsolutePath() + fs + cn.name + ".java");
|
2019-04-17 06:45:15 +00:00
|
|
|
} catch (Exception e) {
|
|
|
|
StringWriter sw = new StringWriter();
|
|
|
|
e.printStackTrace(new PrintWriter(sw));
|
|
|
|
e.printStackTrace();
|
2021-07-11 16:52:07 +00:00
|
|
|
s += nl + ExceptionUI.SEND_STACKTRACE_TO_NL + sw;
|
2019-04-17 06:45:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2021-07-16 20:55:03 +00:00
|
|
|
public String decompileClassNode(ClassNode cn, byte[] b)
|
|
|
|
{
|
|
|
|
//TODO look into transforming through krakatau as a zip rather than direct classfile
|
|
|
|
|
2021-07-12 13:59:26 +00:00
|
|
|
if(!ExternalResources.getSingleton().hasSetPython2Command())
|
2021-07-17 20:51:00 +00:00
|
|
|
return TranslatedStrings.YOU_NEED_TO_SET_YOUR_PYTHON_2_PATH.toString();
|
2021-07-11 16:41:33 +00:00
|
|
|
|
2021-06-21 11:13:11 +00:00
|
|
|
if (Configuration.rt.isEmpty()) {
|
2021-07-18 09:11:45 +00:00
|
|
|
BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A
|
|
|
|
+ "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B);
|
2021-07-11 12:33:18 +00:00
|
|
|
ExternalResources.getSingleton().selectJRERTLibrary();
|
2019-04-17 06:45:15 +00:00
|
|
|
}
|
|
|
|
|
2021-06-21 11:13:11 +00:00
|
|
|
if (Configuration.rt.isEmpty()) {
|
2019-04-17 06:45:15 +00:00
|
|
|
BytecodeViewer.showMessage("You need to set RT.jar!");
|
|
|
|
return "Set your paths";
|
|
|
|
}
|
|
|
|
|
2021-07-11 16:52:07 +00:00
|
|
|
String s = ExceptionUI.SEND_STACKTRACE_TO_NL;
|
2019-04-17 06:45:15 +00:00
|
|
|
|
2021-06-21 09:45:31 +00:00
|
|
|
final File tempDirectory = new File(Constants.tempDirectory + fs + MiscUtils.randomString(32) + fs);
|
2019-04-17 06:45:15 +00:00
|
|
|
tempDirectory.mkdir();
|
2021-06-21 09:45:31 +00:00
|
|
|
final File tempJar = new File(Constants.tempDirectory + fs + "temp" + MiscUtils.randomString(32) + ".jar");
|
2021-06-22 13:23:36 +00:00
|
|
|
|
2019-04-17 06:45:15 +00:00
|
|
|
JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
|
2021-06-22 13:23:36 +00:00
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
try {
|
2021-07-12 13:59:26 +00:00
|
|
|
String[] pythonCommands = new String[]{Configuration.python2};
|
2021-07-19 18:28:47 +00:00
|
|
|
if(Configuration.python2Extra)
|
|
|
|
pythonCommands = ArrayUtils.addAll(pythonCommands, "-2");
|
2021-07-12 13:59:26 +00:00
|
|
|
|
|
|
|
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(
|
|
|
|
pythonCommands,
|
2018-01-31 15:41:24 +00:00
|
|
|
"-O", //love you storyyeller <3
|
2021-06-21 09:45:31 +00:00
|
|
|
krakatauWorkingDirectory + fs + "decompile.py",
|
2018-01-31 15:41:24 +00:00
|
|
|
"-skip", //love you storyyeller <3
|
|
|
|
"-nauto",
|
|
|
|
"-path",
|
2021-07-18 19:11:34 +00:00
|
|
|
Configuration.rt + ";" + tempJar.getAbsolutePath() + buildCLIArguments(),
|
2018-01-31 15:41:24 +00:00
|
|
|
"-out",
|
2019-04-17 06:45:15 +00:00
|
|
|
tempDirectory.getAbsolutePath(),
|
2018-01-31 15:41:24 +00:00
|
|
|
cn.name + ".class"
|
2021-07-12 13:59:26 +00:00
|
|
|
));
|
2018-01-31 15:41:24 +00:00
|
|
|
|
|
|
|
Process process = pb.start();
|
|
|
|
BytecodeViewer.createdProcesses.add(process);
|
|
|
|
|
2021-07-17 20:51:00 +00:00
|
|
|
StringBuilder log = new StringBuilder(TranslatedStrings.PROCESS2 + nl + nl);
|
2021-07-25 16:54:08 +00:00
|
|
|
|
|
|
|
//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);
|
|
|
|
}
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
2021-07-25 16:54:08 +00:00
|
|
|
|
|
|
|
log.append(nl).append(nl).append(TranslatedStrings.ERROR2).append(nl).append(nl);
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int exitValue = process.waitFor();
|
2021-12-19 23:24:17 +00:00
|
|
|
log.append(nl).append(nl).append(TranslatedStrings.EXIT_VALUE_IS).append(" ").append(exitValue);
|
2021-04-12 22:31:22 +00:00
|
|
|
s = log.toString();
|
2018-01-31 15:41:24 +00:00
|
|
|
|
|
|
|
//if the motherfucker failed this'll fail, aka wont set.
|
2021-06-21 09:45:31 +00:00
|
|
|
s = DiskReader.loadAsString(tempDirectory.getAbsolutePath() + fs + cn.name + ".java");
|
2019-04-17 06:45:15 +00:00
|
|
|
tempDirectory.delete();
|
|
|
|
tempJar.delete();
|
2018-01-31 15:41:24 +00:00
|
|
|
} catch (Exception e) {
|
|
|
|
StringWriter sw = new StringWriter();
|
|
|
|
e.printStackTrace(new PrintWriter(sw));
|
|
|
|
e.printStackTrace();
|
2021-07-11 16:52:07 +00:00
|
|
|
s += nl + ExceptionUI.SEND_STACKTRACE_TO_NL + sw;
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2021-04-12 22:31:22 +00:00
|
|
|
@Override
|
2019-04-14 03:45:40 +00:00
|
|
|
public void decompileToZip(String sourceJar, String zipName) {
|
2021-07-12 13:59:26 +00:00
|
|
|
if(!ExternalResources.getSingleton().hasSetPython2Command())
|
2021-07-11 16:41:33 +00:00
|
|
|
return;
|
2021-07-11 12:33:18 +00:00
|
|
|
|
|
|
|
ExternalResources.getSingleton().rtCheck();
|
2021-06-21 11:13:11 +00:00
|
|
|
if (Configuration.rt.isEmpty()) {
|
2021-07-18 09:11:45 +00:00
|
|
|
BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A
|
|
|
|
+ "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B);
|
2021-07-11 12:33:18 +00:00
|
|
|
ExternalResources.getSingleton().selectJRERTLibrary();
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
String ran = MiscUtils.randomString(32);
|
2021-06-21 09:45:31 +00:00
|
|
|
final File tempDirectory = new File(Constants.tempDirectory + fs + ran + fs);
|
2018-01-31 15:41:24 +00:00
|
|
|
tempDirectory.mkdir();
|
2019-04-14 03:45:40 +00:00
|
|
|
|
|
|
|
final File tempJar = new File(sourceJar);
|
2021-07-12 12:13:35 +00:00
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
try {
|
2021-07-12 13:59:26 +00:00
|
|
|
String[] pythonCommands = new String[]{Configuration.python2};
|
2021-07-19 18:28:47 +00:00
|
|
|
if(Configuration.python2Extra)
|
|
|
|
pythonCommands = ArrayUtils.addAll(pythonCommands, "-2");
|
2021-07-12 13:59:26 +00:00
|
|
|
|
|
|
|
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(
|
|
|
|
pythonCommands,
|
2018-01-31 15:41:24 +00:00
|
|
|
"-O", //love you storyyeller <3
|
2021-06-21 09:45:31 +00:00
|
|
|
krakatauWorkingDirectory + fs + "decompile.py",
|
2018-01-31 15:41:24 +00:00
|
|
|
"-skip", //love you storyyeller <3
|
|
|
|
"-nauto",
|
|
|
|
"-path",
|
2021-06-21 11:13:11 +00:00
|
|
|
Configuration.rt + ";" + tempJar.getAbsolutePath(),
|
2018-01-31 15:41:24 +00:00
|
|
|
"-out",
|
|
|
|
tempDirectory.getAbsolutePath(),
|
|
|
|
tempJar.getAbsolutePath()
|
2021-07-12 13:59:26 +00:00
|
|
|
));
|
2018-01-31 15:41:24 +00:00
|
|
|
|
|
|
|
Process process = pb.start();
|
|
|
|
BytecodeViewer.createdProcesses.add(process);
|
|
|
|
process.waitFor();
|
|
|
|
MiscUtils.printProcess(process);
|
|
|
|
|
|
|
|
ZipUtils.zipFolder(tempDirectory.getAbsolutePath(), zipName, ran);
|
|
|
|
} catch (Exception e) {
|
2021-07-07 02:51:10 +00:00
|
|
|
BytecodeViewer.handleException(e);
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-11 04:16:45 +00:00
|
|
|
}
|