修复和优化了多个问题

This commit is contained in:
4ra1n
2025-02-26 15:41:23 +08:00
parent 9004901269
commit 9cd9c30a0f
16 changed files with 284 additions and 69 deletions

View File

@@ -1,5 +1,24 @@
# CHANGELOG
## 1.5.0
从该版本开始,运行混淆会自动创建一个 `class-obf-lib` 目录
用户如果遇到依赖报错,可以将混淆 `class` 需要的依赖 `jar` 放入该目录解决报错问题
更新日志:
- [重要] 解决某些情况下需要正确依赖才能运行的 `BUG`
- [优化] 生成 `AES` 字符串解密方法时避免抛出异常
- [优化] 提高解密方法内的 `Basse64` 解码兼容性
感谢以下用户的贡献:
- 4ra1n (https://github.com/4ra1n)
- lz520520 (https://github.com/lz520520)
可供下载的文件都由 `Github Actions` 构建,使用 `java -jar class-obf.jar` 启动
## 1.4.0
支持将 `INVOKE*` 指令转为反射调用,结合其他配置可完成进阶混淆

View File

@@ -33,6 +33,10 @@
![](img/008.png)
`1.5.0` 版本解决了缺少依赖的问题,如果你混淆时遇到报错找不到某些依赖类:
请将依赖的 `jar` 文件都放在当前目录下的 `class-obf-lib` 目录(会自动生成)
## 背景
`jar-analyzer` 系列曾有一款工具 `jar-obfuscator` 实现 `jar` 包的混淆

5
class-obf-lib/README.md Normal file
View File

@@ -0,0 +1,5 @@
# README
一些情况下混淆可能需要接触依赖库
请将依赖放在 `class-obf-lib` 目录中

View File

@@ -7,6 +7,7 @@ import me.n1ar4.clazz.obfuscator.base.ClassReference;
import me.n1ar4.clazz.obfuscator.base.MethodReference;
import me.n1ar4.clazz.obfuscator.config.BaseCmd;
import me.n1ar4.clazz.obfuscator.config.BaseConfig;
import me.n1ar4.clazz.obfuscator.loader.CustomClassLoader;
import me.n1ar4.clazz.obfuscator.transform.*;
import me.n1ar4.clazz.obfuscator.utils.ASMUtil;
import me.n1ar4.clazz.obfuscator.utils.ColorUtil;
@@ -16,6 +17,7 @@ import me.n1ar4.log.LogManager;
import me.n1ar4.log.Logger;
import org.objectweb.asm.ClassReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -55,6 +57,19 @@ public class Runner {
throw new RuntimeException(ex);
}
Path dirPath = Paths.get(CustomClassLoader.LIB_DIR);
try {
Files.createDirectory(dirPath);
logger.info("已成功创建 {} 目录", CustomClassLoader.LIB_DIR);
Files.write(dirPath.resolve(Paths.get("README.md")), ("# README\n" +
"\n" +
"一些情况下混淆可能需要接触依赖库\n" +
"\n" +
"请将依赖放在 `class-obf-lib` 目录中").getBytes(StandardCharsets.UTF_8));
} catch (Exception ignored) {
logger.warn("无法创建 {} 目录", CustomClassLoader.LIB_DIR);
}
addClass(path);
logger.info("add the input class to analyze");
@@ -201,51 +216,53 @@ public class Runner {
ColorUtil.blue("#################################################################"));
}
CustomClassLoader loader = new CustomClassLoader();
if (config.isEnableReflect()) {
ReflectTransformer.transform();
ReflectTransformer.transform(loader);
logger.info("run reflect transformer finish");
}
if (config.isEnableDeleteCompileInfo()) {
DeleteInfoTransformer.transform();
DeleteInfoTransformer.transform(loader);
logger.info("run delete info transformer finish");
}
if (config.isEnableMethodName()) {
MethodNameTransformer.transform();
MethodNameTransformer.transform(loader);
logger.info("run method name transformer finish");
}
if (config.isEnableFieldName()) {
FieldNameTransformer.transform();
FieldNameTransformer.transform(loader);
logger.info("run field name transformer finish");
}
if (config.isEnableParamName()) {
ParameterTransformer.transform();
ParameterTransformer.transform(loader);
logger.info("run parameter transformer finish");
}
if (config.isEnableXOR()) {
XORTransformer.transform();
XORTransformer.transform(loader);
logger.info("run xor transformer finish");
}
if (config.isEnableAdvanceString()) {
StringArrayTransformer.transform();
StringArrayTransformer.transform(loader);
if (config.isEnableXOR()) {
XORTransformer.transform();
XORTransformer.transform(loader);
}
logger.info("run string array transformer finish");
}
if (config.isEnableAES()) {
StringEncryptTransformer.transform(config.getAesKey(), config.getAesDecName());
StringEncryptTransformer.transform(config.getAesKey(), config.getAesDecName(), loader);
logger.info("run string aes transformer finish");
}
if (config.isEnableJunk()) {
JunkCodeTransformer.transform(config);
JunkCodeTransformer.transform(config, loader);
logger.info("run junk transformer finish");
}
if (!config.isQuiet()) {

View File

@@ -1,24 +1,64 @@
package me.n1ar4.clazz.obfuscator.loader;
import me.n1ar4.clazz.obfuscator.Const;
import me.n1ar4.log.LogManager;
import me.n1ar4.log.Logger;
import java.nio.file.Files;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class CustomClassLoader extends ClassLoader {
private static final Logger logger = LogManager.getLogger();
public static final String LIB_DIR = "class-obf-lib";
@Override
public Class<?> findClass(String name) {
byte[] b = loadClassData();
if (b != null) {
return defineClass(name, b, 0, b.length);
byte[] classData = loadClassData(name);
if (classData != null) {
return defineClass(name, classData, 0, classData.length);
}
logger.warn("not found class: " + name);
return null;
}
private byte[] loadClassData() {
try {
return Files.readAllBytes(Const.TEMP_PATH);
} catch (Exception ignored) {
private byte[] loadClassData(String className) {
File libDir = new File(LIB_DIR);
if (!libDir.exists() || !libDir.isDirectory()) {
return null;
}
File[] jarFiles = libDir.listFiles((dir, name) -> name.endsWith(".jar"));
if (jarFiles == null) {
return null;
}
for (File jarFile : jarFiles) {
try (JarFile jar = new JarFile(jarFile)) {
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
if (entry.getName().endsWith(".class")) {
String entryClassName = entry.getName().replace("/", ".")
.replace(".class", "");
if (entryClassName.equals(className)) {
try (InputStream inputStream = jar.getInputStream(entry);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
return outputStream.toByteArray();
}
}
}
}
} catch (IOException e) {
logger.error("load class error: {}", e.getMessage());
}
}
return null;
}
}
}

View File

@@ -3,6 +3,8 @@ package me.n1ar4.clazz.obfuscator.transform;
import me.n1ar4.clazz.obfuscator.Const;
import me.n1ar4.clazz.obfuscator.asm.CompileInfoClassVisitor;
import me.n1ar4.clazz.obfuscator.core.ObfEnv;
import me.n1ar4.clazz.obfuscator.loader.CustomClassLoader;
import me.n1ar4.clazz.obfuscator.loader.CustomClassWriter;
import me.n1ar4.log.LogManager;
import me.n1ar4.log.Logger;
import org.objectweb.asm.ClassReader;
@@ -14,7 +16,7 @@ import java.nio.file.Path;
public class DeleteInfoTransformer {
private static final Logger logger = LogManager.getLogger();
public static void transform() {
public static void transform(CustomClassLoader loader) {
Path classPath = Const.TEMP_PATH;
if (!Files.exists(classPath)) {
logger.error("class not exist: {}", classPath.toString());
@@ -22,8 +24,8 @@ public class DeleteInfoTransformer {
}
try {
ClassReader classReader = new ClassReader(Files.readAllBytes(classPath));
ClassWriter classWriter = new ClassWriter(classReader,
ObfEnv.config.isAsmAutoCompute() ? Const.WriterASMOptions : 0);
ClassWriter classWriter = new CustomClassWriter(classReader,
ObfEnv.config.isAsmAutoCompute() ? Const.WriterASMOptions : 0, loader);
CompileInfoClassVisitor changer = new CompileInfoClassVisitor(classWriter);
classReader.accept(changer, Const.ReaderASMOptions);
Files.delete(classPath);

View File

@@ -3,6 +3,8 @@ package me.n1ar4.clazz.obfuscator.transform;
import me.n1ar4.clazz.obfuscator.Const;
import me.n1ar4.clazz.obfuscator.asm.FieldNameClassVisitor;
import me.n1ar4.clazz.obfuscator.core.ObfEnv;
import me.n1ar4.clazz.obfuscator.loader.CustomClassLoader;
import me.n1ar4.clazz.obfuscator.loader.CustomClassWriter;
import me.n1ar4.log.LogManager;
import me.n1ar4.log.Logger;
import org.objectweb.asm.ClassReader;
@@ -15,7 +17,7 @@ import java.nio.file.Path;
public class FieldNameTransformer {
private static final Logger logger = LogManager.getLogger();
public static void transform() {
public static void transform(CustomClassLoader loader) {
Path newClassPath = Const.TEMP_PATH;
if (!Files.exists(newClassPath)) {
logger.error("class not exist: {}", newClassPath.toString());
@@ -23,8 +25,8 @@ public class FieldNameTransformer {
}
try {
ClassReader classReader = new ClassReader(Files.readAllBytes(newClassPath));
ClassWriter classWriter = new ClassWriter(classReader,
ObfEnv.config.isAsmAutoCompute() ? Const.WriterASMOptions : 0);
ClassWriter classWriter = new CustomClassWriter(classReader,
ObfEnv.config.isAsmAutoCompute() ? Const.WriterASMOptions : 0, loader);
FieldNameClassVisitor changer = new FieldNameClassVisitor(classWriter);
classReader.accept(changer, Const.ReaderASMOptions);
Files.delete(newClassPath);

View File

@@ -19,7 +19,7 @@ import java.nio.file.Path;
public class JunkCodeTransformer {
private static final Logger logger = LogManager.getLogger();
public static void transform(BaseConfig config) {
public static void transform(BaseConfig config, CustomClassLoader loader) {
Path newClassPath = Const.TEMP_PATH;
if (!Files.exists(newClassPath)) {
logger.error("class not exist: {}", newClassPath.toString());
@@ -27,8 +27,6 @@ public class JunkCodeTransformer {
}
try {
ClassReader classReader = new ClassReader(Files.readAllBytes(newClassPath));
CustomClassLoader loader = new CustomClassLoader();
// COMPUTE_FRAMES 需要修改 CLASSLOADER 来计算
ClassWriter classWriter = new CustomClassWriter(classReader,
ObfEnv.config.isAsmAutoCompute() ? Const.WriterASMOptions : 0, loader);
JunkCodeClassVisitor changer = new JunkCodeClassVisitor(classWriter, config);

View File

@@ -3,6 +3,8 @@ package me.n1ar4.clazz.obfuscator.transform;
import me.n1ar4.clazz.obfuscator.Const;
import me.n1ar4.clazz.obfuscator.asm.MethodNameClassVisitor;
import me.n1ar4.clazz.obfuscator.core.ObfEnv;
import me.n1ar4.clazz.obfuscator.loader.CustomClassLoader;
import me.n1ar4.clazz.obfuscator.loader.CustomClassWriter;
import me.n1ar4.log.LogManager;
import me.n1ar4.log.Logger;
import org.objectweb.asm.ClassReader;
@@ -15,7 +17,7 @@ import java.nio.file.Path;
public class MethodNameTransformer {
private static final Logger logger = LogManager.getLogger();
public static void transform() {
public static void transform(CustomClassLoader loader) {
Path newClassPath = Const.TEMP_PATH;
if (!Files.exists(newClassPath)) {
logger.error("class not exist: {}", newClassPath.toString());
@@ -23,8 +25,8 @@ public class MethodNameTransformer {
}
try {
ClassReader classReader = new ClassReader(Files.readAllBytes(newClassPath));
ClassWriter classWriter = new ClassWriter(classReader,
ObfEnv.config.isAsmAutoCompute() ? Const.WriterASMOptions : 0);
ClassWriter classWriter = new CustomClassWriter(classReader,
ObfEnv.config.isAsmAutoCompute() ? Const.WriterASMOptions : 0, loader);
MethodNameClassVisitor changer = new MethodNameClassVisitor(classWriter);
classReader.accept(changer, Const.ReaderASMOptions);
Files.delete(newClassPath);

View File

@@ -3,6 +3,8 @@ package me.n1ar4.clazz.obfuscator.transform;
import me.n1ar4.clazz.obfuscator.Const;
import me.n1ar4.clazz.obfuscator.asm.ParameterClassVisitor;
import me.n1ar4.clazz.obfuscator.core.ObfEnv;
import me.n1ar4.clazz.obfuscator.loader.CustomClassLoader;
import me.n1ar4.clazz.obfuscator.loader.CustomClassWriter;
import me.n1ar4.log.LogManager;
import me.n1ar4.log.Logger;
import org.objectweb.asm.ClassReader;
@@ -15,7 +17,7 @@ import java.nio.file.Path;
public class ParameterTransformer {
private static final Logger logger = LogManager.getLogger();
public static void transform() {
public static void transform(CustomClassLoader loader) {
Path newClassPath = Const.TEMP_PATH;
if (!Files.exists(newClassPath)) {
logger.error("class not exist: {}", newClassPath.toString());
@@ -23,8 +25,8 @@ public class ParameterTransformer {
}
try {
ClassReader classReader = new ClassReader(Files.readAllBytes(newClassPath));
ClassWriter classWriter = new ClassWriter(classReader,
ObfEnv.config.isAsmAutoCompute() ? Const.WriterASMOptions : 0);
ClassWriter classWriter = new CustomClassWriter(classReader,
ObfEnv.config.isAsmAutoCompute() ? Const.WriterASMOptions : 0, loader);
ParameterClassVisitor changer = new ParameterClassVisitor(classWriter);
classReader.accept(changer, Const.ReaderASMOptions);
Files.delete(newClassPath);

View File

@@ -3,6 +3,8 @@ package me.n1ar4.clazz.obfuscator.transform;
import me.n1ar4.clazz.obfuscator.Const;
import me.n1ar4.clazz.obfuscator.asm.ReflectClassVisitor;
import me.n1ar4.clazz.obfuscator.core.ObfEnv;
import me.n1ar4.clazz.obfuscator.loader.CustomClassLoader;
import me.n1ar4.clazz.obfuscator.loader.CustomClassWriter;
import me.n1ar4.log.LogManager;
import me.n1ar4.log.Logger;
import org.objectweb.asm.ClassReader;
@@ -14,7 +16,7 @@ import java.nio.file.Path;
public class ReflectTransformer {
private static final Logger logger = LogManager.getLogger();
public static void transform() {
public static void transform(CustomClassLoader loader) {
Path classPath = Const.TEMP_PATH;
if (!Files.exists(classPath)) {
logger.error("class not exist: {}", classPath.toString());
@@ -22,8 +24,8 @@ public class ReflectTransformer {
}
try {
ClassReader classReader = new ClassReader(Files.readAllBytes(classPath));
ClassWriter classWriter = new ClassWriter(classReader,
ObfEnv.config.isAsmAutoCompute() ? Const.WriterASMOptions : 0);
ClassWriter classWriter = new CustomClassWriter(classReader,
ObfEnv.config.isAsmAutoCompute() ? Const.WriterASMOptions : 0, loader);
ReflectClassVisitor changer = new ReflectClassVisitor(classWriter);
classReader.accept(changer, Const.ReaderASMOptions);
Files.delete(classPath);

View File

@@ -3,6 +3,8 @@ package me.n1ar4.clazz.obfuscator.transform;
import me.n1ar4.clazz.obfuscator.Const;
import me.n1ar4.clazz.obfuscator.asm.StringArrayClassVisitor;
import me.n1ar4.clazz.obfuscator.core.ObfEnv;
import me.n1ar4.clazz.obfuscator.loader.CustomClassLoader;
import me.n1ar4.clazz.obfuscator.loader.CustomClassWriter;
import me.n1ar4.log.LogManager;
import me.n1ar4.log.Logger;
import org.objectweb.asm.ClassReader;
@@ -16,7 +18,7 @@ public class StringArrayTransformer {
private static final Logger logger = LogManager.getLogger();
public static int INDEX = 0;
public static void transform() {
public static void transform(CustomClassLoader loader) {
Path newClassPath = Const.TEMP_PATH;
if (!Files.exists(newClassPath)) {
logger.error("class not exist: {}", newClassPath.toString());
@@ -25,8 +27,8 @@ public class StringArrayTransformer {
try {
INDEX = 0;
ClassReader classReader = new ClassReader(Files.readAllBytes(newClassPath));
ClassWriter classWriter = new ClassWriter(classReader,
ObfEnv.config.isAsmAutoCompute() ? Const.WriterASMOptions : 0);
ClassWriter classWriter = new CustomClassWriter(classReader,
ObfEnv.config.isAsmAutoCompute() ? Const.WriterASMOptions : 0, loader);
StringArrayClassVisitor changer = new StringArrayClassVisitor(classWriter);
classReader.accept(changer, Const.ReaderASMOptions);
Files.delete(newClassPath);

View File

@@ -3,6 +3,8 @@ package me.n1ar4.clazz.obfuscator.transform;
import me.n1ar4.clazz.obfuscator.Const;
import me.n1ar4.clazz.obfuscator.asm.StringEncryptClassVisitor;
import me.n1ar4.clazz.obfuscator.core.ObfEnv;
import me.n1ar4.clazz.obfuscator.loader.CustomClassLoader;
import me.n1ar4.clazz.obfuscator.loader.CustomClassWriter;
import me.n1ar4.log.LogManager;
import me.n1ar4.log.Logger;
import org.objectweb.asm.ClassReader;
@@ -15,7 +17,7 @@ import java.nio.file.Path;
public class StringEncryptTransformer {
private static final Logger logger = LogManager.getLogger();
public static void transform(String aesKey, String aesDecName) {
public static void transform(String aesKey, String aesDecName, CustomClassLoader loader) {
Path newClassPath = Const.TEMP_PATH;
if (!Files.exists(newClassPath)) {
logger.error("class not exist: {}", newClassPath.toString());
@@ -23,13 +25,14 @@ public class StringEncryptTransformer {
}
try {
ClassReader classReader = new ClassReader(Files.readAllBytes(newClassPath));
ClassWriter classWriter = new ClassWriter(classReader,
ObfEnv.config.isAsmAutoCompute() ? Const.WriterASMOptions : 0);
ClassWriter classWriter = new CustomClassWriter(classReader,
ObfEnv.config.isAsmAutoCompute() ? Const.WriterASMOptions : 0, loader);
StringEncryptClassVisitor changer = new StringEncryptClassVisitor(classWriter, aesKey, aesDecName);
classReader.accept(changer, Const.ReaderASMOptions);
Files.delete(newClassPath);
Files.write(newClassPath, classWriter.toByteArray());
} catch (Exception ex) {
ex.printStackTrace();
logger.error("transform error: {}", ex.toString());
}
}

View File

@@ -3,6 +3,8 @@ package me.n1ar4.clazz.obfuscator.transform;
import me.n1ar4.clazz.obfuscator.Const;
import me.n1ar4.clazz.obfuscator.asm.IntToXorClassVisitor;
import me.n1ar4.clazz.obfuscator.core.ObfEnv;
import me.n1ar4.clazz.obfuscator.loader.CustomClassLoader;
import me.n1ar4.clazz.obfuscator.loader.CustomClassWriter;
import me.n1ar4.log.LogManager;
import me.n1ar4.log.Logger;
import org.objectweb.asm.ClassReader;
@@ -15,7 +17,7 @@ import java.nio.file.Path;
public class XORTransformer {
private static final Logger logger = LogManager.getLogger();
public static void transform() {
public static void transform(ClassLoader loader) {
Path newClassPath = Const.TEMP_PATH;
if (!Files.exists(newClassPath)) {
logger.error("class not exist: {}", newClassPath.toString());
@@ -23,8 +25,8 @@ public class XORTransformer {
}
try {
ClassReader classReader = new ClassReader(Files.readAllBytes(newClassPath));
ClassWriter classWriter = new ClassWriter(classReader,
ObfEnv.config.isAsmAutoCompute() ? Const.WriterASMOptions : 0);
ClassWriter classWriter = new CustomClassWriter(classReader,
ObfEnv.config.isAsmAutoCompute() ? Const.WriterASMOptions : 0, loader);
IntToXorClassVisitor changer = new IntToXorClassVisitor(classWriter);
classReader.accept(changer, Const.ReaderASMOptions);
Files.delete(newClassPath);

View File

@@ -1,18 +1,30 @@
package me.n1ar4.clazz.obfuscator.utils;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.*;
import static org.objectweb.asm.Opcodes.*;
public class AESUtil {
public static void addAesDecodeCode(ClassVisitor cv, String aesDecName) {
MethodVisitor methodVisitor = cv.visitMethod(
ACC_PUBLIC | ACC_STATIC,
aesDecName,
"(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
null, new String[]{"java/lang/Exception"});
MethodVisitor methodVisitor = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, aesDecName,
"(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", null, null);
methodVisitor.visitCode();
Label label0 = new Label();
Label label1 = new Label();
Label label2 = new Label();
methodVisitor.visitTryCatchBlock(label0, label1, label2, "java/lang/Exception");
Label label3 = new Label();
Label label4 = new Label();
Label label5 = new Label();
methodVisitor.visitTryCatchBlock(label3, label4, label5, "java/lang/Exception");
Label label6 = new Label();
Label label7 = new Label();
Label label8 = new Label();
methodVisitor.visitTryCatchBlock(label6, label7, label8, "java/lang/Exception");
Label label9 = new Label();
Label label10 = new Label();
methodVisitor.visitTryCatchBlock(label9, label10, label8, "java/lang/Exception");
methodVisitor.visitLabel(label6);
methodVisitor.visitTypeInsn(NEW, "java/lang/StringBuilder");
methodVisitor.visitInsn(DUP);
methodVisitor.visitVarInsn(ALOAD, 1);
@@ -41,18 +53,100 @@ public class AESUtil {
methodVisitor.visitInsn(ICONST_2);
methodVisitor.visitVarInsn(ALOAD, 2);
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "javax/crypto/Cipher", "init", "(ILjava/security/Key;)V", false);
methodVisitor.visitVarInsn(ALOAD, 3);
methodVisitor.visitMethodInsn(INVOKESTATIC, "java/util/Base64", "getDecoder", "()Ljava/util/Base64$Decoder;", false);
methodVisitor.visitVarInsn(ALOAD, 0);
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/util/Base64$Decoder", "decode", "(Ljava/lang/String;)[B", false);
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "javax/crypto/Cipher", "doFinal", "([B)[B", false);
methodVisitor.visitInsn(ACONST_NULL);
methodVisitor.visitVarInsn(ASTORE, 5);
methodVisitor.visitLabel(label0);
methodVisitor.visitLdcInsn("java.util.Base64");
methodVisitor.visitMethodInsn(INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false);
methodVisitor.visitVarInsn(ASTORE, 4);
methodVisitor.visitVarInsn(ALOAD, 4);
methodVisitor.visitLdcInsn("getDecoder");
methodVisitor.visitInsn(ACONST_NULL);
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", false);
methodVisitor.visitVarInsn(ALOAD, 4);
methodVisitor.visitInsn(ACONST_NULL);
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Method", "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", false);
methodVisitor.visitVarInsn(ASTORE, 6);
methodVisitor.visitVarInsn(ALOAD, 6);
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
methodVisitor.visitLdcInsn("decode");
methodVisitor.visitInsn(ICONST_1);
methodVisitor.visitTypeInsn(ANEWARRAY, "java/lang/Class");
methodVisitor.visitInsn(DUP);
methodVisitor.visitInsn(ICONST_0);
methodVisitor.visitLdcInsn(Type.getType(String.class));
methodVisitor.visitInsn(AASTORE);
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", false);
methodVisitor.visitVarInsn(ALOAD, 6);
methodVisitor.visitInsn(ICONST_1);
methodVisitor.visitTypeInsn(ANEWARRAY, "java/lang/Object");
methodVisitor.visitInsn(DUP);
methodVisitor.visitInsn(ICONST_0);
methodVisitor.visitVarInsn(ALOAD, 0);
methodVisitor.visitInsn(AASTORE);
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Method", "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", false);
methodVisitor.visitTypeInsn(CHECKCAST, "[B");
methodVisitor.visitTypeInsn(CHECKCAST, "[B");
methodVisitor.visitVarInsn(ASTORE, 5);
methodVisitor.visitLabel(label1);
methodVisitor.visitJumpInsn(GOTO, label9);
methodVisitor.visitLabel(label2);
methodVisitor.visitFrame(Opcodes.F_FULL, 6, new Object[]{"java/lang/String", "java/lang/String", "javax/crypto/spec/SecretKeySpec", "javax/crypto/Cipher", Opcodes.TOP, "[B"}, 1, new Object[]{"java/lang/Exception"});
methodVisitor.visitVarInsn(ASTORE, 6);
methodVisitor.visitLabel(label3);
methodVisitor.visitLdcInsn("sun.misc.BASE64Decoder");
methodVisitor.visitMethodInsn(INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false);
methodVisitor.visitVarInsn(ASTORE, 4);
methodVisitor.visitVarInsn(ALOAD, 4);
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "newInstance", "()Ljava/lang/Object;", false);
methodVisitor.visitVarInsn(ASTORE, 7);
methodVisitor.visitVarInsn(ALOAD, 7);
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
methodVisitor.visitLdcInsn("decodeBuffer");
methodVisitor.visitInsn(ICONST_1);
methodVisitor.visitTypeInsn(ANEWARRAY, "java/lang/Class");
methodVisitor.visitInsn(DUP);
methodVisitor.visitInsn(ICONST_0);
methodVisitor.visitLdcInsn(Type.getType(String.class));
methodVisitor.visitInsn(AASTORE);
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", false);
methodVisitor.visitVarInsn(ALOAD, 7);
methodVisitor.visitInsn(ICONST_1);
methodVisitor.visitTypeInsn(ANEWARRAY, "java/lang/Object");
methodVisitor.visitInsn(DUP);
methodVisitor.visitInsn(ICONST_0);
methodVisitor.visitVarInsn(ALOAD, 0);
methodVisitor.visitInsn(AASTORE);
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Method", "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", false);
methodVisitor.visitTypeInsn(CHECKCAST, "[B");
methodVisitor.visitTypeInsn(CHECKCAST, "[B");
methodVisitor.visitVarInsn(ASTORE, 5);
methodVisitor.visitLabel(label4);
methodVisitor.visitJumpInsn(GOTO, label9);
methodVisitor.visitLabel(label5);
methodVisitor.visitFrame(Opcodes.F_FULL, 7, new Object[]{"java/lang/String", "java/lang/String", "javax/crypto/spec/SecretKeySpec", "javax/crypto/Cipher", Opcodes.TOP, "[B", "java/lang/Exception"}, 1, new Object[]{"java/lang/Exception"});
methodVisitor.visitVarInsn(ASTORE, 7);
methodVisitor.visitLdcInsn("");
methodVisitor.visitLabel(label7);
methodVisitor.visitInsn(ARETURN);
methodVisitor.visitLabel(label9);
methodVisitor.visitFrame(Opcodes.F_FULL, 6, new Object[]{"java/lang/String", "java/lang/String", "javax/crypto/spec/SecretKeySpec", "javax/crypto/Cipher", "java/lang/Class", "[B"}, 0, new Object[]{});
methodVisitor.visitVarInsn(ALOAD, 3);
methodVisitor.visitVarInsn(ALOAD, 5);
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "javax/crypto/Cipher", "doFinal", "([B)[B", false);
methodVisitor.visitVarInsn(ASTORE, 6);
methodVisitor.visitTypeInsn(NEW, "java/lang/String");
methodVisitor.visitInsn(DUP);
methodVisitor.visitVarInsn(ALOAD, 4);
methodVisitor.visitVarInsn(ALOAD, 6);
methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/String", "<init>", "([B)V", false);
methodVisitor.visitLabel(label10);
methodVisitor.visitInsn(ARETURN);
methodVisitor.visitMaxs(4, 5);
methodVisitor.visitLabel(label8);
methodVisitor.visitFrame(Opcodes.F_FULL, 2, new Object[]{"java/lang/String", "java/lang/String"}, 1, new Object[]{"java/lang/Exception"});
methodVisitor.visitVarInsn(ASTORE, 2);
methodVisitor.visitLdcInsn("");
methodVisitor.visitInsn(ARETURN);
methodVisitor.visitMaxs(6, 8);
methodVisitor.visitEnd();
}
}

View File

@@ -17,14 +17,35 @@ public class AESTemplates {
return new StringBuilder(base).reverse().toString();
}
public static String decrypt(String encryptedData, String key) throws Exception {
key = new StringBuilder(key).reverse().toString();
encryptedData = new StringBuilder(encryptedData).reverse().toString();
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
return new String(decryptedBytes);
public static String decrypt(String encryptedData, String key) {
try {
key = new StringBuilder(key).reverse().toString();
encryptedData = new StringBuilder(encryptedData).reverse().toString();
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
Class<?> base64;
byte[] value = null;
try {
base64 = Class.forName("java.util.Base64");
Object decoder = base64.getMethod("getDecoder", null).invoke(base64, null);
value = (byte[]) decoder.getClass().getMethod("decode",
new Class[]{String.class}).invoke(decoder, new Object[]{encryptedData});
} catch (Exception e) {
try {
base64 = Class.forName("sun.misc.BASE64Decoder");
Object decoder = base64.newInstance();
value = (byte[]) decoder.getClass().getMethod("decodeBuffer",
new Class[]{String.class}).invoke(decoder, new Object[]{encryptedData});
} catch (Exception ex) {
return "";
}
}
byte[] decryptedBytes = cipher.doFinal(value);
return new String(decryptedBytes);
} catch (Exception ignored) {
return "";
}
}
public static void main(String[] args) {