From 994684351dc0284f736faab2739e834d38e26709 Mon Sep 17 00:00:00 2001 From: superblaubeere27 Date: Tue, 10 Jul 2018 20:02:30 +0200 Subject: [PATCH] Added GUI & Improves StringEncryption --- pom.xml | 7 +- script.js | 9 +- .../superblaubeere27/jobf/Configuration.java | 85 ----- .../jobf/IClassProcessor.java | 2 +- .../java/me/superblaubeere27/jobf/JObf.java | 113 +++--- .../me/superblaubeere27/jobf/JObfImpl.java | 90 ++--- .../jobf/processors/CrasherProcessor.java | 2 +- .../jobf/processors/FlowObfuscator.java | 20 +- .../jobf/processors/HWIDProtection.java | 18 +- .../jobf/processors/InvokeDynamic.java | 9 +- .../jobf/processors/LineNumberRemover.java | 111 ++++-- .../NumberObfuscationProcessor.java | 97 +++++- .../jobf/processors/ReferenceProxy.java | 9 +- .../jobf/processors/SBProcessor.java | 9 +- .../processors/ShuffleMembersProcessor.java | 9 +- .../StaticInitializionProcessor.java | 2 +- .../processors/StringEncryptionProcessor.java | 57 +++- .../string/XOREncryptionAlgorithm.java | 15 +- .../jobf/processors/packager/Packager.java | 2 +- .../java/me/superblaubeere27/jobf/ui/GUI.form | 295 ++++------------ .../java/me/superblaubeere27/jobf/ui/GUI.java | 322 ++++++++++-------- .../me/superblaubeere27/jobf/util/Util.java | 14 + .../jobf/util/script/JObfScript.java | 3 +- .../jobf/util/values/BooleanValue.java | 9 + .../jobf/util/values/ConfigManager.java | 112 ++++++ .../jobf/util/values/Configuration.java | 63 ++++ .../jobf/util/values/DeprecationLevel.java | 5 + .../jobf/util/values/EnabledValue.java | 13 + .../jobf/util/values/ModeValue.java | 22 ++ .../jobf/util/values/NumberValue.java | 9 + .../jobf/util/values/StringValue.java | 13 + .../jobf/util/values/Value.java | 40 +++ .../jobf/util/values/ValueManager.java | 40 +++ .../jobf/utils/NameUtils.java | 6 +- .../jobf/utils/NodeUtils.java | 15 +- .../superblaubeere27/jobf/utils/Template.java | 24 ++ .../jobf/utils/Templates.java | 55 +++ src/main/resources/templates/Aggressive.json | 36 ++ src/main/resources/theme.xml | 88 +++++ .../me/superblaubeere27/ObfuscatorTest.java | 5 +- 40 files changed, 1199 insertions(+), 656 deletions(-) delete mode 100644 src/main/java/me/superblaubeere27/jobf/Configuration.java create mode 100644 src/main/java/me/superblaubeere27/jobf/util/values/BooleanValue.java create mode 100644 src/main/java/me/superblaubeere27/jobf/util/values/ConfigManager.java create mode 100644 src/main/java/me/superblaubeere27/jobf/util/values/Configuration.java create mode 100644 src/main/java/me/superblaubeere27/jobf/util/values/DeprecationLevel.java create mode 100644 src/main/java/me/superblaubeere27/jobf/util/values/EnabledValue.java create mode 100644 src/main/java/me/superblaubeere27/jobf/util/values/ModeValue.java create mode 100644 src/main/java/me/superblaubeere27/jobf/util/values/NumberValue.java create mode 100644 src/main/java/me/superblaubeere27/jobf/util/values/StringValue.java create mode 100644 src/main/java/me/superblaubeere27/jobf/util/values/Value.java create mode 100644 src/main/java/me/superblaubeere27/jobf/util/values/ValueManager.java create mode 100644 src/main/java/me/superblaubeere27/jobf/utils/Template.java create mode 100644 src/main/java/me/superblaubeere27/jobf/utils/Templates.java create mode 100644 src/main/resources/templates/Aggressive.json create mode 100644 src/main/resources/theme.xml diff --git a/pom.xml b/pom.xml index 888b800..7d8f943 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ me.superblaubeere27 obfuscator - 1.5 + 1.6 @@ -16,6 +16,11 @@ asm-debug-all 6.0_BETA + + com.fifesoft + rsyntaxtextarea + 2.6.1 + diff --git a/script.js b/script.js index 9394a55..d0d5886 100644 --- a/script.js +++ b/script.js @@ -1,11 +1,6 @@ function isRemappingEnabledForClass(name) { - if (name.toLowerCase().endsWith("main")) { - print("Keeping Main-Class " + name); - return false; - } - - return true; + return false; } function isObfuscatorEnabledForClass(name) { - return !name.contains("netty"); + return true; } \ No newline at end of file diff --git a/src/main/java/me/superblaubeere27/jobf/Configuration.java b/src/main/java/me/superblaubeere27/jobf/Configuration.java deleted file mode 100644 index 1d8d119..0000000 --- a/src/main/java/me/superblaubeere27/jobf/Configuration.java +++ /dev/null @@ -1,85 +0,0 @@ -package me.superblaubeere27.jobf; - -import com.google.gson.JsonObject; - -public class Configuration { - public boolean isFlowObfuscatorEnabled; - public boolean isInformationRemoverEnabled; - public boolean isNumberObfuscatorEnabled; - public boolean isHiderEnabled; - public boolean isShuffleMembersEnabled; - public boolean isStaticInitializionProtectorEnabled; - public boolean isStringEncryptionEnabled; - public boolean isReferenceProxyEnabled; - - public Configuration fromJson(JsonObject object) { - if (object.has("FlowObfuscator")) { - JsonObject obj1 = object.getAsJsonObject("FlowObfuscator"); - isFlowObfuscatorEnabled = obj1.has("enabled") && obj1.get("enabled").getAsBoolean(); - } - if (object.has("ReferenceProxy")) { - JsonObject obj1 = object.getAsJsonObject("ReferenceProxy"); - isReferenceProxyEnabled = obj1.has("enabled") && obj1.get("enabled").getAsBoolean(); - } - - if (object.has("InformationRemover")) { - JsonObject obj1 = object.getAsJsonObject("InformationRemover"); - isInformationRemoverEnabled = obj1.has("enabled") && obj1.get("enabled").getAsBoolean(); - } - if (object.has("NumberObfuscation")) { - JsonObject obj1 = object.getAsJsonObject("NumberObfuscation"); - isNumberObfuscatorEnabled = obj1.has("enabled") && obj1.get("enabled").getAsBoolean(); - } - if (object.has("Hider")) { - JsonObject obj1 = object.getAsJsonObject("Hider"); - isHiderEnabled = obj1.has("enabled") && obj1.get("enabled").getAsBoolean(); - } - if (object.has("StaticInitializion")) { - JsonObject obj1 = object.getAsJsonObject("StaticInitializion"); - isStaticInitializionProtectorEnabled = obj1.has("enabled") && obj1.get("enabled").getAsBoolean(); - } - if (object.has("StringEncryption")) { - JsonObject obj1 = object.getAsJsonObject("StringEncryption"); - isStringEncryptionEnabled = obj1.has("enabled") && obj1.get("enabled").getAsBoolean(); - } - return this; - } - - public JsonObject toJson() { - JsonObject object = new JsonObject(); - - JsonObject flowObfuscatorObject = new JsonObject(); - flowObfuscatorObject.addProperty("enabled", isFlowObfuscatorEnabled); - - object.add("ReferenceProxy", flowObfuscatorObject); - JsonObject refProxy = new JsonObject(); - refProxy.addProperty("enabled", isReferenceProxyEnabled); - object.add("ReferenceProxy", refProxy); - - JsonObject informationRemover = new JsonObject(); - informationRemover.addProperty("enabled", isInformationRemoverEnabled); - object.add("InformationRemover", informationRemover); - - JsonObject isNumberObfuscationRemover = new JsonObject(); - isNumberObfuscationRemover.addProperty("enabled", isNumberObfuscatorEnabled); - object.add("NumberObfuscation", isNumberObfuscationRemover); - - JsonObject hiderObject = new JsonObject(); - hiderObject.addProperty("enabled", isHiderEnabled); - object.add("Hider", hiderObject); - - JsonObject shuffleProcessor = new JsonObject(); - shuffleProcessor.addProperty("enabled", isShuffleMembersEnabled); - object.add("Hider", shuffleProcessor); - - JsonObject staticInitializion = new JsonObject(); - staticInitializion.addProperty("enabled", isStaticInitializionProtectorEnabled); - object.add("StaticInitializion", staticInitializion); - - JsonObject stringencryption = new JsonObject(); - stringencryption.addProperty("enabled", isStringEncryptionEnabled); - object.add("StringEncryption", stringencryption); - - return object; - } -} diff --git a/src/main/java/me/superblaubeere27/jobf/IClassProcessor.java b/src/main/java/me/superblaubeere27/jobf/IClassProcessor.java index 8fd7406..e801c3f 100644 --- a/src/main/java/me/superblaubeere27/jobf/IClassProcessor.java +++ b/src/main/java/me/superblaubeere27/jobf/IClassProcessor.java @@ -3,5 +3,5 @@ import org.objectweb.asm.tree.ClassNode; public interface IClassProcessor { - void process(ClassNode node, int mode); + void process(ClassNode node); } \ No newline at end of file diff --git a/src/main/java/me/superblaubeere27/jobf/JObf.java b/src/main/java/me/superblaubeere27/jobf/JObf.java index 7904006..c9c7378 100644 --- a/src/main/java/me/superblaubeere27/jobf/JObf.java +++ b/src/main/java/me/superblaubeere27/jobf/JObf.java @@ -6,21 +6,53 @@ import me.superblaubeere27.hwid.HWID; import me.superblaubeere27.jobf.ui.GUI; import me.superblaubeere27.jobf.util.script.JObfScript; +import me.superblaubeere27.jobf.utils.Templates; +import javax.swing.*; import java.io.File; -import java.io.PrintWriter; -import java.io.StringWriter; import java.nio.file.Files; import java.util.ArrayList; import java.util.List; -import java.util.logging.*; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; public class JObf { - private static final String VERSION = "Obfuscator v" + (JObf.class.getPackage().getImplementationVersion() == null ? "0.0" : JObf.class.getPackage().getImplementationVersion()) + " by superblaubeere27"; - private final static Logger log = Logger.getLogger("Obfuscator"); + public static final String VERSION = "obfuscator " + (JObf.class.getPackage().getImplementationVersion() == null ? "DEV" : "v" + JObf.class.getPackage().getImplementationVersion()) + " by superblaubeere27"; + public final static Logger log = Logger.getLogger("obfuscator"); private static GUI gui; public static void main(String[] args) throws Exception { + Class.forName(JObfImpl.class.getCanonicalName()); + JObf.log.setUseParentHandlers(false); + JObf.log.setLevel(Level.ALL); + JObf.log.setFilter(record -> true); + +// if (log != null) {a + + JObf.log.addHandler(new Handler() { + @Override + public void publish(LogRecord record) { +// if (record.getLevel().intValue() < Level.INFO.intValue()) return; +// System.out.println("ACAB"); + if (gui != null) { + gui.logArea.append(String.format(record.getMessage(), record.getParameters()) + "\n"); + gui.scrollDown(); +// System.out.println("lloool"); + } + + System.out.println(String.format(record.getMessage(), record.getParameters())); + } + + @Override + public void flush() { + } + + @Override + public void close() throws SecurityException { + } + }); // MethodHandle handle = MethodHandles.lookup().findVirtual(PrintStream.class, "println", MethodType.methodType(void.class, int.class)); // handle.asType(MethodType.methodType(void.class, int.class)); // MethodHandles.lookup().loo @@ -31,6 +63,8 @@ public static void main(String[] args) throws Exception { // throwable.printStackTrace(); // } + Templates.loadTemplates(); + OptionParser parser = new OptionParser(); parser.accepts("help").forHelp(); parser.accepts("version").forHelp(); @@ -63,56 +97,7 @@ public static void main(String[] args) throws Exception { String log = (String) options.valueOf("log"); int mode = (int) options.valueOf("mode"); - JObf.log.setUseParentHandlers(false); - JObf.log.setLevel(Level.ALL); - - if (log != null) { - FileHandler filehandler = new FileHandler(log); - filehandler.setFormatter(new Formatter() { - @Override - public synchronized String format(LogRecord record) { - StringBuffer sb = new StringBuffer(); - String message = this.formatMessage(record); - sb.append(record.getLevel().getName()); - sb.append(": "); - sb.append(message); - sb.append("\n"); - if (record.getThrown() != null) { - try { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - record.getThrown().printStackTrace(pw); - pw.close(); - sb.append(sw.toString()); - } catch (Exception ex) { - } - } - return sb.toString(); - } - - }); - JObf.log.addHandler(filehandler); - } - - JObf.log.addHandler(new Handler() { - @Override - public void publish(LogRecord record) { -// if (record.getLevel().intValue() < Level.INFO.intValue()) return; - - if (gui != null) - gui.logArea.append(String.format(record.getMessage(), record.getParameters()) + "\n"); - - System.out.println(String.format(record.getMessage(), record.getParameters())); - } - - @Override - public void flush() { - } - @Override - public void close() throws SecurityException { - } - }); log(JObf.VERSION); log("Input: " + jarIn); @@ -130,9 +115,7 @@ public void close() throws SecurityException { String path = p.toString().toLowerCase(); return path.endsWith(".jar") || path.endsWith(".zip"); - }).forEach(p -> { - fileList.add(p.toFile()); - }); + }).forEach(p -> fileList.add(p.toFile())); } else if (file.getName().endsWith(".jar") || file.getName().endsWith(".zip")) { fileList.add(file); } @@ -158,13 +141,13 @@ public void close() throws SecurityException { System.exit(1); } } catch (OptionException e) { -// try { -// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); -// } catch (Exception e1) { -// e1.printStackTrace(); -// } + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception e1) { + e1.printStackTrace(); + } -// gui = new GUI(); + gui = new GUI(); // e.printStackTrace(); // parser.printHelpOn(System.out); System.err.println("ERROR: " + e.getMessage() + " (try --help)"); @@ -176,4 +159,8 @@ public void close() throws SecurityException { private static void log(String line) { log.info(line); } + + public static void report(String s) { + + } } diff --git a/src/main/java/me/superblaubeere27/jobf/JObfImpl.java b/src/main/java/me/superblaubeere27/jobf/JObfImpl.java index 192b8c7..393f5f7 100644 --- a/src/main/java/me/superblaubeere27/jobf/JObfImpl.java +++ b/src/main/java/me/superblaubeere27/jobf/JObfImpl.java @@ -7,6 +7,7 @@ import me.superblaubeere27.jobf.processors.packager.Packager; import me.superblaubeere27.jobf.util.Util; import me.superblaubeere27.jobf.util.script.JObfScript; +import me.superblaubeere27.jobf.util.values.ValueManager; import me.superblaubeere27.jobf.utils.ClassTree; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; @@ -21,15 +22,15 @@ import java.io.*; import java.util.*; import java.util.logging.Level; -import java.util.logging.Logger; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; public class JObfImpl { - final static Logger log = Logger.getLogger("Obfuscator"); - public static List processors = new ArrayList<>(); + public static final JObfImpl INSTANCE = new JObfImpl(); + // final static Logger log = Logger.getLogger("Obfuscator"); + public static List processors; private boolean packagerEnabled = false; private boolean hwid; private byte[] hwidBytes; @@ -69,6 +70,8 @@ public JObfImpl() { // processors.add(new SBProcessor(this)); // processors.add(new LineNumberRemover(this)); // processors.add(new ShuffleMembersProcessor(this)); + processors = new ArrayList<>(); + addProcessors(); } public static void processConsole(String inFile, String outFile, List fileList, String logFile, int mode, boolean packager, boolean nameobf, boolean hwid, boolean invokeDynamic, byte[] hwidBytes, String packagerMainClass, JObfScript script) { @@ -85,20 +88,20 @@ public static void processConsole(String inFile, String outFile, List file inst.script = script; inst.nameobf = nameobf; - inst.addProcessors(); +// inst.addProcessors(); try { - System.out.println("Loading classpath..."); + JObf.log.info("Loading classpath..."); inst.loadClasspath(); - System.out.println("Loaded"); + JObf.log.info("Loaded"); } catch (IOException e) { e.printStackTrace(); } inst.processJar(inFile, outFile, mode); - log.fine("Processed " + inFile); + JObf.log.fine("Processed " + inFile); } public String getMainClass() { @@ -133,7 +136,7 @@ private void loadClasspath() throws IOException { int i = 0; for (File file : libraryFiles) { if (file.isFile()) { - System.out.println("Loading " + file.getAbsolutePath() + " (" + (i++ * 100 / libraryFiles.size()) + "%)"); + JObf.log.info("Loading " + file.getAbsolutePath() + " (" + (i++ * 100 / libraryFiles.size()) + "%)"); classpath.putAll(loadClasspathFile(file, true)); } // else { @@ -322,14 +325,17 @@ public void addProcessor(IClassProcessor processor) { } public void addProcessors() { - processors.add(new StaticInitializionProcessor(this)); + processors + .add( + new StaticInitializionProcessor( + this)); - if (hwid) { - processors.add(new HWIDProtection(this, hwidBytes)); - } - if (invokeDynamic) { +// if (hwid) { + processors.add(new HWIDProtection(this)); +// } +// if (invokeDynamic) { processors.add(new InvokeDynamic(this)); - } +// } processors.add(new StringEncryptionProcessor(this)); processors.add(new NumberObfuscationProcessor(this)); processors.add(new FlowObfuscator(this)); @@ -340,7 +346,18 @@ public void addProcessors() { nameObfuscationProcessors.add(new NameObfuscation()); // processors.add(new CrasherProcessor(this)); -// processors.add(new ReferenceProxy(this)); + processors.add(new ReferenceProxy(this)); + + for (IClassProcessor processor : processors) { + ValueManager.registerClass(processor); + } +// for (Value value : ValueManager.getValues()) { +// System.out.println(value); +// } + } + + public void setScript(JObfScript script) { + this.script = script; } public void processJar(String inFile, String outFile, int mode) { @@ -353,6 +370,7 @@ public void processJar(String inFile, String outFile, int mode) { packager.initHWID(hwidBytes); } } + ZipInputStream inJar = null; ZipOutputStream outJar = null; @@ -411,7 +429,7 @@ public void processJar(String inFile, String outFile, int mode) { } else { if (entryName.equals("META-INF/MANIFEST.MF")) { setMainClass(Util.getMainClass(new String(entryData, "UTF-8"))); - System.out.println(mainClass); + JObf.log.fine(mainClass); } files.put(entryName, entryData); @@ -438,14 +456,15 @@ public void processJar(String inFile, String outFile, int mode) { try { try { + computeMode = ClassWriter.COMPUTE_MAXS; - JObfImpl.log.log(Level.FINE, String.format("(%s/%s), Processing %s", processed, classes.size(), entryName)); + JObf.log.log(Level.INFO, String.format("(%s/%s), Processing %s", processed, classes.size(), entryName)); if (script == null || script.isObfuscatorEnabled(cn.name)) { for (IClassProcessor proc : processors) - proc.process(cn, mode); + proc.process(cn); } @@ -495,12 +514,12 @@ public void processJar(String inFile, String outFile, int mode) { entryData = Util.replaceMainClass(new String(entryData, "UTF-8"), packager.getDecryptorClassName()).getBytes("UTF-8"); } else if (mainClassChanged) { entryData = Util.replaceMainClass(new String(entryData, "UTF-8"), mainClass).getBytes("UTF-8"); - JObfImpl.log.log(Level.FINE, "Replaced Main-Class with " + mainClass); + JObf.log.log(Level.FINE, "Replaced Main-Class with " + mainClass); } - JObfImpl.log.log(Level.FINE, "Processed MANIFEST.MF"); + JObf.log.log(Level.FINE, "Processed MANIFEST.MF"); } - JObfImpl.log.log(Level.FINE, "Copying " + entryName); + JObf.log.log(Level.INFO, "Copying " + entryName); ZipEntry newEntry = new ZipEntry(entryName); outJar.putNextEntry(newEntry); @@ -519,12 +538,12 @@ public void processJar(String inFile, String outFile, int mode) { outJar.write(ByteStreams.toByteArray(JObfImpl.class.getClassLoader().getResourceAsStream(name))); } if (packagerEnabled) { - System.out.println("Packaging..."); + JObf.log.info("Packaging..."); byte[] decryptorData = packager.generateEncryptionClass(packagerMainClass, mode); outJar.putNextEntry(new ZipEntry(packager.getDecryptorClassName() + ".class")); outJar.write(decryptorData); outJar.closeEntry(); - System.out.println("Packaging finished."); + JObf.log.info("Packaging finished."); } } catch (Exception e) { e.printStackTrace(); @@ -533,7 +552,7 @@ public void processJar(String inFile, String outFile, int mode) { try { outJar.flush(); outJar.close(); - System.out.println(">>> Processing completed +" + (new File(inFile).length() / ((float) new File(outFile).length()) * 100.0f) + "%"); + JObf.log.info(">>> Processing completed +" + (new File(inFile).length() / ((float) new File(outFile).length()) * 100.0f) + "%"); } catch (Exception e) { // ignore } @@ -566,9 +585,9 @@ public byte[] processClass(byte[] cls, boolean readOnly, int mode) { cr.accept(ca, 0); for (IClassProcessor proc : processors) - proc.process(cn, mode); + proc.process(cn); - Analyzer analyzer = new Analyzer(new BasicInterpreter()); + Analyzer analyzer = new Analyzer<>(new BasicInterpreter()); for (MethodNode method : cn.methods) { System.err.println("Verifing " + cn.name + "/" + method.name); @@ -587,23 +606,4 @@ public byte[] processClass(byte[] cls, boolean readOnly, int mode) { return workDone ? writer.toByteArray() : cls; } - public void loadConfig(Configuration config) { - FlowObfuscator flowObfuscator = new FlowObfuscator(this); - LineNumberRemover numberRemover = new LineNumberRemover(this); - NumberObfuscationProcessor numberProcessor = new NumberObfuscationProcessor(this); - SBProcessor sbProcessor = new SBProcessor(this); - ShuffleMembersProcessor shuffleMembersProcessor = new ShuffleMembersProcessor(this); - StaticInitializionProcessor staticInitializionProcessor = new StaticInitializionProcessor(this); - StringEncryptionProcessor stringEncryptionProcessor = new StringEncryptionProcessor(this); - ReferenceProxy referenceProxy = new ReferenceProxy(this); - - if (config.isStaticInitializionProtectorEnabled) addProcessor(staticInitializionProcessor); - if (config.isReferenceProxyEnabled) addProcessor(referenceProxy); - if (config.isStringEncryptionEnabled) addProcessor(stringEncryptionProcessor); - if (config.isNumberObfuscatorEnabled) addProcessor(numberProcessor); - if (config.isFlowObfuscatorEnabled) addProcessor(flowObfuscator); - if (config.isInformationRemoverEnabled) addProcessor(numberRemover); - if (config.isHiderEnabled) addProcessor(sbProcessor); - if (config.isShuffleMembersEnabled) addProcessor(shuffleMembersProcessor); - } } diff --git a/src/main/java/me/superblaubeere27/jobf/processors/CrasherProcessor.java b/src/main/java/me/superblaubeere27/jobf/processors/CrasherProcessor.java index 058a28a..945910c 100644 --- a/src/main/java/me/superblaubeere27/jobf/processors/CrasherProcessor.java +++ b/src/main/java/me/superblaubeere27/jobf/processors/CrasherProcessor.java @@ -32,7 +32,7 @@ public CrasherProcessor(JObfImpl inst) { } @Override - public void process(ClassNode node, int mode) { + public void process(ClassNode node) { if (Modifier.isInterface(node.access)) return; for (MethodNode method : node.methods) { diff --git a/src/main/java/me/superblaubeere27/jobf/processors/FlowObfuscator.java b/src/main/java/me/superblaubeere27/jobf/processors/FlowObfuscator.java index 05ffeec..c47add7 100644 --- a/src/main/java/me/superblaubeere27/jobf/processors/FlowObfuscator.java +++ b/src/main/java/me/superblaubeere27/jobf/processors/FlowObfuscator.java @@ -2,6 +2,9 @@ import me.superblaubeere27.jobf.IClassProcessor; import me.superblaubeere27.jobf.JObfImpl; +import me.superblaubeere27.jobf.util.values.BooleanValue; +import me.superblaubeere27.jobf.util.values.DeprecationLevel; +import me.superblaubeere27.jobf.util.values.EnabledValue; import me.superblaubeere27.jobf.utils.NameUtils; import me.superblaubeere27.jobf.utils.NodeUtils; import org.objectweb.asm.Opcodes; @@ -14,6 +17,13 @@ public class FlowObfuscator implements IClassProcessor { private static Random random = new Random(); private JObfImpl inst; + private static final String PROCESSOR_NAME = "FlowObfuscator"; + + private EnabledValue enabled = new EnabledValue(PROCESSOR_NAME, DeprecationLevel.GOOD, true); + private BooleanValue replaceGoto = new BooleanValue(PROCESSOR_NAME, "Replace GOTO", DeprecationLevel.GOOD, true); + private BooleanValue replaceIf = new BooleanValue(PROCESSOR_NAME, "Replace If", DeprecationLevel.GOOD, true); + private BooleanValue badPop = new BooleanValue(PROCESSOR_NAME, "Bad POP", DeprecationLevel.GOOD, true); + public FlowObfuscator(JObfImpl inst) { this.inst = inst; } @@ -229,24 +239,26 @@ public static MethodNode ifWrapper(int opcode) { } @Override - public void process(ClassNode node, int mode) { + public void process(ClassNode node) { + if (!enabled.getObject()) return; + HashMap jumpMethodMap = new HashMap<>(); for (MethodNode method : node.methods) { for (AbstractInsnNode abstractInsnNode : method.instructions.toArray()) { - if (abstractInsnNode instanceof JumpInsnNode && abstractInsnNode.getOpcode() == Opcodes.GOTO) { + if (badPop.getObject() && abstractInsnNode instanceof JumpInsnNode && abstractInsnNode.getOpcode() == Opcodes.GOTO) { method.instructions.insertBefore(abstractInsnNode, new LdcInsnNode("")); method.instructions.insertBefore(abstractInsnNode, new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/String", "length", "()I", false)); method.instructions.insertBefore(abstractInsnNode, new InsnNode(Opcodes.POP)); } - if (abstractInsnNode instanceof JumpInsnNode && abstractInsnNode.getOpcode() == Opcodes.GOTO) { + if (replaceIf.getObject() && abstractInsnNode instanceof JumpInsnNode && abstractInsnNode.getOpcode() == Opcodes.GOTO) { JumpInsnNode insnNode = (JumpInsnNode) abstractInsnNode; final InsnList insnList = new InsnList(); insnList.add(ifGoto(insnNode.label)); method.instructions.insert(insnNode, insnList); method.instructions.remove(insnNode); } - if (abstractInsnNode instanceof JumpInsnNode && (abstractInsnNode.getOpcode() >= Opcodes.IFEQ && abstractInsnNode.getOpcode() <= Opcodes.IF_ACMPNE || abstractInsnNode.getOpcode() >= Opcodes.IFNULL && abstractInsnNode.getOpcode() <= Opcodes.IFNONNULL)) { + if (replaceGoto.getObject() && abstractInsnNode instanceof JumpInsnNode && (abstractInsnNode.getOpcode() >= Opcodes.IFEQ && abstractInsnNode.getOpcode() <= Opcodes.IF_ACMPNE || abstractInsnNode.getOpcode() >= Opcodes.IFNULL && abstractInsnNode.getOpcode() <= Opcodes.IFNONNULL)) { JumpInsnNode insnNode = (JumpInsnNode) abstractInsnNode; MethodNode wrapper = jumpMethodMap.get(insnNode.getOpcode()); diff --git a/src/main/java/me/superblaubeere27/jobf/processors/HWIDProtection.java b/src/main/java/me/superblaubeere27/jobf/processors/HWIDProtection.java index 70b4cd3..f936538 100644 --- a/src/main/java/me/superblaubeere27/jobf/processors/HWIDProtection.java +++ b/src/main/java/me/superblaubeere27/jobf/processors/HWIDProtection.java @@ -1,7 +1,11 @@ package me.superblaubeere27.jobf.processors; +import me.superblaubeere27.hwid.HWID; import me.superblaubeere27.jobf.IClassProcessor; import me.superblaubeere27.jobf.JObfImpl; +import me.superblaubeere27.jobf.util.values.DeprecationLevel; +import me.superblaubeere27.jobf.util.values.EnabledValue; +import me.superblaubeere27.jobf.util.values.StringValue; import me.superblaubeere27.jobf.utils.NameUtils; import me.superblaubeere27.jobf.utils.NodeUtils; import org.objectweb.asm.Label; @@ -15,11 +19,13 @@ public class HWIDProtection implements IClassProcessor { private static Random random = new Random(); - private final byte[] hwid; private JObfImpl inst; + private static final String PROCESSOR_NAME = "HWIDPRotection"; + private EnabledValue enabled = new EnabledValue(PROCESSOR_NAME, DeprecationLevel.GOOD, false); + private StringValue hwidValue = new StringValue(PROCESSOR_NAME, "HWID", DeprecationLevel.GOOD, HWID.bytesToHex(HWID.generateHWID())); + private byte[] hwid; - public HWIDProtection(JObfImpl inst, byte[] hwid) { - this.hwid = hwid; + public HWIDProtection(JObfImpl inst) { this.inst = inst; } @@ -139,7 +145,11 @@ private static String addHWIDGenerator(ClassNode cn) { } @Override - public void process(ClassNode node, int mode) { + public void process(ClassNode node) { + if (!enabled.getObject()) return; + + hwid = HWID.hexStringToByteArray(hwidValue.getObject()); + if (Modifier.isInterface(node.access)) { return; } diff --git a/src/main/java/me/superblaubeere27/jobf/processors/InvokeDynamic.java b/src/main/java/me/superblaubeere27/jobf/processors/InvokeDynamic.java index 48752b5..2d90523 100644 --- a/src/main/java/me/superblaubeere27/jobf/processors/InvokeDynamic.java +++ b/src/main/java/me/superblaubeere27/jobf/processors/InvokeDynamic.java @@ -2,6 +2,8 @@ import me.superblaubeere27.jobf.IClassProcessor; import me.superblaubeere27.jobf.JObfImpl; +import me.superblaubeere27.jobf.util.values.DeprecationLevel; +import me.superblaubeere27.jobf.util.values.EnabledValue; import me.superblaubeere27.jobf.utils.NameUtils; import me.superblaubeere27.jobf.utils.NodeUtils; import org.objectweb.asm.*; @@ -17,6 +19,9 @@ public class InvokeDynamic implements IClassProcessor { private static Random random = new Random(); private JObfImpl inst; + private static final String PROCESSOR_NAME = "InvokeDynamic"; + + private EnabledValue enabled = new EnabledValue(PROCESSOR_NAME, DeprecationLevel.OK, false); public InvokeDynamic(JObfImpl inst) { this.inst = inst; @@ -143,7 +148,9 @@ private static MethodNode bootstrap(FieldNode arrayField, ClassNode node) { } @Override - public void process(ClassNode classNode, int mode) { + public void process(ClassNode classNode) { + if (!enabled.getObject()) return; + if (!NodeUtils.isClassValid(classNode)) { return; } diff --git a/src/main/java/me/superblaubeere27/jobf/processors/LineNumberRemover.java b/src/main/java/me/superblaubeere27/jobf/processors/LineNumberRemover.java index 62a0932..78f14dc 100644 --- a/src/main/java/me/superblaubeere27/jobf/processors/LineNumberRemover.java +++ b/src/main/java/me/superblaubeere27/jobf/processors/LineNumberRemover.java @@ -2,42 +2,105 @@ import me.superblaubeere27.jobf.IClassProcessor; import me.superblaubeere27.jobf.JObfImpl; -import org.objectweb.asm.tree.ClassNode; +import me.superblaubeere27.jobf.util.values.BooleanValue; +import me.superblaubeere27.jobf.util.values.DeprecationLevel; +import me.superblaubeere27.jobf.util.values.EnabledValue; +import me.superblaubeere27.jobf.util.values.StringValue; +import me.superblaubeere27.jobf.utils.NameUtils; +import org.objectweb.asm.tree.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; import java.util.Random; public class LineNumberRemover implements IClassProcessor { private static Random random = new Random(); private JObfImpl inst; + private static final String PROCESSOR_NAME = "LineNumberRemover"; + private static ArrayList TYPES = new ArrayList<>(); + + static { + TYPES.add("Z"); + TYPES.add("C"); + TYPES.add("B"); + TYPES.add("S"); + TYPES.add("I"); + TYPES.add("F"); + TYPES.add("J"); + TYPES.add("D"); + TYPES.add("Ljava/lang/Exception;"); + TYPES.add("Ljava/lang/String;"); + } + + private EnabledValue enabled = new EnabledValue(PROCESSOR_NAME, DeprecationLevel.GOOD, true); + private BooleanValue renameValues = new BooleanValue(PROCESSOR_NAME, "Rename local variables", DeprecationLevel.GOOD, true); + private BooleanValue removeLineNumbers = new BooleanValue(PROCESSOR_NAME, "Remove Line Numbers", DeprecationLevel.GOOD, true); + private BooleanValue removeDebugNames = new BooleanValue(PROCESSOR_NAME, "Remove Debug Names", DeprecationLevel.GOOD, true); + private BooleanValue addLocalVariables = new BooleanValue(PROCESSOR_NAME, "Add Local Variables", DeprecationLevel.GOOD, true); + private StringValue newSourceFileName = new StringValue(PROCESSOR_NAME, "New SourceFile Name", DeprecationLevel.GOOD, ""); public LineNumberRemover(JObfImpl inst) { this.inst = inst; } @Override - public void process(ClassNode node, int mode) { -// for (MethodNode method : node.methods) { -// for (AbstractInsnNode abstractInsnNode : method.instructions.toArray()) { -// if (abstractInsnNode instanceof LineNumberNode) { -// LineNumberNode insnNode = (LineNumberNode) abstractInsnNode; -// method.instructions.remove(insnNode); -// } -// } -// if (method.parameters != null) { -// for (ParameterNode parameter : method.parameters) { -// parameter.name = NameUtils.unicodeString((int) (Math.random() * 20 + 1)); -// } -// } -// if (method.localVariables != null) { -// for (LocalVariableNode parameter : method.localVariables) { -// parameter.name = NameUtils.generateLocalVariableName(); -// } -// } -// } -// if (node.sourceFile == null || !node.sourceFile.contains(StringEncryptionProcessor.MAGICNUMBER_START)) { -// node.sourceFile = null; -// } -// inst.setWorkDone(); + public void process(ClassNode node) { + if (!enabled.getObject()) return; + + for (MethodNode method : node.methods) { + LabelNode firstLabel = null; + LabelNode lastLabel = null; + HashMap varMap = new HashMap<>(); + + for (AbstractInsnNode abstractInsnNode : method.instructions.toArray()) { + if (abstractInsnNode instanceof LineNumberNode && removeLineNumbers.getObject()) { + LineNumberNode insnNode = (LineNumberNode) abstractInsnNode; + method.instructions.remove(insnNode); + } + + if (abstractInsnNode instanceof VarInsnNode) { + VarInsnNode insnNode = (VarInsnNode) abstractInsnNode; + + if (!varMap.containsKey(insnNode.var)) { + varMap.put(insnNode.var, TYPES.get(random.nextInt(TYPES.size()))); + } + } + if (abstractInsnNode instanceof LabelNode) { + LabelNode insnNode = (LabelNode) abstractInsnNode; + + if (firstLabel == null) { + firstLabel = insnNode; + } + + lastLabel = insnNode; + } + } + + if (firstLabel != null && addLocalVariables.getObject()) { + if (method.localVariables == null) method.localVariables = new ArrayList<>(); + + for (Map.Entry integerStringEntry : varMap.entrySet()) { + method.localVariables.add(new LocalVariableNode(NameUtils.generateLocalVariableName(), integerStringEntry.getValue(), null, firstLabel, lastLabel, integerStringEntry.getKey())); + } + } + + if (method.parameters != null && renameValues.getObject()) { + for (ParameterNode parameter : method.parameters) { + parameter.name = NameUtils.generateLocalVariableName(); + } + } + if (method.localVariables != null && renameValues.getObject()) { + for (LocalVariableNode parameter : method.localVariables) { + parameter.name = NameUtils.generateLocalVariableName(); + } + } + } + if ((node.sourceFile == null || !node.sourceFile.contains(StringEncryptionProcessor.MAGICNUMBER_START)) && removeDebugNames.getObject()) { + node.sourceFile = newSourceFileName.getObject().isEmpty() ? null : newSourceFileName.getObject(); + } + + inst.setWorkDone(); } } \ No newline at end of file diff --git a/src/main/java/me/superblaubeere27/jobf/processors/NumberObfuscationProcessor.java b/src/main/java/me/superblaubeere27/jobf/processors/NumberObfuscationProcessor.java index 1b32707..0d3ece4 100644 --- a/src/main/java/me/superblaubeere27/jobf/processors/NumberObfuscationProcessor.java +++ b/src/main/java/me/superblaubeere27/jobf/processors/NumberObfuscationProcessor.java @@ -2,6 +2,9 @@ import me.superblaubeere27.jobf.IClassProcessor; import me.superblaubeere27.jobf.JObfImpl; +import me.superblaubeere27.jobf.util.values.BooleanValue; +import me.superblaubeere27.jobf.util.values.DeprecationLevel; +import me.superblaubeere27.jobf.util.values.EnabledValue; import me.superblaubeere27.jobf.utils.NameUtils; import me.superblaubeere27.jobf.utils.NodeUtils; import org.objectweb.asm.Opcodes; @@ -15,20 +18,29 @@ public class NumberObfuscationProcessor implements IClassProcessor { private static Random random = new Random(); private JObfImpl inst; + private static final String PROCESSOR_NAME = "NumberObfuscation"; private static boolean lenghtMode = true; private static boolean xorMode = true; private static boolean simpleMathMode = true; + private static NumberObfuscationProcessor INSTANCE; + private EnabledValue enabled = new EnabledValue(PROCESSOR_NAME, DeprecationLevel.GOOD, true); + private BooleanValue extractToArray = new BooleanValue(PROCESSOR_NAME, "Extract to Array", DeprecationLevel.GOOD, true); + private BooleanValue obfuscateZero = new BooleanValue(PROCESSOR_NAME, "Obfuscate Zero", DeprecationLevel.GOOD, true); + private BooleanValue shift = new BooleanValue(PROCESSOR_NAME, "Shift", DeprecationLevel.OK, false); + private BooleanValue and = new BooleanValue(PROCESSOR_NAME, "And", DeprecationLevel.OK, false); + private BooleanValue multipleInstrucstions = new BooleanValue(PROCESSOR_NAME, "Multiple Instructions", DeprecationLevel.GOOD, true); public NumberObfuscationProcessor(JObfImpl inst) { this.inst = inst; + INSTANCE = this; } public static InsnList getInstructionsMultipleTimes(int value, int iterations) { InsnList list = new InsnList(); list.add(NodeUtils.generateIntPush(value)); - for (int i = 0; i < iterations; i++) { + for (int i = 0; i < (INSTANCE.multipleInstrucstions.getObject() ? iterations : 1); i++) { list = obfuscateInsnList(list); } return list; @@ -50,20 +62,55 @@ public static InsnList obfuscateInsnList(InsnList list) { } public static InsnList getInstructions(int value) { - /* - * Method 0: FASTEST, longer JIT (just in time) compiling, the length variable of string is predefined - * Method 1: FAST, XOR is faster than ADD and SUB - * Method 3: FAST - */ InsnList methodInstructions = new InsnList(); + + if (value == 0 && INSTANCE.obfuscateZero.getObject()) { + int randomInt = random.nextInt(100); + methodInstructions.add(getInstructions(randomInt)); + methodInstructions.add(getInstructions(randomInt)); + methodInstructions.add(new InsnNode(Opcodes.ICONST_M1)); + methodInstructions.add(new InsnNode(Opcodes.IXOR)); + methodInstructions.add(new InsnNode(Opcodes.IAND)); + + return methodInstructions; + } + int[] shiftOutput = splitToLShift(value); + + if (shiftOutput[1] > 0 && INSTANCE.shift.getObject()) { + methodInstructions.add(getInstructions(shiftOutput[0])); + methodInstructions.add(getInstructions(shiftOutput[1])); + methodInstructions.add(new InsnNode(Opcodes.ISHL)); + return methodInstructions; + } +// if (value == Integer.MIN_VALUE) { +// methodInstructions.add(NodeUtils.generateIntPush(Integer.MAX_VALUE)); +// methodInstructions.add(new InsnNode(Opcodes.ICONST_M1)); +// methodInstructions.add(new InsnNode(Opcodes.IXOR)); +// +// return methodInstructions; +// } +// if (value == Integer.MAX_VALUE) { +// methodInstructions.add(NodeUtils.generateIntPush(Integer.MIN_VALUE)); +// methodInstructions.add(new InsnNode(Opcodes.ICONST_M1)); +// methodInstructions.add(new InsnNode(Opcodes.IXOR)); +// +// return methodInstructions; +// } + int method; if (lenghtMode && (Math.abs(value) < 4 || (!xorMode && !simpleMathMode))) method = 0; else if (xorMode && (Math.abs(value) < Byte.MAX_VALUE || (!lenghtMode && !simpleMathMode))) method = 1; - else - method = 2; + else { + if (!INSTANCE.and.getObject() && Math.abs(value) > 0xFF) { + method = 3; + } else { + method = 2; + } + + } final boolean negative = value < 0; @@ -89,7 +136,7 @@ else if (xorMode && (Math.abs(value) < Byte.MAX_VALUE || (!lenghtMode && !simple methodInstructions.add(NodeUtils.generateIntPush(B)); methodInstructions.add(new InsnNode(Opcodes.IXOR)); break; - default: + case 2: /* * Generates a simple calculation e. 5 + 3 - 2 + 3 = 9 */ @@ -106,14 +153,39 @@ else if (xorMode && (Math.abs(value) < Byte.MAX_VALUE || (!lenghtMode && !simple methodInstructions.add(NodeUtils.generateIntPush(ADD_3)); methodInstructions.add(new InsnNode(Opcodes.IADD)); break; + case 3: + int[] and = splitToAnd(value); + methodInstructions.add(NodeUtils.generateIntPush(and[0])); + methodInstructions.add(NodeUtils.generateIntPush(and[1])); + methodInstructions.add(new InsnNode(Opcodes.IAND)); + break; } if (negative) methodInstructions.add(new InsnNode(Opcodes.INEG)); + return methodInstructions; } + private static int[] splitToAnd(int number) { + int number2 = random.nextInt(Short.MAX_VALUE) & ~number; + + return new int[]{~number2, number2 | number}; + } + + private static int[] splitToLShift(int number) { + int shift = 0; + + while ((number & ~0x7ffffffffffffffEL) == 0 && number != 0) { + number = number >> 1; + shift++; + } + return new int[]{number, shift}; + } + @Override - public void process(ClassNode node, int mode) { + public void process(ClassNode node) { + if (!enabled.getObject()) return; + int i = 0; String fieldName = NameUtils.generateFieldName(node.name); List integerList = new ArrayList<>(); @@ -133,7 +205,8 @@ public void process(ClassNode node, int mode) { // System.out.println(((LdcInsnNode) abstractInsnNode).cst + "/" + number); // } if (!Modifier.isInterface(node.access) - && mode == 1 +// && mode == 1 + && extractToArray.getObject() ) { int containedSlot = -1; int j = 0; @@ -181,7 +254,7 @@ public void process(ClassNode node, int mode) { for (int j = 0; j < i; j++) { toAdd.add(new FieldInsnNode(Opcodes.GETSTATIC, node.name, fieldName, "[I")); toAdd.add(NodeUtils.generateIntPush(j)); - toAdd.add(getInstructions(integerList.get(j))); + toAdd.add(getInstructionsMultipleTimes(integerList.get(j), random.nextInt(2) + 1)); toAdd.add(new InsnNode(Opcodes.IASTORE)); } diff --git a/src/main/java/me/superblaubeere27/jobf/processors/ReferenceProxy.java b/src/main/java/me/superblaubeere27/jobf/processors/ReferenceProxy.java index 7210e79..b964b86 100644 --- a/src/main/java/me/superblaubeere27/jobf/processors/ReferenceProxy.java +++ b/src/main/java/me/superblaubeere27/jobf/processors/ReferenceProxy.java @@ -2,6 +2,8 @@ import me.superblaubeere27.jobf.IClassProcessor; import me.superblaubeere27.jobf.JObfImpl; +import me.superblaubeere27.jobf.util.values.DeprecationLevel; +import me.superblaubeere27.jobf.util.values.EnabledValue; import me.superblaubeere27.jobf.utils.NameUtils; import me.superblaubeere27.jobf.utils.NodeUtils; import org.objectweb.asm.Label; @@ -20,13 +22,18 @@ public class ReferenceProxy implements IClassProcessor { private static Random random = new Random(); private JObfImpl inst; + private static final String PROCESSOR_NAME = "ReferenceProxy"; + + private EnabledValue enabled = new EnabledValue(PROCESSOR_NAME, DeprecationLevel.BAD, false); public ReferenceProxy(JObfImpl inst) { this.inst = inst; } @Override - public void process(ClassNode node, int mode) { + public void process(ClassNode node) { + if (!enabled.getObject()) return; + try { HashMap nodes = new HashMap<>(); List add = new ArrayList<>(); diff --git a/src/main/java/me/superblaubeere27/jobf/processors/SBProcessor.java b/src/main/java/me/superblaubeere27/jobf/processors/SBProcessor.java index c2d0170..09b059d 100644 --- a/src/main/java/me/superblaubeere27/jobf/processors/SBProcessor.java +++ b/src/main/java/me/superblaubeere27/jobf/processors/SBProcessor.java @@ -2,6 +2,8 @@ import me.superblaubeere27.jobf.IClassProcessor; import me.superblaubeere27.jobf.JObfImpl; +import me.superblaubeere27.jobf.util.values.DeprecationLevel; +import me.superblaubeere27.jobf.util.values.EnabledValue; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.FieldNode; @@ -12,13 +14,18 @@ public class SBProcessor implements IClassProcessor { private static Random random = new Random(); private JObfImpl inst; + private static final String PROCESSOR_NAME = "HideMembers"; + + private EnabledValue enabled = new EnabledValue(PROCESSOR_NAME, DeprecationLevel.GOOD, true); public SBProcessor(JObfImpl inst) { this.inst = inst; } @Override - public void process(ClassNode node, int mode) { + public void process(ClassNode node) { + if (!enabled.getObject()) return; + if ((node.access & Opcodes.ACC_INTERFACE) == 0) { for (MethodNode method : node.methods) { // if ((method.access & Opcodes.ACC_BRIDGE) == 0 && (method.access & Opcodes.ACC_STATIC) == 0 && !method.name.startsWith("<")) { diff --git a/src/main/java/me/superblaubeere27/jobf/processors/ShuffleMembersProcessor.java b/src/main/java/me/superblaubeere27/jobf/processors/ShuffleMembersProcessor.java index d05db00..01fc94d 100644 --- a/src/main/java/me/superblaubeere27/jobf/processors/ShuffleMembersProcessor.java +++ b/src/main/java/me/superblaubeere27/jobf/processors/ShuffleMembersProcessor.java @@ -2,6 +2,8 @@ import me.superblaubeere27.jobf.IClassProcessor; import me.superblaubeere27.jobf.JObfImpl; +import me.superblaubeere27.jobf.util.values.DeprecationLevel; +import me.superblaubeere27.jobf.util.values.EnabledValue; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.MethodNode; @@ -12,13 +14,18 @@ public class ShuffleMembersProcessor implements IClassProcessor { private static Random random = new Random(); private JObfImpl inst; + private static final String PROCESSOR_NAME = "ShuffleMembers"; + + private EnabledValue enabled = new EnabledValue(PROCESSOR_NAME, DeprecationLevel.GOOD, true); public ShuffleMembersProcessor(JObfImpl inst) { this.inst = inst; } @Override - public void process(ClassNode node, int mode) { + public void process(ClassNode node) { + if (!enabled.getObject()) return; + Collections.shuffle(node.methods, random); Collections.shuffle(node.fields, random); Collections.shuffle(node.innerClasses, random); diff --git a/src/main/java/me/superblaubeere27/jobf/processors/StaticInitializionProcessor.java b/src/main/java/me/superblaubeere27/jobf/processors/StaticInitializionProcessor.java index 5214dbe..7021de6 100644 --- a/src/main/java/me/superblaubeere27/jobf/processors/StaticInitializionProcessor.java +++ b/src/main/java/me/superblaubeere27/jobf/processors/StaticInitializionProcessor.java @@ -19,7 +19,7 @@ public StaticInitializionProcessor(JObfImpl inst) { } @Override - public void process(ClassNode node, int mode) { + public void process(ClassNode node) { HashMap objs = new HashMap<>(); for (FieldNode field : node.fields) { if (field.value != null) { diff --git a/src/main/java/me/superblaubeere27/jobf/processors/StringEncryptionProcessor.java b/src/main/java/me/superblaubeere27/jobf/processors/StringEncryptionProcessor.java index 08b1473..45f86dc 100644 --- a/src/main/java/me/superblaubeere27/jobf/processors/StringEncryptionProcessor.java +++ b/src/main/java/me/superblaubeere27/jobf/processors/StringEncryptionProcessor.java @@ -2,10 +2,10 @@ import me.superblaubeere27.jobf.IClassProcessor; import me.superblaubeere27.jobf.JObfImpl; -import me.superblaubeere27.jobf.processors.encryption.string.BlowfishEncryptionAlgorithm; -import me.superblaubeere27.jobf.processors.encryption.string.DESEncryptionAlgorithm; -import me.superblaubeere27.jobf.processors.encryption.string.IStringEncryptionAlgorithm; -import me.superblaubeere27.jobf.processors.encryption.string.XOREncryptionAlgorithm; +import me.superblaubeere27.jobf.processors.encryption.string.*; +import me.superblaubeere27.jobf.util.values.BooleanValue; +import me.superblaubeere27.jobf.util.values.DeprecationLevel; +import me.superblaubeere27.jobf.util.values.EnabledValue; import me.superblaubeere27.jobf.utils.NameUtils; import me.superblaubeere27.jobf.utils.NodeUtils; import me.superblaubeere27.jobf.utils.StringUtils; @@ -18,25 +18,35 @@ import java.util.*; public class StringEncryptionProcessor implements IClassProcessor { - private static final String MAGICNUMBER_START = "\u4590"; - private static final String MAGICNUMBER_SPLIT = "\u4591"; - private static final String MAGICNUMBER_END = "\u4592"; + public static final String MAGICNUMBER_START = "ä"; + private static final String MAGICNUMBER_SPLIT = "ö"; + private static final String MAGICNUMBER_END = "ü"; + private static final String PROCESSOR_NAME = "StringEncryption"; private static Random random = new Random(); private JObfImpl inst; private List algorithmList = new ArrayList<>(); + private EnabledValue enabled = new EnabledValue(PROCESSOR_NAME, DeprecationLevel.GOOD, true); + private BooleanValue hideStrings = new BooleanValue(PROCESSOR_NAME, "HideStrings", DeprecationLevel.GOOD, false); + private BooleanValue aes = new BooleanValue(PROCESSOR_NAME, "AES", DeprecationLevel.OK, false); public StringEncryptionProcessor(JObfImpl inst) { this.inst = inst; } private static void hideStrings(ClassNode cn, MethodNode... methods) { + cn.sourceFile = null; + cn.sourceDebug = null; String fieldName = NameUtils.generateFieldName(cn); HashMap hiddenStrings = new HashMap<>(); int slot = 0; int stringLength = 0; + int methodCount = 0; + MethodNode methodNode = null; + for (MethodNode method : methods) { + boolean hide = false; for (AbstractInsnNode abstractInsnNode : method.instructions.toArray()) { if (abstractInsnNode instanceof LdcInsnNode) { LdcInsnNode ldc = (LdcInsnNode) abstractInsnNode; @@ -54,10 +64,26 @@ private static void hideStrings(ClassNode cn, MethodNode... methods) { slot++; stringLength += ((String) ldc.cst).length() + 1; hiddenStrings.put(slot, (String) ldc.cst); + hide = true; } } } + if (hide) { + methodCount++; + methodNode = method; + } + } + + if (methodCount == 1) { + InsnList toAdd = new InsnList(); + toAdd.add(new InsnNode(Opcodes.ACONST_NULL)); + toAdd.add(new FieldInsnNode(Opcodes.PUTSTATIC, cn.name, fieldName, "[Ljava/lang/String;")); + + NodeUtils.insertOn(methodNode.instructions, insnNode -> insnNode.getOpcode() >= Opcodes.IRETURN && insnNode.getOpcode() <= Opcodes.RETURN, toAdd); + +// System.out.println("Win in " + cn.name); } + StringBuilder sb = new StringBuilder(MAGICNUMBER_START); for (String s : hiddenStrings.values()) { sb.append(s); @@ -114,17 +140,20 @@ private static void hideStrings(ClassNode cn, MethodNode... methods) { generateStrings.maxLocals = 4; // generateStrings.localVariables.add(new LocalVariableNode(NameUtils.generateLocalVariableName(), "Ljava/lang/String;", null, start, end, 1)); cn.methods.add(generateStrings); +// System.out.println("Added shit in " + cn.name); - clInit.instructions.insertBefore(clInit.instructions.getFirst(), new MethodInsnNode(Opcodes.INVOKESTATIC, cn.name, fieldName, "()V", false)); + clInit.instructions.insertBefore(clInit.instructions.getFirst(), NodeUtils.methodCall(cn, generateStrings)); +// System.out.println(generateStrings.name); } } @Override - public void process(ClassNode node, int mode) { - initAlgorithims(mode); + public void process(ClassNode node) { + if (!enabled.getObject()) return; + initAlgorithms(); - boolean hideStrings = mode == 1; + boolean hideStrings = this.hideStrings.getObject(); if (Modifier.isInterface(node.access)) return; @@ -247,16 +276,14 @@ public void process(ClassNode node, int mode) { inst.setWorkDone(); } - private void initAlgorithims(int mode) { + private void initAlgorithms() { algorithmList.clear(); algorithmList.add(new XOREncryptionAlgorithm()); algorithmList.add(new DESEncryptionAlgorithm()); algorithmList.add(new BlowfishEncryptionAlgorithm()); - if (mode == 1) { -// algorithmList.add(new AESEncryptionAlgorithm()); - } + if (aes.getObject()) algorithmList.add(new AESEncryptionAlgorithm()); } } \ No newline at end of file diff --git a/src/main/java/me/superblaubeere27/jobf/processors/encryption/string/XOREncryptionAlgorithm.java b/src/main/java/me/superblaubeere27/jobf/processors/encryption/string/XOREncryptionAlgorithm.java index 8a5c19d..e934ae0 100644 --- a/src/main/java/me/superblaubeere27/jobf/processors/encryption/string/XOREncryptionAlgorithm.java +++ b/src/main/java/me/superblaubeere27/jobf/processors/encryption/string/XOREncryptionAlgorithm.java @@ -1,8 +1,16 @@ package me.superblaubeere27.jobf.processors.encryption.string; +import java.io.UnsupportedEncodingException; +import java.util.Base64; + public class XOREncryptionAlgorithm implements IStringEncryptionAlgorithm { public static String decrypt(String obj, String key) { + try { + obj = new String(Base64.getDecoder().decode(obj.getBytes("UTF-8")), "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } StringBuilder sb = new StringBuilder(); char[] keyChars = key.toCharArray(); int i = 0; @@ -22,6 +30,11 @@ public String encrypt(String obj, String key) { sb.append((char) (c ^ keyChars[i % keyChars.length])); i++; } - return sb.toString(); + try { + return new String(Base64.getEncoder().encode(sb.toString().getBytes("UTF-8")), "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return ""; } } diff --git a/src/main/java/me/superblaubeere27/jobf/processors/packager/Packager.java b/src/main/java/me/superblaubeere27/jobf/processors/packager/Packager.java index e204a1e..93d0425 100644 --- a/src/main/java/me/superblaubeere27/jobf/processors/packager/Packager.java +++ b/src/main/java/me/superblaubeere27/jobf/processors/packager/Packager.java @@ -540,7 +540,7 @@ public byte[] generateEncryptionClass(String mainClass, int mode) { cw.visitEnd(); for (IClassProcessor processor : JObfImpl.processors) { - processor.process(cw, 0); + processor.process(cw); } ClassWriter writer = new ClassWriter(0); diff --git a/src/main/java/me/superblaubeere27/jobf/ui/GUI.form b/src/main/java/me/superblaubeere27/jobf/ui/GUI.form index f438074..6578f20 100644 --- a/src/main/java/me/superblaubeere27/jobf/ui/GUI.form +++ b/src/main/java/me/superblaubeere27/jobf/ui/GUI.form @@ -3,7 +3,7 @@ - + @@ -90,7 +90,7 @@ - + @@ -99,236 +99,14 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -389,16 +167,62 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + - + @@ -421,6 +245,15 @@ + + + + + + + + + diff --git a/src/main/java/me/superblaubeere27/jobf/ui/GUI.java b/src/main/java/me/superblaubeere27/jobf/ui/GUI.java index 302ed6f..38c0bad 100644 --- a/src/main/java/me/superblaubeere27/jobf/ui/GUI.java +++ b/src/main/java/me/superblaubeere27/jobf/ui/GUI.java @@ -1,22 +1,31 @@ package me.superblaubeere27.jobf.ui; -import com.google.gson.JsonParser; import com.intellij.uiDesigner.core.GridConstraints; import com.intellij.uiDesigner.core.GridLayoutManager; import com.intellij.uiDesigner.core.Spacer; -import me.superblaubeere27.jobf.Configuration; +import me.superblaubeere27.jobf.JObf; import me.superblaubeere27.jobf.JObfImpl; import me.superblaubeere27.jobf.util.JObfFileFilter; import me.superblaubeere27.jobf.util.JarFileFilter; import me.superblaubeere27.jobf.util.Util; +import me.superblaubeere27.jobf.util.script.JObfScript; +import me.superblaubeere27.jobf.util.values.*; +import me.superblaubeere27.jobf.utils.Template; +import me.superblaubeere27.jobf.utils.Templates; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.Theme; +import org.fife.ui.rtextarea.RTextScrollPane; import javax.swing.*; import java.awt.*; import java.io.File; import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; import java.nio.charset.Charset; import java.nio.file.Files; -import java.util.ResourceBundle; +import java.nio.file.Paths; +import java.util.*; public class GUI extends JFrame { public JTextArea logArea; @@ -27,32 +36,25 @@ public class GUI extends JFrame { private JTextField outputTextField; private JButton outputBrowseButton; private JButton obfuscateButton; - private JTabbedPane tabbedPane2; - private JCheckBox flowObfuscatorEnabled; - private JCheckBox informationRemoverEnabled; - private JCheckBox numberObfuscatorEnabled; - private JCheckBox hiderEnabled; - private JCheckBox shuffleMembersEnabled; - private JCheckBox staticinitializionProtectorEnabled; - private JCheckBox stringEncryptionEnabled; - private JButton lightButton; - private JButton mediumButton; - private JButton heavyButton; - private JButton aggressiveButton; private JButton buildButton; private JButton loadButton; private JButton saveButton; private JCheckBox prettyPrintCheckBox; private JTextArea configPanel; - private JCheckBox referenceProxyEnabled; + private JTabbedPane processorOptions; + private RSyntaxTextArea scriptArea; + private JList