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
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@ public enum ObfuscationTransformer {
INNER_CLASS_REMOVER,
NAME_OBFUSCATION,
HIDE_MEMBERS,
INLINING
INLINING,
EXPIREDATE
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,7 @@

package me.superblaubeere27.jobf;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
Expand All @@ -42,28 +34,15 @@

import com.google.common.io.ByteStreams;
import lombok.extern.slf4j.Slf4j;
import me.superblaubeere27.jobf.processors.CrasherTransformer;
import me.superblaubeere27.jobf.processors.HWIDProtection;
import me.superblaubeere27.jobf.processors.HideMembers;
import me.superblaubeere27.jobf.processors.InlineTransformer;
import me.superblaubeere27.jobf.processors.InvokeDynamic;
import me.superblaubeere27.jobf.processors.LineNumberRemover;
import me.superblaubeere27.jobf.processors.NumberObfuscationTransformer;
import me.superblaubeere27.jobf.processors.ReferenceProxy;
import me.superblaubeere27.jobf.processors.ShuffleMembersTransformer;
import me.superblaubeere27.jobf.processors.StaticInitializionTransformer;
import me.superblaubeere27.jobf.processors.StringEncryptionTransformer;
import me.superblaubeere27.jobf.processors.*;
import me.superblaubeere27.jobf.processors.flowObfuscation.FlowObfuscator;
import me.superblaubeere27.jobf.processors.name.ClassWrapper;
import me.superblaubeere27.jobf.processors.name.INameObfuscationProcessor;
import me.superblaubeere27.jobf.processors.name.InnerClassRemover;
import me.superblaubeere27.jobf.processors.name.NameObfuscation;
import me.superblaubeere27.jobf.processors.optimizer.Optimizer;
import me.superblaubeere27.jobf.processors.packager.Packager;
import me.superblaubeere27.jobf.utils.ClassTree;
import me.superblaubeere27.jobf.utils.MissingClassException;
import me.superblaubeere27.jobf.utils.NameUtils;
import me.superblaubeere27.jobf.utils.Utils;
import me.superblaubeere27.jobf.utils.*;
import me.superblaubeere27.jobf.utils.scheduler.ScheduledRunnable;
import me.superblaubeere27.jobf.utils.scheduler.Scheduler;
import me.superblaubeere27.jobf.utils.script.JObfScript;
Expand All @@ -83,9 +62,11 @@ public class JObfImpl {
public static HashMap<String, byte[]> files = new HashMap<>();
private static List<IPreClassTransformer> preProcessors;
public JObfScript script;
private boolean mainClassChanged;
public boolean mainClassChanged;
public boolean agentClassChanged;
private final List<INameObfuscationProcessor> nameObfuscationProcessors = new ArrayList<>();
private String mainClass;
private String agentClass;
private Map<String, ClassWrapper> classPath = new HashMap<>();
private Map<String, ClassTree> hierarchy = new HashMap<>();
private Set<ClassWrapper> libraryClassnodes = new HashSet<>();
Expand All @@ -94,6 +75,7 @@ public class JObfImpl {
private boolean invokeDynamic;
private final JObfSettings settings = new JObfSettings();
private int threadCount = Math.max(1, Runtime.getRuntime().availableProcessors());
private final Map<String, FXMLControllerData> fxmlControllerClasses = new HashMap<>();


public JObfImpl() {
Expand All @@ -108,14 +90,28 @@ public static HashMap<String, ClassNode> getClasses() {
return classes;
}

public FXMLControllerData getFXMLControllerDataByClassName(String className) {
return this.fxmlControllerClasses.values().stream()
.filter(fxmlControllerData -> fxmlControllerData.getOriginalClassName().equals(className))
.findFirst().orElse(null);
}

public String getMainClass() {
return mainClass;
}

private void setMainClass(String mainClass) {
public void setMainClass(String mainClass) {
this.mainClass = mainClass;
}

public String getAgentClass() {
return agentClass;
}

public void setAgentClass(String agentClass) {
this.agentClass = agentClass;
}

public ClassTree getTree(String ref) {
if (!hierarchy.containsKey(ref)) {
ClassWrapper wrapper = classPath.get(ref);
Expand Down Expand Up @@ -295,6 +291,9 @@ public boolean isLoadedCode(ClassNode classNode) {
private void addProcessors() {
processors.add(new StaticInitializionTransformer(this));

processors.add(new ExpireDate(this));


processors.add(new HWIDProtection(this));
processors.add(new Optimizer());
processors.add(new InlineTransformer(this));
Expand All @@ -308,6 +307,7 @@ private void addProcessors() {
processors.add(new ShuffleMembersTransformer(this));



nameObfuscationProcessors.add(new NameObfuscation());
nameObfuscationProcessors.add(new InnerClassRemover());
processors.add(new CrasherTransformer(this));
Expand Down Expand Up @@ -380,6 +380,7 @@ public void processJar(Configuration config) throws IOException {
throw new FileNotFoundException("Could not open output file: " + e.getMessage());
}
setMainClass(null);
setAgentClass(null);

log.info("... Finished after " + Utils.formatTime(System.currentTimeMillis() - startTime));

Expand Down Expand Up @@ -436,6 +437,13 @@ public void processJar(Configuration config) throws IOException {
} else {
if (entryName.equals("META-INF/MANIFEST.MF")) {
setMainClass(Utils.getMainClass(new String(entryData, StandardCharsets.UTF_8)));
setAgentClass(Utils.getAgentClass(new String(entryData, StandardCharsets.UTF_8)));
}
if (entryName.endsWith(".fxml")) {
String className = FXMLParser.getControllerClassName(new ByteArrayInputStream(entryData));
if (className != null) {
this.fxmlControllerClasses.put(entryName, new FXMLControllerData(className.replace('.', '/')));
}
}

files.put(entryName, entryData);
Expand Down Expand Up @@ -627,13 +635,26 @@ public void processJar(Configuration config) throws IOException {
if (entryName.equals("META-INF/MANIFEST.MF")) {
if (Packager.INSTANCE.isEnabled()) {
entryData = Utils.replaceMainClass(new String(entryData, StandardCharsets.UTF_8), Packager.INSTANCE.getDecryptionClassName()).getBytes(StandardCharsets.UTF_8);
} else if (mainClassChanged) {
entryData = Utils.replaceMainClass(new String(entryData, StandardCharsets.UTF_8), mainClass).getBytes(StandardCharsets.UTF_8);
log.info("Replaced Main-Class with " + mainClass);
} else {
if (mainClassChanged) {
entryData = Utils.replaceMainClass(new String(entryData, StandardCharsets.UTF_8), mainClass).getBytes(StandardCharsets.UTF_8);
log.info("Replaced Main-Class with " + mainClass);
}
if (agentClassChanged) {
entryData = Utils.replaceAgentClass(new String(entryData, StandardCharsets.UTF_8), agentClass).getBytes(StandardCharsets.UTF_8);
log.info("Replaced LoaderAgent-Class with " + agentClass);

}
}


log.info("Processed MANIFEST.MF");
}
if (entryName.endsWith(".fxml") && this.fxmlControllerClasses.containsKey(entryName)) {
entryData = FXMLParser.updateFXML(new ByteArrayInputStream(entryData), this.fxmlControllerClasses.get(entryName));
log.info("Processed FXML file " + entryName);

}
log.info("Copying " + entryName);


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package me.superblaubeere27.jobf.processors;

import me.superblaubeere27.annotations.ObfuscationTransformer;
import me.superblaubeere27.jobf.IClassTransformer;
import me.superblaubeere27.jobf.JObfImpl;
import me.superblaubeere27.jobf.ProcessorCallback;
import me.superblaubeere27.jobf.utils.values.DeprecationLevel;
import me.superblaubeere27.jobf.utils.values.EnabledValue;
import me.superblaubeere27.jobf.utils.values.NumberValue;
import me.superblaubeere27.jobf.utils.values.StringValue;
import org.objectweb.asm.*;
import org.objectweb.asm.tree.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.Random;

public class ExpireDate implements IClassTransformer {

private static final String PROCESSOR_NAME = "ExpireDate";

private JObfImpl inst;
private EnabledValue enabled = new EnabledValue(PROCESSOR_NAME, DeprecationLevel.GOOD, true);
private StringValue expireDate = new StringValue(PROCESSOR_NAME, "Exprire Date in format DD\\MM\\YYYY", DeprecationLevel.GOOD,
"01\\01\\2023");
private StringValue message = new StringValue(PROCESSOR_NAME, "Message", DeprecationLevel.GOOD,
"Expired!");
private NumberValue<Integer> chance = new NumberValue<>(PROCESSOR_NAME, "Insert Chance", DeprecationLevel.GOOD,
30);
private NumberValue<Integer> dayVariation = new NumberValue<>(PROCESSOR_NAME, "Day variation", DeprecationLevel.GOOD,
3);

private static Random random = new Random();

private final List<String> exceptions = Arrays.asList(
"java/lang/ClassNotFoundException",
"java/lang/IllegalAccessException",
"java/lang/IllegalArgumentException",
"java/lang/NullPointerException",
"java/lang/NumberFormatException",
"java/lang/UnsupportedOperationException",
"java/lang/ClassCastException");


public ExpireDate(JObfImpl inst) {
this.inst = inst;
}

@Override
public void process(ProcessorCallback callback, ClassNode node) {
if (!enabled.getObject()) return;

for (MethodNode method: node.methods) {
if (((method.access & Opcodes.ACC_ABSTRACT) != 0) ||
((method.access & Opcodes.ACC_INTERFACE) != 0) ||
method.name.equals("main") ||
method.name.equals("<init>") ||
method.name.equals("<clinit>")) {
continue;
}

callback.setForceComputeFrames();
if (random.nextInt(100) < chance.getObject()) {
return;
}
try {
method.instructions.insert(getInstructions());
} catch (ParseException e) {
e.printStackTrace();
}
}
}

private InsnList getInstructions() throws ParseException {
Calendar calendar = Calendar.getInstance();
calendar.setTime((new SimpleDateFormat("dd\\MM\\yyyy")).parse(expireDate.getObject()));
calendar.add(Calendar.DATE, random.nextInt(dayVariation.getObject()));
long expireDateLong = calendar.getTimeInMillis();

String exception = exceptions.get(random.nextInt(exceptions.size()));

InsnList instructions = new InsnList();
instructions.add(new TypeInsnNode(Opcodes.NEW, "java/util/Date"));
instructions.add(new InsnNode(Opcodes.DUP));
instructions.add(new LdcInsnNode(expireDateLong));
instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/util/Date", "<init>", "(J)V",false));
instructions.add(new TypeInsnNode(Opcodes.NEW, "java/util/Date"));
instructions.add(new InsnNode(Opcodes.DUP));
instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/util/Date", "<init>", "()V", false));
instructions.add(new InsnNode(Opcodes.SWAP));
instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/util/Date", "after", "(Ljava/util/Date;)Z", false));
LabelNode label = new LabelNode();
instructions.add(new JumpInsnNode(Opcodes.IFEQ, label));

instructions.add(new TypeInsnNode(Opcodes.NEW, "java/util/Date"));
instructions.add(new InsnNode(Opcodes.DUP));
instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/util/Date", "<init>", "()V", false));
instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/util/Date", "getTime", "()J", false));
instructions.add(new LdcInsnNode(2L));
instructions.add(new InsnNode(Opcodes.LREM));
instructions.add(new InsnNode(Opcodes.LCONST_0));
instructions.add(new InsnNode(Opcodes.LCMP));
instructions.add(new JumpInsnNode(Opcodes.IFNE, label));

instructions.add(new TypeInsnNode(Opcodes.NEW, exception));
instructions.add(new InsnNode(Opcodes.DUP));
instructions.add(new LdcInsnNode(message.getObject()));
instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, exception, "<init>", "(Ljava/lang/String;)V", false));
instructions.add(new InsnNode(Opcodes.ATHROW));
instructions.add(label);
return instructions;
}

@Override
public ObfuscationTransformer getType() {
return ObfuscationTransformer.EXPIREDATE;
}


}
Loading