Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

# Ignore Gradle build output directory
build
.gui/gradle/wrapper/

# Ignore logs
*.log
Expand Down
24 changes: 12 additions & 12 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ allprojects {

plugins.withType<JavaPlugin> {
configure<JavaPluginExtension> {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.toVersion(19)
targetCompatibility = JavaVersion.toVersion(19)
}

if (!skipAutostyle) {
Expand All @@ -88,7 +88,7 @@ allprojects {
include("**/*.properties")
filteringCharset = "UTF-8"
// apply native2ascii conversion since Java 8 expects properties to have ascii symbols only
filter(org.apache.tools.ant.filters.EscapeUnicode::class)
// filter(org.apache.tools.ant.filters.EscapeUnicode::class)
}
}

Expand All @@ -103,13 +103,13 @@ allprojects {
windowTitle = "Threadtear ${project.name} API"
header = "<b>Threadtear</b>"
addBooleanOption("Xdoclint:none", true)
addStringOption("source", "8")
if (JavaVersion.current().isJava9Compatible) {
addBooleanOption("html5", true)
links("https://docs.oracle.com/javase/9/docs/api/")
} else {
links("https://docs.oracle.com/javase/8/docs/api/")
}
addStringOption("source", "22")
// if (JavaVersion.current().isJava9Compatible) {
// addBooleanOption("html5", true)
// links("https://docs.oracle.com/javase/9/docs/api/")
// } else {
// links("https://docs.oracle.com/javase/8/docs/api/")
// }
}
}

Expand All @@ -132,10 +132,10 @@ allprojects {
// This includes either project-specific license or a default one
if (file("$projectDir/LICENSE").exists()) {
textFrom("$projectDir/LICENSE")
rename { s -> "${project.name.toUpperCase()}_LICENSE" }
rename { "${project.name.toUpperCase()}_LICENSE" }
} else {
textFrom("$rootDir/LICENSE")
rename { s -> "${rootProject.name.toUpperCase()}_LICENSE" }
rename { "${rootProject.name.toUpperCase()}_LICENSE" }
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ dependencies {
implementation("org.ow2.asm:asm-commons")

implementation("com.github.leibnitz27:cfr") { isChanging = true }
implementation("org.vineflower:vineflower:1.10.1")
implementation("ch.qos.logback:logback-classic")
implementation("software.coley:cafedude-core:2.1.1")

externalLib("fernflower-15-05-20")
// externalLib("fernflower-15-05-20")
}
17 changes: 9 additions & 8 deletions core/src/main/java/me/nov/threadtear/ThreadtearCore.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@
import me.nov.threadtear.execution.Execution;
import me.nov.threadtear.logging.LogWrapper;
import me.nov.threadtear.security.VMSecurityManager;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;
import org.slf4j.LoggerFactory;
import software.coley.cafedude.InvalidClassException;
import software.coley.cafedude.classfile.ClassFile;
import software.coley.cafedude.io.ClassFileReader;
import software.coley.cafedude.io.ClassFileWriter;

import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.lang.reflect.Field;
Expand All @@ -15,12 +22,6 @@
import java.util.stream.Collectors;

public class ThreadtearCore {
public static void configureEnvironment() throws Exception {
System.setProperty("file.encoding", "UTF-8");
Field charset = Charset.class.getDeclaredField("defaultCharset");
charset.setAccessible(true);
charset.set(null, null);
}

public static void configureLoggers() {
LogWrapper.logger.addLogger(LoggerFactory.getLogger("logfile"));
Expand All @@ -32,13 +33,14 @@ public static void run(List<Clazz> classes, List<Execution> executions, boolean
LogWrapper.logger.info("Executing {} tasks on {} classes!", executions.size(), classes.size());
if (!disableSecurity) {
LogWrapper.logger.info("Initializing security manager if something goes horribly wrong");
System.setSecurityManager(new VMSecurityManager());
} else {
LogWrapper.logger.warning("Starting without security manager!");
}
List<Clazz> ignoredClasses = classes.stream().filter(c -> !c.transform).collect(Collectors.toList());
LogWrapper.logger.warning("{} classes will be ignored", ignoredClasses.size());
classes.removeIf(c -> !c.transform);


Map<String, Clazz> map = classes.stream().collect(Collectors.toMap(c -> c.node.name, c -> c, (c1, c2) -> {
LogWrapper.logger.warning("Warning: Duplicate class definition of {}, one class may not get decrypted", c1.node.name);
return c1;
Expand Down Expand Up @@ -70,7 +72,6 @@ public static void run(List<Clazz> classes, List<Execution> executions, boolean
} catch (InterruptedException e1) {
}
LogWrapper.logger.info("Successful completion!");
System.setSecurityManager(null);
}

// TODO: make a CLI
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public String toString() {
public static List<DecompilerInfo<?>> getDecompilerInfos() {
List<DecompilerInfo<?>> list = new ArrayList<>(3);
list.add(new CFRBridge.CFRDecompilerInfo());
list.add(new FernflowerBridge.FernflowerDecompilerInfo());
list.add(new VineFlowerBridge.FernflowerDecompilerInfo());
list.add(new KrakatauBridge.KrakatauDecompilerInfo());
return list;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

import me.nov.threadtear.io.JarIO;

public class FernflowerBridge implements IDecompilerBridge, IBytecodeProvider, IResultSaver {
public class VineFlowerBridge implements IDecompilerBridge, IBytecodeProvider, IResultSaver {

protected static final Map<String, Object> options = new HashMap<>();

Expand Down Expand Up @@ -68,7 +68,7 @@ public String decompile(File archive, String name, byte[] bytez) {
return sw.toString();
}
if (result == null || result.trim().isEmpty()) {
result = "No Fernflower output received\n\nOutput log:\n" + new String(log.toByteArray());
result = "No VineFlower output received\n\nOutput log:\n" + new String(log.toByteArray());
}
return result;
}
Expand Down Expand Up @@ -112,21 +112,21 @@ public void saveClassEntry(String path, String archiveName, String qualifiedName
public void closeArchive(String path, String archiveName) {
}

public static class FernflowerDecompilerInfo extends DecompilerInfo<FernflowerBridge> {
public static class FernflowerDecompilerInfo extends DecompilerInfo<VineFlowerBridge> {

@Override
public String getName() {
return "Fernflower";
return "VineFlower";
}

@Override
public String getVersionInfo() {
return "15-08-20";
return "1.10.1";
}

@Override
public FernflowerBridge createDecompilerBridge() {
return new FernflowerBridge();
public VineFlowerBridge createDecompilerBridge() {
return new VineFlowerBridge();
}
}
}
95 changes: 26 additions & 69 deletions core/src/main/java/me/nov/threadtear/execution/ExecutionLink.java
Original file line number Diff line number Diff line change
@@ -1,77 +1,34 @@
package me.nov.threadtear.execution;

import me.nov.threadtear.execution.allatori.ExpirationDateRemoverAllatori;
import me.nov.threadtear.execution.allatori.JunkRemoverAllatori;
import me.nov.threadtear.execution.allatori.StringObfuscationAllatori;
import me.nov.threadtear.execution.analysis.*;
import me.nov.threadtear.execution.cleanup.InlineMethods;
import me.nov.threadtear.execution.cleanup.InlineUnchangedFields;
import me.nov.threadtear.execution.cleanup.remove.RemoveAttributes;
import me.nov.threadtear.execution.cleanup.remove.RemoveUnnecessary;
import me.nov.threadtear.execution.cleanup.remove.RemoveUnusedVariables;
import me.nov.threadtear.execution.dasho.StringObfuscationDashO;
import me.nov.threadtear.execution.generic.ConvertCompareInstructions;
import me.nov.threadtear.execution.generic.KnownConditionalJumps;
import me.nov.threadtear.execution.generic.ObfuscatedAccess;
import me.nov.threadtear.execution.generic.TryCatchObfuscationRemover;
import me.nov.threadtear.execution.generic.inliner.ArgumentInliner;
import me.nov.threadtear.execution.generic.inliner.JSRInliner;
import me.nov.threadtear.execution.paramorphism.AccessObfuscationParamorphism;
import me.nov.threadtear.execution.paramorphism.BadAttributeRemover;
import me.nov.threadtear.execution.paramorphism.StringObfuscationParamorphism;
import me.nov.threadtear.execution.stringer.AccessObfuscationStringer;
import me.nov.threadtear.execution.stringer.StringObfuscationStringer;
import me.nov.threadtear.execution.tools.*;
import me.nov.threadtear.execution.zkm.*;

import me.nov.threadtear.logging.LogWrapper;
import me.nov.threadtear.util.reflection.ReflectionUtil;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

public class ExecutionLink {
public static final List<Class<? extends Execution>> executions = new ArrayList<Class<? extends Execution>>() {{
add(InlineMethods.class);
add(InlineUnchangedFields.class);
add(RemoveUnnecessary.class);
add(RemoveUnusedVariables.class);
add(RemoveAttributes.class);

add(ArgumentInliner.class);
add(JSRInliner.class);
add(ObfuscatedAccess.class);
add(KnownConditionalJumps.class);
add(ConvertCompareInstructions.class);

add(RestoreSourceFiles.class);
add(ReobfuscateClassNames.class);
add(ReobfuscateMembers.class);
add(ReobfuscateVariableNames.class);
add(RemoveMonitors.class);
add(RemoveTCBs.class);

add(StringObfuscationStringer.class);
add(AccessObfuscationStringer.class);

add(TryCatchObfuscationRemover.class);
add(StringObfuscationZKM.class);
add(AccessObfuscationZKM.class);
add(FlowObfuscationZKM.class);
add(DESObfuscationZKM.class);

add(StringObfuscationAllatori.class);
add(ExpirationDateRemoverAllatori.class);
add(JunkRemoverAllatori.class);

add(StringObfuscationDashO.class);

add(BadAttributeRemover.class);
add(StringObfuscationParamorphism.class);
add(AccessObfuscationParamorphism.class);

add(Java7Compatibility.class);
add(Java8Compatibility.class);
add(IsolatePossiblyMalicious.class);
add(AddLineNumbers.class);
add(LogAllExceptions.class);
add(RemoveMaxs.class);
}};
public static final List<Class<? extends Execution>> executions = new ArrayList<Class<? extends Execution>>() {};
static {
// Use reflection to get every class in the execution package and add it if it extends Execution
Class<?>[] classes = ReflectionUtil.getClassInPackage("me.nov.threadtear.execution");
LogWrapper.logger.info("Found " + classes.length + " classes in execution package");
for(Class<?> clazz : classes){
// Skip the Execution class itself, abstract classes, and interfaces
if(Execution.class.isAssignableFrom(clazz) && clazz != Execution.class && !Modifier.isAbstract(clazz.getModifiers()) && !clazz.isInterface()){
try {
// Check if the class has a public no-argument constructor
clazz.getConstructor();
// Add the class directly to the list without instantiating
executions.add((Class<? extends Execution>) clazz);
} catch (NoSuchMethodException e) {
// The class doesn't have a public no-argument constructor; skip it
continue;
}
}
}

}
}

This file was deleted.

Loading