[功能] 支持 --std-output 参数输出到包名对应的完整路径

This commit is contained in:
4ra1n
2025-01-02 22:59:53 +08:00
parent 1e9b8e7102
commit b567f3ae16
6 changed files with 82 additions and 14 deletions

View File

@@ -1,10 +1,10 @@
# CHANGELOG
## 1.4.0
## 1.3.2
更新日志:
- todo
- [功能] 支持 `--std-output` 参数输出到包名对应的完整路径
感谢以下用户的贡献:

View File

@@ -67,6 +67,6 @@ public class Main {
}
logger.info("start class obfuscate");
Runner.run(path, config);
Runner.run(path, config, false, baseCmd);
}
}

View File

@@ -63,7 +63,7 @@ public class ClassObf {
try {
clean();
Manager.initConfig(this.config);
Runner.run(path, this.config);
Runner.run(path, this.config, true, null);
String fileName = FileUtil.getFileNameWithoutExt(path);
String newFile = fileName + "_obf.class";
Path newFilePath = Paths.get(newFile);

View File

@@ -12,6 +12,8 @@ public class BaseCmd {
private boolean generate;
@Parameter(names = {"-v", "--version"}, description = "version")
private boolean version;
@Parameter(names = {"--std-output"}, description = "standard output (export file to package dir)")
private boolean stdOutput;
public boolean isVersion() {
return version;
@@ -44,4 +46,12 @@ public class BaseCmd {
public void setConfig(String config) {
this.config = config;
}
public boolean isStdOutput() {
return stdOutput;
}
public void setStdOutput(boolean stdOutput) {
this.stdOutput = stdOutput;
}
}

View File

@@ -5,13 +5,16 @@ import me.n1ar4.clazz.obfuscator.base.ClassField;
import me.n1ar4.clazz.obfuscator.base.ClassFileEntity;
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.transform.*;
import me.n1ar4.clazz.obfuscator.utils.ASMUtil;
import me.n1ar4.clazz.obfuscator.utils.ColorUtil;
import me.n1ar4.clazz.obfuscator.utils.FileUtil;
import me.n1ar4.clazz.obfuscator.utils.NameUtil;
import me.n1ar4.log.LogManager;
import me.n1ar4.log.Logger;
import org.objectweb.asm.ClassReader;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -32,7 +35,7 @@ public class Runner {
AnalyzeEnv.classFileList.add(cf);
}
public static void run(Path path, BaseConfig config) {
public static void run(Path path, BaseConfig config, boolean isApi, BaseCmd cmd) {
ObfEnv.config = config;
if (!config.isQuiet()) {
// 输出配置信息
@@ -243,7 +246,8 @@ public class Runner {
System.out.println(
ColorUtil.blue("###################### ALL OBFUSCATE FINISH ######################"));
}
boolean simpleOutput = cmd == null || !cmd.isStdOutput();
if (isApi || simpleOutput) {
try {
Files.write(Paths.get(newFile), Files.readAllBytes(Const.TEMP_PATH));
logger.info("class obfuscate finish and write new class file");
@@ -254,5 +258,35 @@ public class Runner {
logger.info("class obfuscate finish and delete temp file");
} catch (Exception ignored) {
}
} else {
// 标准输出
try {
byte[] result = Files.readAllBytes(Const.TEMP_PATH);
ClassReader classReader = new ClassReader(result);
String packageName = ASMUtil.getPackageName(classReader);
String className = ASMUtil.getClassName(classReader);
Path baseDir = Files.createDirectory(Paths.get("class-obf-output"));
if (!packageName.contains(".")) {
Path packDir = Files.createDirectory(baseDir.resolve(packageName));
Path classFile = packDir.resolve(String.format("%s.class", className));
Files.write(classFile, result);
}
String[] dirs = packageName.split("\\.");
Path packDir = baseDir;
for (String dir : dirs) {
packDir = Files.createDirectory(packDir.resolve(dir));
}
Path classFile = packDir.resolve(String.format("%s.class", className));
Files.write(classFile, result);
logger.info("create dir {} and class {} finish", packageName, className);
} catch (Exception ex) {
logger.error("create class output error: {}", ex.getMessage());
logger.info("please delete the class-obf-output dir");
logger.info("可能是目标文件或目录已存在:请删除 class-obf-output 目录");
}
}
}
}

View File

@@ -0,0 +1,24 @@
package me.n1ar4.clazz.obfuscator.utils;
import org.objectweb.asm.ClassReader;
public class ASMUtil {
public static String getClassName(ClassReader classReader) {
String className = classReader.getClassName();
int lastSlashIndex = className.lastIndexOf('/');
if (lastSlashIndex != -1) {
return className.substring(lastSlashIndex+1)
.replace('/', '.');
}
return "";
}
public static String getPackageName(ClassReader classReader) {
String className = classReader.getClassName();
int lastSlashIndex = className.lastIndexOf('/');
if (lastSlashIndex != -1) {
return className.substring(0, lastSlashIndex).replace('/', '.');
}
return "";
}
}