From 1e5c034417cc32124d0c5649e280339bf0576ad0 Mon Sep 17 00:00:00 2001 From: iam2316361 Date: Thu, 27 Feb 2020 11:52:42 +0800 Subject: [PATCH] new! --- pom.xml | 58 +++++++++++++++++++ src/main/java/crack/AddConstFunction.java | 8 +++ src/main/java/crack/FineCrackAgent.java | 30 ++++++++++ src/main/java/crack/FineCrackInjector.java | 44 ++++++++++++++ .../crack/transformer/CrackTransformer.java | 43 ++++++++++++++ .../transformer/MultiMethodTransformer.java | 46 +++++++++++++++ .../transformer/SingleMethodTransformer.java | 42 ++++++++++++++ 7 files changed, 271 insertions(+) create mode 100644 pom.xml create mode 100644 src/main/java/crack/AddConstFunction.java create mode 100644 src/main/java/crack/FineCrackAgent.java create mode 100644 src/main/java/crack/FineCrackInjector.java create mode 100644 src/main/java/crack/transformer/CrackTransformer.java create mode 100644 src/main/java/crack/transformer/MultiMethodTransformer.java create mode 100644 src/main/java/crack/transformer/SingleMethodTransformer.java diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..ef84eb0 --- /dev/null +++ b/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + + org.example + FineCrack + 1.0-SNAPSHOT + + + UTF-8 + UTF-8 + 1.8 + 1.8 + 1.8 + + + + + org.javassist + javassist + 3.26.0-GA + + + + + FineCrack + + + org.apache.maven.plugins + maven-assembly-plugin + + + + crack.FineCrackInjector + crack.FineCrackAgent + true + true + + + + jar-with-dependencies + + + + + make-assembly + package + + single + + + + + + + \ No newline at end of file diff --git a/src/main/java/crack/AddConstFunction.java b/src/main/java/crack/AddConstFunction.java new file mode 100644 index 0000000..43f2d1d --- /dev/null +++ b/src/main/java/crack/AddConstFunction.java @@ -0,0 +1,8 @@ +package crack; + +import javassist.bytecode.ConstPool; + +@FunctionalInterface +public interface AddConstFunction { + void accept(ConstPool constPool); +} diff --git a/src/main/java/crack/FineCrackAgent.java b/src/main/java/crack/FineCrackAgent.java new file mode 100644 index 0000000..483c6be --- /dev/null +++ b/src/main/java/crack/FineCrackAgent.java @@ -0,0 +1,30 @@ +package crack; + +import crack.transformer.MultiMethodTransformer; +import crack.transformer.SingleMethodTransformer; + +import java.lang.instrument.Instrumentation; + +public class FineCrackAgent { + public static void agentmain(String args, Instrumentation inst) throws Exception { + Class[] classes = inst.getAllLoadedClasses(); + for (Class clazz : classes) { + String name = clazz.getName(); + if (name.equals("com.fr.license.selector.EncryptedLicenseSelector")) { + inst.addTransformer(new SingleMethodTransformer(name, "decrypt", 1, 2, new byte[]{43, -80}, null), true); + inst.retransformClasses(clazz); + System.out.println(name + " 替换完成!"); + } + if (name.equals("com.fr.license.security.LicFileRegistry")) { + inst.addTransformer(new SingleMethodTransformer(name, "check", 1, 2, new byte[]{4, -84}, null), true); + inst.retransformClasses(clazz); + System.out.println(name + " 替换完成!"); + } + if (name.equals("com.fr.license.entity.FineLicense")) { + inst.addTransformer(new MultiMethodTransformer(name, "support", 1, 2, new byte[]{4, -84}, null), true); + inst.retransformClasses(clazz); + System.out.println(name + " 替换完成!"); + } + } + } +} diff --git a/src/main/java/crack/FineCrackInjector.java b/src/main/java/crack/FineCrackInjector.java new file mode 100644 index 0000000..98efc61 --- /dev/null +++ b/src/main/java/crack/FineCrackInjector.java @@ -0,0 +1,44 @@ +package crack; + +import crack.transformer.SingleMethodTransformer; + +import java.io.File; +import java.lang.instrument.Instrumentation; + +public class FineCrackInjector { + + public static void premain(String agentArgs, Instrumentation inst) { + String path = FineCrackInjector.class.getProtectionDomain().getCodeSource().getLocation().getPath(); + File file = new File(path); + String finalPath = file.getAbsolutePath(); + byte[] codeTemplate = new byte[]{18, 29, -72, 0, 12, -74, 0, 30, -64, 0, 31, 75, 18, 11, 4, 42, -72, 0, 32, 87, -72, 0, 19, -71, 0, 33, 1, 0, 76, 43, 3, 43, 16, 64, -74, 0, 34, -74, 0, 35, 77, 44, -72, 0, 36, 78, 45, 18, 37, 1, -74, 0, 38, 45, -74, 0, 39, -79}; + inst.addTransformer(new SingleMethodTransformer("com.fr.runtime.FineRuntime", "initEncryptedBridge", 4, 4, codeTemplate, constPool -> { + int index = constPool.addClassInfo("java.lang.management.ManagementFactory"); + index = constPool.addMethodrefInfo(index, "getRuntimeMXBean", "()Ljava/lang/management/RuntimeMXBean;"); + codeTemplate[22] = (byte) index; + codeTemplate[21] = (byte) (index >>> 8); + index = constPool.addClassInfo("java.lang.management.RuntimeMXBean"); + index = constPool.addInterfaceMethodrefInfo(index, "getName", "()Ljava/lang/String;"); + codeTemplate[25] = (byte) index; + codeTemplate[24] = (byte) (index >>> 8); + index = constPool.addMethodrefInfo(92, "indexOf", "(I)I"); + codeTemplate[36] = (byte) index; + codeTemplate[35] = (byte) (index >>> 8); + index = constPool.addMethodrefInfo(92, "substring", "(II)Ljava/lang/String;"); + codeTemplate[39] = (byte) index; + codeTemplate[38] = (byte) (index >>> 8); + int virtualMachineIndex = constPool.addClassInfo("com.sun.tools.attach.VirtualMachine"); + index = constPool.addMethodrefInfo(virtualMachineIndex, "attach", "(Ljava/lang/String;)Lcom/sun/tools/attach/VirtualMachine;"); + codeTemplate[44] = (byte) index; + codeTemplate[43] = (byte) (index >>> 8); + index = constPool.addStringInfo(finalPath); + codeTemplate[48] = (byte) index; + index = constPool.addMethodrefInfo(virtualMachineIndex, "loadAgent", "(Ljava/lang/String;Ljava/lang/String;)V"); + codeTemplate[52] = (byte) index; + codeTemplate[51] = (byte) (index >>> 8); + index = constPool.addMethodrefInfo(virtualMachineIndex, "detach", "()V"); + codeTemplate[56] = (byte) index; + codeTemplate[55] = (byte) (index >>> 8); + })); + } +} diff --git a/src/main/java/crack/transformer/CrackTransformer.java b/src/main/java/crack/transformer/CrackTransformer.java new file mode 100644 index 0000000..29d7527 --- /dev/null +++ b/src/main/java/crack/transformer/CrackTransformer.java @@ -0,0 +1,43 @@ +package crack.transformer; + +import crack.AddConstFunction; + +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.IllegalClassFormatException; +import java.security.ProtectionDomain; + +public abstract class CrackTransformer implements ClassFileTransformer { + + protected String targetClassName; + protected String targetMethodName; + protected int stack; + protected int locals; + protected byte[] newCode; + protected AddConstFunction function; + + protected CrackTransformer(String targetClassName, String targetMethodName, int stack, int locals, byte[] newCode, AddConstFunction function) { + this.targetClassName = targetClassName.replace('.', '/'); + this.targetMethodName = targetMethodName; + this.stack = stack; + this.locals = locals; + this.newCode = newCode; + this.function = function; + } + + @Override + public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) { + if (className.equals(this.targetClassName)) { + try { + return this.modifyMethod(classfileBuffer, this.targetMethodName, this.stack, this.locals, this.newCode); + } catch (Exception e) { + e.printStackTrace(); + return classfileBuffer; + } + } else { + return classfileBuffer; + } + } + + protected abstract byte[] modifyMethod(byte[] classfileBuffer, String methodName, int stack, int locals, byte[] newCode) throws Exception; + +} diff --git a/src/main/java/crack/transformer/MultiMethodTransformer.java b/src/main/java/crack/transformer/MultiMethodTransformer.java new file mode 100644 index 0000000..b9f762d --- /dev/null +++ b/src/main/java/crack/transformer/MultiMethodTransformer.java @@ -0,0 +1,46 @@ +package crack.transformer; + +import crack.AddConstFunction; +import javassist.bytecode.ClassFile; +import javassist.bytecode.CodeAttribute; +import javassist.bytecode.ConstPool; +import javassist.bytecode.ExceptionTable; +import javassist.bytecode.MethodInfo; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.util.List; + +public class MultiMethodTransformer extends CrackTransformer { + + public MultiMethodTransformer(String targetClassName, String targetMethodName, int stack, int locals, byte[] newCode, AddConstFunction function) { + super(targetClassName, targetMethodName, stack, locals, newCode, function); + } + + @Override + protected byte[] modifyMethod(byte[] classfileBuffer, String methodName, int stack, int locals, byte[] newCode) throws Exception { + DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(classfileBuffer)); + ClassFile classFile = new ClassFile(inputStream); + inputStream.close(); + ConstPool constPool = classFile.getConstPool(); + if (this.function != null) { + this.function.accept(constPool); + } + CodeAttribute codeAttribute = new CodeAttribute(constPool, stack, locals, newCode, new ExceptionTable(constPool)); + List methodInfoList = classFile.getMethods(); + methodInfoList.forEach(methodInfo -> { + if (methodInfo.getName().equals(this.targetMethodName)) { + methodInfo.setCodeAttribute(codeAttribute); + } + }); + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + DataOutputStream outputStream = new DataOutputStream(byteArrayOutputStream); + classFile.write(outputStream); + outputStream.close(); + byte[] result = byteArrayOutputStream.toByteArray(); + byteArrayOutputStream.close(); + return result; + } +} diff --git a/src/main/java/crack/transformer/SingleMethodTransformer.java b/src/main/java/crack/transformer/SingleMethodTransformer.java new file mode 100644 index 0000000..2195fb7 --- /dev/null +++ b/src/main/java/crack/transformer/SingleMethodTransformer.java @@ -0,0 +1,42 @@ +package crack.transformer; + +import crack.AddConstFunction; +import javassist.bytecode.ClassFile; +import javassist.bytecode.CodeAttribute; +import javassist.bytecode.ConstPool; +import javassist.bytecode.ExceptionTable; +import javassist.bytecode.MethodInfo; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; + +public class SingleMethodTransformer extends CrackTransformer { + + public SingleMethodTransformer(String targetClassName, String targetMethodName, int stack, int locals, byte[] newCode, AddConstFunction function) { + super(targetClassName, targetMethodName, stack, locals, newCode, function); + } + + @Override + protected byte[] modifyMethod(byte[] classfileBuffer, String methodName, int stack, int locals, byte[] newCode) throws Exception { + DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(classfileBuffer)); + ClassFile classFile = new ClassFile(inputStream); + inputStream.close(); + ConstPool constPool = classFile.getConstPool(); + + if (this.function != null) { + this.function.accept(constPool); + } + MethodInfo methodInfo = classFile.getMethod(methodName); + CodeAttribute codeAttribute = new CodeAttribute(constPool, stack, locals, newCode, new ExceptionTable(constPool)); + methodInfo.setCodeAttribute(codeAttribute); + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + DataOutputStream outputStream = new DataOutputStream(byteArrayOutputStream); + classFile.write(outputStream); + outputStream.close(); + byte[] result = byteArrayOutputStream.toByteArray(); + byteArrayOutputStream.close(); + return result; + } +}