bcv-vf/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/KrakatauDecompiler.java

293 lines
12 KiB
Java
Raw Normal View History

2021-07-04 06:18:06 +00:00
package the.bytecode.club.bytecodeviewer.decompilers.impl;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.stream.Collectors;
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;
import the.bytecode.club.bytecodeviewer.Configuration;
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;
import static the.bytecode.club.bytecodeviewer.Constants.fs;
import static the.bytecode.club.bytecodeviewer.Constants.krakatauWorkingDirectory;
import static the.bytecode.club.bytecodeviewer.Constants.nl;
/***************************************************************************
* 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/>. *
***************************************************************************/
/**
* Krakatau Java Decompiler Wrapper, requires Python 2.7
*
2018-01-31 15:41:24 +00:00
* @author Konloch
*/
public class KrakatauDecompiler extends InternalDecompiler
{
2021-07-18 19:11:34 +00:00
public String buildCLIArguments()
{
if (Configuration.library.isEmpty())
2018-01-31 15:41:24 +00:00
return "";
File dir = new File(Configuration.library);
if (!dir.exists())
return "";
if (!dir.isDirectory())
return ";" + Configuration.library;
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();
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
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.
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
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
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
}
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
final File tempDirectory = new File(Constants.tempDirectory + fs + MiscUtils.randomString(32) + fs);
2019-04-17 06:45:15 +00:00
tempDirectory.mkdir();
final File tempJar = new File(Constants.tempDirectory + fs + "temp" + MiscUtils.randomString(32) + ".jar");
2019-04-17 06:45:15 +00:00
JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
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
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.
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();
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);
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
krakatauWorkingDirectory + fs + "decompile.py",
2018-01-31 15:41:24 +00:00
"-skip", //love you storyyeller <3
"-nauto",
"-path",
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
}
}
}