commit
9610786896
@ -0,0 +1,8 @@ |
||||
# 默认忽略的文件 |
||||
/shelf/ |
||||
/workspace.xml |
||||
# 基于编辑器的 HTTP 客户端请求 |
||||
/httpRequests/ |
||||
# Datasource local storage ignored files |
||||
/dataSources/ |
||||
/dataSources.local.xml |
@ -0,0 +1,13 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="CompilerConfiguration"> |
||||
<annotationProcessing> |
||||
<profile name="Maven default annotation processors profile" enabled="true"> |
||||
<sourceOutputDir name="target/generated-sources/annotations" /> |
||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" /> |
||||
<outputRelativeToContentRoot value="true" /> |
||||
<module name="obfuscation" /> |
||||
</profile> |
||||
</annotationProcessing> |
||||
</component> |
||||
</project> |
@ -0,0 +1,25 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="RemoteRepositoriesConfiguration"> |
||||
<remote-repository> |
||||
<option name="id" value="central" /> |
||||
<option name="name" value="Central Repository" /> |
||||
<option name="url" value="http://maven.aliyun.com/nexus/content/groups/public/" /> |
||||
</remote-repository> |
||||
<remote-repository> |
||||
<option name="id" value="central" /> |
||||
<option name="name" value="Central Repository" /> |
||||
<option name="url" value="https://repo.maven.apache.org/maven2" /> |
||||
</remote-repository> |
||||
<remote-repository> |
||||
<option name="id" value="central" /> |
||||
<option name="name" value="Maven Central repository" /> |
||||
<option name="url" value="https://repo1.maven.org/maven2" /> |
||||
</remote-repository> |
||||
<remote-repository> |
||||
<option name="id" value="jboss.community" /> |
||||
<option name="name" value="JBoss Community repository" /> |
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" /> |
||||
</remote-repository> |
||||
</component> |
||||
</project> |
@ -0,0 +1,12 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="ExternalStorageConfigurationManager" enabled="true" /> |
||||
<component name="MavenProjectsManager"> |
||||
<option name="originalFiles"> |
||||
<list> |
||||
<option value="$PROJECT_DIR$/pom.xml" /> |
||||
</list> |
||||
</option> |
||||
</component> |
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="corretto-11" project-jdk-type="JavaSDK" /> |
||||
</project> |
@ -0,0 +1,6 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="VcsDirectoryMappings"> |
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" /> |
||||
</component> |
||||
</project> |
@ -0,0 +1,11 @@ |
||||
# obfuscation |
||||
**基于Allatori的Java代码混淆工具** |
||||
|
||||
使用Allatori混淆工具写的一个Maven插件 |
||||
|
||||
mvn install此项目,然后在想要混淆的项目的pom文件中引入此插件,并指定配置文件全路径以及要混淆的类所在路径即可使用 |
||||
|
||||
支持Windows、Linux、MacOS |
||||
|
||||
详情请参阅博客: |
||||
https://blog.csdn.net/qq_27574367/article/details/105930348 |
@ -0,0 +1,45 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
<groupId>com.dwp</groupId> |
||||
<artifactId>obfuscation</artifactId> |
||||
<version>1.0.0</version> |
||||
<packaging>maven-plugin</packaging> |
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>org.apache.maven</groupId> |
||||
<artifactId>maven-plugin-api</artifactId> |
||||
<version>2.0</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.apache.maven.plugin-tools</groupId> |
||||
<artifactId>maven-plugin-annotations</artifactId> |
||||
<version>3.2</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>dom4j</groupId> |
||||
<artifactId>dom4j</artifactId> |
||||
<version>1.6.1</version> |
||||
</dependency> |
||||
</dependencies> |
||||
<build> |
||||
<resources> |
||||
<resource> |
||||
<directory>src/main/resources</directory> |
||||
<targetPath>com/dwp/</targetPath> |
||||
</resource> |
||||
</resources> |
||||
<plugins> |
||||
<plugin> |
||||
<groupId>org.apache.maven.plugins</groupId> |
||||
<artifactId>maven-compiler-plugin</artifactId> |
||||
<configuration> |
||||
<source>6</source> |
||||
<target>6</target> |
||||
</configuration> |
||||
</plugin> |
||||
</plugins> |
||||
</build> |
||||
</project> |
@ -0,0 +1,124 @@ |
||||
package com.dwp; |
||||
|
||||
import org.dom4j.Attribute; |
||||
import org.dom4j.Document; |
||||
import org.dom4j.Element; |
||||
import org.dom4j.io.OutputFormat; |
||||
import org.dom4j.io.SAXReader; |
||||
import org.dom4j.io.XMLWriter; |
||||
|
||||
import java.io.*; |
||||
import java.util.HashSet; |
||||
import java.util.Iterator; |
||||
import java.util.Properties; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* 使用dom4j操作xml |
||||
* |
||||
* @author denngweiping |
||||
* 2020-04-01 |
||||
*/ |
||||
public class DocumentUtil { |
||||
|
||||
public static void setConfigDirPath(String configPath, String dirPath) throws Exception { |
||||
//读取XML文件,获得document对象
|
||||
SAXReader reader = new SAXReader(); |
||||
Document document = reader.read(new File(configPath)); |
||||
document.setXMLEncoding("UTF-8"); |
||||
// 获取根节点
|
||||
Element root = document.getRootElement(); |
||||
Element input = (Element) root.elements("input").get(0); |
||||
Element jar = (Element) input.elements("dir").get(0); |
||||
Attribute in = jar.attribute("in"); |
||||
in.setValue(dirPath); |
||||
Attribute out = jar.attribute("out"); |
||||
out.setValue(dirPath); |
||||
//格式化输出流,同时指定编码格式。也可以在FileOutputStream中指定。
|
||||
OutputFormat format = OutputFormat.createPrettyPrint(); |
||||
format.setEncoding("utf-8"); |
||||
XMLWriter writer = new XMLWriter(new FileOutputStream(configPath), format); |
||||
writer.write(document); |
||||
writer.close(); |
||||
} |
||||
|
||||
/** |
||||
* 向配置文件中添加需要忽略的类 |
||||
* |
||||
* @param path 源文件路径 |
||||
* @param classPathList 需要忽略的类集合 |
||||
* @throws Exception |
||||
*/ |
||||
private static void addIgnore(String path, Set<String> classPathList) throws Exception { |
||||
//读取XML文件,获得document对象
|
||||
SAXReader reader = new SAXReader(); |
||||
Document document = reader.read(new File(path)); |
||||
document.setXMLEncoding("UTF-8"); |
||||
// 获取根节点
|
||||
Element root = document.getRootElement(); |
||||
Element keepNames = (Element) root.elements("keep-names").get(0); |
||||
for (String classPath : classPathList) { |
||||
keepNames.addElement("class").addAttribute("template", "class " + classPath); |
||||
} |
||||
for (int i = 0; i < keepNames.elements("class").size(); i++) { |
||||
Element ignore = (Element) keepNames.elements("class").get(i); |
||||
ignore.addElement("field").addAttribute("access", "private+"); |
||||
ignore.addElement("method").addAttribute("access", "private+"); |
||||
} |
||||
//格式化输出流,同时指定编码格式。也可以在FileOutputStream中指定。
|
||||
OutputFormat format = OutputFormat.createPrettyPrint(); |
||||
format.setEncoding("utf-8"); |
||||
XMLWriter writer = new XMLWriter(new FileOutputStream(path), format); |
||||
writer.write(document); |
||||
writer.close(); |
||||
} |
||||
|
||||
/** |
||||
* 创建配置文件 |
||||
* |
||||
* @param classPath class文件所在路径 |
||||
* @param resourcePath 指定加密类列表的文件所在目录 |
||||
* @throws Exception |
||||
*/ |
||||
public static void createConfigFile(String classPath, String resourcePath) throws Exception { |
||||
//读取用户配置文件并修改config内容
|
||||
//读取配置文件
|
||||
|
||||
//全包扫描,扫描所有class文件,并将全类名写入ignoreList
|
||||
Set<String> ignoreList = JarFileLoader.scanClassPathList(classPath, new HashSet<String>()); |
||||
if (ignoreList == null || ignoreList.isEmpty()) { |
||||
System.out.println("error: " + classPath + " 在指定目录下未扫描到class文件!"); |
||||
return; |
||||
} |
||||
|
||||
File file = new File(resourcePath); |
||||
if (!file.exists()) { |
||||
// 文件不存在
|
||||
System.out.println("warm: 未指定需要混淆的class类!"); |
||||
//System.out.println(" warning: 未指定需要混淆的class类!");
|
||||
} else { |
||||
InputStream in = new BufferedInputStream(new FileInputStream(resourcePath)); |
||||
Set<String> encryptList = new HashSet<String>(); |
||||
if (in != null) { |
||||
Properties prop = new Properties(); |
||||
prop.load(in); ///加载属性列表
|
||||
Iterator<String> it = prop.stringPropertyNames().iterator(); |
||||
System.out.println("以下类将被混淆:"); |
||||
//System.out.println("info: 以下类将被混淆");
|
||||
while (it.hasNext()) { |
||||
String key = it.next(); |
||||
if (key != null && key.trim().length() > 0) { |
||||
System.out.println(key); |
||||
//System.out.println(key);
|
||||
encryptList.add(key); |
||||
} |
||||
} |
||||
} |
||||
in.close(); |
||||
//移除需要加密的类
|
||||
ignoreList.removeAll(encryptList); |
||||
} |
||||
addIgnore(classPath + "/config.xml", ignoreList); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,157 @@ |
||||
package com.dwp; |
||||
|
||||
import org.codehaus.plexus.util.FileUtils; |
||||
|
||||
import java.io.*; |
||||
|
||||
/** |
||||
* 文件操作工具类 |
||||
* |
||||
* @author denngweiping |
||||
* 2020-04-01 |
||||
*/ |
||||
public class FileUtil { |
||||
|
||||
/** |
||||
* 创建文件 |
||||
* |
||||
* @param path 文件名称 |
||||
* @param filecontent 文件内容 |
||||
* @return 是否创建成功,成功则返回true |
||||
*/ |
||||
public static boolean createFile(String path, String filecontent) { |
||||
Boolean bool = false; |
||||
File file = new File(path); |
||||
try { |
||||
//如果文件不存在,则创建新的文件
|
||||
if (!file.exists()) { |
||||
file.createNewFile(); |
||||
bool = true; |
||||
//创建文件成功后,写入内容到文件里
|
||||
writeFileContent(path, filecontent); |
||||
} |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} |
||||
|
||||
return bool; |
||||
} |
||||
|
||||
/** |
||||
* 向文件中写入内容 |
||||
* |
||||
* @param filepath 文件路径与名称 |
||||
* @param fileIn 写入的内容 |
||||
* @return |
||||
* @throws IOException |
||||
*/ |
||||
public static boolean writeFileContent(String filepath, String fileIn) throws IOException { |
||||
Boolean bool = false; |
||||
String temp = ""; |
||||
|
||||
FileInputStream fis = null; |
||||
InputStreamReader isr = null; |
||||
BufferedReader br = null; |
||||
FileOutputStream fos = null; |
||||
PrintWriter pw = null; |
||||
try { |
||||
File file = new File(filepath);//文件路径(包括文件名称)
|
||||
//将文件读入输入流
|
||||
fis = new FileInputStream(file); |
||||
isr = new InputStreamReader(fis); |
||||
br = new BufferedReader(isr); |
||||
StringBuffer buffer = new StringBuffer(); |
||||
|
||||
//文件原有内容
|
||||
for (int i = 0; (temp = br.readLine()) != null; i++) { |
||||
buffer.append(temp); |
||||
// 行与行之间的分隔符 相当于“\n”
|
||||
buffer = buffer.append(System.getProperty("line.separator")); |
||||
} |
||||
buffer.append(fileIn); |
||||
|
||||
fos = new FileOutputStream(file); |
||||
pw = new PrintWriter(fos); |
||||
pw.write(buffer.toString().toCharArray()); |
||||
pw.flush(); |
||||
bool = true; |
||||
} catch (Exception e) { |
||||
// TODO: handle exception
|
||||
e.printStackTrace(); |
||||
} finally { |
||||
//不要忘记关闭
|
||||
if (pw != null) { |
||||
pw.close(); |
||||
} |
||||
if (fos != null) { |
||||
fos.close(); |
||||
} |
||||
if (br != null) { |
||||
br.close(); |
||||
} |
||||
if (isr != null) { |
||||
isr.close(); |
||||
} |
||||
if (fis != null) { |
||||
fis.close(); |
||||
} |
||||
} |
||||
return bool; |
||||
} |
||||
|
||||
/** |
||||
* 删除文件 |
||||
* |
||||
* @param path 文件名称 |
||||
* @return |
||||
*/ |
||||
public static boolean delFile(String path) { |
||||
Boolean bool = false; |
||||
File file = new File(path); |
||||
if (file.exists()) { |
||||
bool = file.delete(); |
||||
} else { |
||||
System.out.println("未找到指定文件:" + path); |
||||
} |
||||
return bool; |
||||
} |
||||
|
||||
/** |
||||
* 复制文件 |
||||
* |
||||
* @param source |
||||
* @param dest |
||||
* @throws IOException |
||||
*/ |
||||
public static void copyFile(File source, File dest) |
||||
throws IOException { |
||||
FileUtils.copyFile(source, dest); |
||||
} |
||||
|
||||
/** |
||||
* 通过文件路径直接修改文件名 |
||||
* |
||||
* @param filePath 需要修改的文件的完整路径 |
||||
* @param newFileName 需要修改的文件的名称 |
||||
* @return |
||||
*/ |
||||
public static boolean FixFileName(String filePath, String newFileName) throws Exception { |
||||
File f = new File(filePath); |
||||
if (!f.exists()) { // 判断原文件是否存在(防止文件名冲突)
|
||||
throw new RuntimeException("源文件不存在!"); |
||||
} |
||||
newFileName = newFileName.trim(); |
||||
if ("".equals(newFileName) || newFileName == null) // 文件名不能为空
|
||||
return false; |
||||
String newFilePath = null; |
||||
if (f.isDirectory()) { // 判断是否为文件夹
|
||||
newFilePath = filePath.substring(0, filePath.lastIndexOf("/")) + "/" + newFileName; |
||||
} else { |
||||
newFilePath = filePath.substring(0, filePath.lastIndexOf("/")) + "/" + newFileName |
||||
+ filePath.substring(filePath.lastIndexOf(".")); |
||||
} |
||||
File nf = new File(newFilePath); |
||||
return f.renameTo(nf); // 修改文件名
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,140 @@ |
||||
package com.dwp; |
||||
|
||||
import java.io.*; |
||||
import java.net.URL; |
||||
import java.util.Enumeration; |
||||
import java.util.Set; |
||||
import java.util.jar.JarEntry; |
||||
import java.util.jar.JarFile; |
||||
|
||||
/** |
||||
* Jar包工具类 |
||||
* |
||||
* @author denngweiping |
||||
* 2020-04-01 |
||||
*/ |
||||
public class JarFileLoader { |
||||
|
||||
/** |
||||
* 扫描指定文件夹,返回所有calss文件 |
||||
* |
||||
* @param path |
||||
* @param resultList |
||||
* @return |
||||
*/ |
||||
public static Set<String> scanClassPathList(String path, Set<String> resultList) { |
||||
File file = new File(path); |
||||
if (file.exists()) { |
||||
File[] files = file.listFiles(); |
||||
if (null == files || files.length == 0) { |
||||
return null; |
||||
} else { |
||||
for (File file2 : files) { |
||||
if (file2.isDirectory()) { |
||||
scanClassPathList(file2.getAbsolutePath(), resultList); |
||||
} else { |
||||
String filePath = file2.getAbsolutePath(); |
||||
if (filePath.endsWith(".class")) { |
||||
String classPath = filePath.substring(filePath.lastIndexOf("classes") + 8, filePath.lastIndexOf(".class")); |
||||
resultList.add(classPath.replace("\\", ".")); |
||||
} |
||||
} |
||||
} |
||||
return resultList; |
||||
} |
||||
} else { |
||||
throw new RuntimeException("文件不存在!"); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* copyFile |
||||
* |
||||
* @param url |
||||
* @param targetPath |
||||
* @throws Exception |
||||
*/ |
||||
public synchronized static void copyFile(URL url, String targetPath) throws Exception { |
||||
String protocol = url.getProtocol(); |
||||
int startIndex = url.getPath().indexOf("file:"); |
||||
int endIndex = url.getPath().lastIndexOf("!/com/dwp"); |
||||
String path = url.getPath().substring(startIndex + 5, endIndex); |
||||
if ("jar".equals(protocol)) { |
||||
JarFile jarFile = new JarFile(new File(path)); |
||||
// 遍历Jar包
|
||||
Enumeration<JarEntry> entries = jarFile.entries(); |
||||
while (entries.hasMoreElements()) { |
||||
JarEntry jarEntry = entries.nextElement(); |
||||
if (jarEntry.isDirectory()) { |
||||
continue; |
||||
} |
||||
loadJar(jarEntry, path, targetPath); |
||||
} |
||||
} else if ("file".equals(protocol)) { |
||||
File file = new File(path); |
||||
loadFile(file, targetPath); |
||||
} |
||||
} |
||||
|
||||
private static void loadFile(File file, String targetPath) throws IOException { |
||||
if (null == file) { |
||||
return; |
||||
} |
||||
if (file.isDirectory()) { |
||||
File[] files = file.listFiles(); |
||||
if (null != files) { |
||||
for (File f : files) { |
||||
loadFile(f, targetPath); |
||||
} |
||||
} |
||||
} else { |
||||
if (file.getName() != null && (file.getName().endsWith(".jar") || file.getName().indexOf("config.xml") != -1)) { |
||||
File allatoriTarget = new File(targetPath + "/" + file.getName()); |
||||
FileUtil.copyFile(file, allatoriTarget); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private static void loadJar(JarEntry jarEntry, String path, String targetPath) throws Exception { |
||||
String entityName = jarEntry.getName(); |
||||
String fileName = entityName.substring(entityName.lastIndexOf("/") + 1); |
||||
if (!fileName.endsWith("jar") && fileName.indexOf("config.xml") == -1) { |
||||
return; |
||||
} |
||||
|
||||
File tempFile = new File(targetPath + "/" + fileName); |
||||
if (!tempFile.getParentFile().exists()) { |
||||
tempFile.getParentFile().mkdirs(); |
||||
} |
||||
// 如果缓存文件存在,则删除
|
||||
if (tempFile.exists()) { |
||||
tempFile.delete(); |
||||
} |
||||
InputStream in = null; |
||||
|
||||
BufferedInputStream reader = null; |
||||
FileOutputStream writer = null; |
||||
in = JarFileLoader.class.getResourceAsStream(entityName); |
||||
if (in == null) { |
||||
in = JarFileLoader.class.getResourceAsStream("/" + entityName); |
||||
if (null == in) { |
||||
return; |
||||
} |
||||
} |
||||
reader = new BufferedInputStream(in); |
||||
writer = new FileOutputStream(tempFile); |
||||
byte[] buffer = new byte[1024]; |
||||
int len = 0; |
||||
while ((len = reader.read(buffer)) != -1) { |
||||
writer.write(buffer, 0, len); |
||||
buffer = new byte[1024]; |
||||
} |
||||
if (in != null) { |
||||
in.close(); |
||||
} |
||||
if (writer != null) { |
||||
writer.close(); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,24 @@ |
||||
package com.dwp; |
||||
|
||||
/** |
||||
* 获取当前操作系统类型工具类 |
||||
* |
||||
* @author denngweiping |
||||
* 2020-04-01 |
||||
*/ |
||||
public class OSUtil { |
||||
|
||||
private static String OS = System.getProperty("os.name").toLowerCase(); |
||||
|
||||
public static boolean isMac() { |
||||
return OS.indexOf("mac") != -1; |
||||
} |
||||
|
||||
public static boolean isWindows() { |
||||
return OS.indexOf("win") != -1; |
||||
} |
||||
|
||||
public static boolean isLinux() { |
||||
return OS.indexOf("linux") != -1 || OS.indexOf("unix") != -1 || OS.indexOf("centos") != -1; |
||||
} |
||||
} |
@ -0,0 +1,57 @@ |
||||
package com.dwp; |
||||
|
||||
import org.apache.maven.plugin.AbstractMojo; |
||||
import org.apache.maven.plugins.annotations.LifecyclePhase; |
||||
import org.apache.maven.plugins.annotations.Mojo; |
||||
import org.apache.maven.plugins.annotations.Parameter; |
||||
|
||||
import java.net.URL; |
||||
|
||||
/** |
||||
* 混淆插件主类 |
||||
* |
||||
* @author denngweiping |
||||
* 2020-04-01 |
||||
*/ |
||||
@Mojo(name = "obfuscation", defaultPhase = LifecyclePhase.PACKAGE) |
||||
public class Obfuscation extends AbstractMojo { |
||||
/** |
||||
* 项目根目录 |
||||
*/ |
||||
@Parameter |
||||
private String basePath="D:/develope/IdeaProjects/dky/dntd-model-tool1";//不要一开始就让人把你看透
|
||||
/** |
||||
* class文件所在目录 |
||||
*/ |
||||
@Parameter |
||||
private String classPath="D:/develope/IdeaProjects/dky/dntd-model-tool1/target/classes";//学会保留30%的神秘感
|
||||
|
||||
public void execute() { |
||||
try { |
||||
//学会给予,你才能获得更多(复制工具jar包、配置文件到目标目录)
|
||||
URL url = this.getClass().getResource(""); |
||||
JarFileLoader.copyFile(url, classPath); |
||||
//学会从外界获取自己想要的东西(获取传入的混淆类列表,创建并修改配置文件)
|
||||
String resourcePath = basePath + "/classNames.properties"; |
||||
DocumentUtil.createConfigFile(classPath, resourcePath); |
||||
//人生需要一盏指路明灯(指定class类所在路径)
|
||||
DocumentUtil.setConfigDirPath(classPath + "/config.xml", classPath); |
||||
//道理都懂得和实际去体会是不一样的(创建并运行脚本文件)
|
||||
ShellExcutor.createAndRunShell(classPath); |
||||
//不带片履来到这人世间,走的时候也要干干净净的离去(删除多余文件,避免项目污染)
|
||||
FileUtil.delFile(resourcePath); |
||||
FileUtil.delFile(classPath + "/obfuscation-main.jar"); |
||||
FileUtil.delFile(classPath + "/obfuscation-annotations.jar"); |
||||
if (OSUtil.isMac() || OSUtil.isLinux()) { |
||||
FileUtil.delFile(classPath + "/run.sh"); |
||||
} else if (OSUtil.isWindows()) { |
||||
FileUtil.delFile(classPath + "/run.bat"); |
||||
} |
||||
FileUtil.delFile(classPath + "/config.xml"); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,160 @@ |
||||
package com.dwp; |
||||
|
||||
import java.io.*; |
||||
|
||||
/** |
||||
* Java执行shell脚本工具类 |
||||
* |
||||
* @author denngweiping |
||||
* 2020-04-01 |
||||
*/ |
||||
public class ShellExcutor { |
||||
|
||||
/** |
||||
* 运行bat脚本 |
||||
* |
||||
* @param path 文件全路径 |
||||
*/ |
||||
public static void runBat(String path) { |
||||
// TODO Auto-generated method stub
|
||||
File batFile = new File(path); |
||||
boolean batFileExist = batFile.exists(); |
||||
if (batFileExist) { |
||||
callCmd(path); |
||||
} |
||||
} |
||||
|
||||
private static void callCmd(String locationCmd) { |
||||
StringBuilder sb = new StringBuilder(); |
||||
try { |
||||
Process child = Runtime.getRuntime().exec(locationCmd); |
||||
InputStream in = child.getInputStream(); |
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); |
||||
String line; |
||||
while ((line = bufferedReader.readLine()) != null) { |
||||
sb.append(line + "\n"); |
||||
} |
||||
in.close(); |
||||
try { |
||||
child.waitFor(); |
||||
} catch (InterruptedException e) { |
||||
System.out.println("error: 代码混淆时出现异常"); |
||||
} |
||||
} catch (IOException e) { |
||||
System.out.println(e.getMessage()); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Java执行shell脚本入口 |
||||
* |
||||
* @param fileName 文件名 |
||||
* @param path 文件所在目录 |
||||
* @throws Exception |
||||
*/ |
||||
public static void runShell(String fileName, String path) throws Exception { |
||||
try { |
||||
//拼接完整的脚本目录
|
||||
String shellPath = path + "/" + fileName; |
||||
|
||||
//执行脚本
|
||||
callScript(shellPath); |
||||
|
||||
} catch (Exception e) { |
||||
System.out.println("error: 混淆时出现异常"); |
||||
//System.out.println("混淆时出现异常");
|
||||
throw e; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 脚本文件具体执行及脚本执行过程探测 |
||||
* |
||||
* @param script 脚本文件绝对路径 |
||||
* @throws Exception |
||||
*/ |
||||
private static void callScript(String script) throws Exception { |
||||
try { |
||||
String cmd = "sh " + script; |
||||
|
||||
//启动独立线程等待process执行完成
|
||||
CommandWaitForThread commandThread = new CommandWaitForThread(cmd); |
||||
commandThread.start(); |
||||
|
||||
while (!commandThread.isFinish()) { |
||||
System.out.println("代码混淆中..."); |
||||
//System.out.println(" 代码混淆中...");
|
||||
Thread.sleep(10000); |
||||
} |
||||
|
||||
//检查脚本执行结果状态码
|
||||
if (commandThread.getExitValue() != 0) { |
||||
throw new Exception("混淆失败,系统异常"); |
||||
} |
||||
} catch (Exception e) { |
||||
throw new Exception("混淆时出现异常"); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 脚本函数执行线程 |
||||
*/ |
||||
public static class CommandWaitForThread extends Thread { |
||||
|
||||
private String cmd; |
||||
private boolean finish = false; |
||||
private int exitValue = -1; |
||||
|
||||
public CommandWaitForThread(String cmd) { |
||||
this.cmd = cmd; |
||||
} |
||||
|
||||
public void run() { |
||||
try { |
||||
//执行脚本并等待脚本执行完成
|
||||
Process process = Runtime.getRuntime().exec(cmd); |
||||
//阻塞执行线程直至脚本执行完成后返回
|
||||
this.exitValue = process.waitFor(); |
||||
} catch (Throwable e) { |
||||
System.out.println("error: 执行混淆时出现异常:" + cmd); |
||||
//System.out.println("脚本命令执行异常:" + cmd);
|
||||
exitValue = 110; |
||||
} finally { |
||||
finish = true; |
||||
} |
||||
} |
||||
|
||||
public boolean isFinish() { |
||||
return finish; |
||||
} |
||||
|
||||
public void setFinish(boolean finish) { |
||||
this.finish = finish; |
||||
} |
||||
|
||||
public int getExitValue() { |
||||
return exitValue; |
||||
} |
||||
} |
||||
|
||||
public static void createAndRunShell(String targetPath) throws Exception { |
||||
//将脚本写到要加密的jar所在目录下
|
||||
//判断当前项目所在环境 Windows Mac Linux
|
||||
if (OSUtil.isMac() || OSUtil.isLinux()) { |
||||
//Mac Linux
|
||||
System.out.println("OS: Linux"); |
||||
String runAllatoriTarget = targetPath + "/run.sh"; |
||||
FileUtil.createFile(runAllatoriTarget, "java -Xms128m -Xmx512m -jar " + targetPath + "/obfuscation-main.jar " + targetPath + "/config.xml"); |
||||
//执行脚本
|
||||
runShell("run.sh", targetPath); |
||||
System.out.println("********代码混淆完成*********"); |
||||
} else if (OSUtil.isWindows()) { |
||||
//Windows
|
||||
System.out.println("OS: Windows"); |
||||
String runAllatoriTarget = targetPath + "/run.bat"; |
||||
FileUtil.createFile(runAllatoriTarget, "java -Xms128m -Xmx512m -jar " + targetPath + "/obfuscation-main.jar " + targetPath + "/config.xml"); |
||||
//执行脚本
|
||||
runBat(runAllatoriTarget); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,21 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
|
||||
<!--混淆插件配置文件--> |
||||
<config> |
||||
<property name="classes-naming" value="unique"/> |
||||
<property name="classes-naming" value="iii"/> |
||||
<property name="methods-naming" value="iii"/> |
||||
<property name="fields-naming" value="iii"/> |
||||
<!--方法参数名称保持不变,避免公共api接口等出现异常 --> |
||||
<property name="local-variables-naming" value="keep-parameters"/> |
||||
<!-- 输入和输出jar配置,out指向的是加密后的jar --> |
||||
<input> |
||||
<dir in="" out=""/> |
||||
</input> |
||||
<ignore-classes> |
||||
<class template="class org.springframework.boot.*"/> |
||||
<class template="class cn.aaa.bbb.*"/> |
||||
</ignore-classes> |
||||
<keep-names> |
||||
</keep-names> |
||||
</config> |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,46 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
||||
<!-- Generated by maven-plugin-tools 3.9 (for help'mojo with additional elements)--> |
||||
|
||||
<plugin> |
||||
<name>obfuscation</name> |
||||
<description></description> |
||||
<groupId>com.dwp</groupId> |
||||
<artifactId>obfuscation</artifactId> |
||||
<version>1.0.0</version> |
||||
<goalPrefix>obfuscation</goalPrefix> |
||||
<mojos> |
||||
<mojo> |
||||
<goal>obfuscation</goal> |
||||
<description>混淆插件主类</description> |
||||
<requiresDirectInvocation>false</requiresDirectInvocation> |
||||
<requiresProject>true</requiresProject> |
||||
<requiresReports>false</requiresReports> |
||||
<aggregator>false</aggregator> |
||||
<requiresOnline>false</requiresOnline> |
||||
<inheritedByDefault>true</inheritedByDefault> |
||||
<phase>package</phase> |
||||
<implementation>com.dwp.Obfuscation</implementation> |
||||
<language>java</language> |
||||
<instantiationStrategy>per-lookup</instantiationStrategy> |
||||
<executionStrategy>once-per-session</executionStrategy> |
||||
<threadSafe>false</threadSafe> |
||||
<parameters> |
||||
<parameter> |
||||
<name>basePath</name> |
||||
<type>java.lang.String</type> |
||||
<required>false</required> |
||||
<editable>true</editable> |
||||
<description>项目根目录</description> |
||||
</parameter> |
||||
<parameter> |
||||
<name>classPath</name> |
||||
<type>java.lang.String</type> |
||||
<required>false</required> |
||||
<editable>true</editable> |
||||
<description>class文件所在目录</description> |
||||
</parameter> |
||||
</parameters> |
||||
</mojo> |
||||
</mojos> |
||||
</plugin> |
@ -0,0 +1,88 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
||||
<!-- Generated by maven-plugin-tools 3.9--> |
||||
|
||||
<plugin> |
||||
<name>obfuscation</name> |
||||
<description></description> |
||||
<groupId>com.dwp</groupId> |
||||
<artifactId>obfuscation</artifactId> |
||||
<version>1.0.0</version> |
||||
<goalPrefix>obfuscation</goalPrefix> |
||||
<isolatedRealm>false</isolatedRealm> |
||||
<inheritedByDefault>true</inheritedByDefault> |
||||
<requiredJavaVersion>1.6</requiredJavaVersion> |
||||
<requiredMavenVersion>2.0</requiredMavenVersion> |
||||
<mojos> |
||||
<mojo> |
||||
<goal>obfuscation</goal> |
||||
<description>混淆插件主类</description> |
||||
<requiresDirectInvocation>false</requiresDirectInvocation> |
||||
<requiresProject>true</requiresProject> |
||||
<requiresReports>false</requiresReports> |
||||
<aggregator>false</aggregator> |
||||
<requiresOnline>false</requiresOnline> |
||||
<inheritedByDefault>true</inheritedByDefault> |
||||
<phase>package</phase> |
||||
<implementation>com.dwp.Obfuscation</implementation> |
||||
<language>java</language> |
||||
<instantiationStrategy>per-lookup</instantiationStrategy> |
||||
<executionStrategy>once-per-session</executionStrategy> |
||||
<threadSafe>false</threadSafe> |
||||
<parameters> |
||||
<parameter> |
||||
<name>basePath</name> |
||||
<type>java.lang.String</type> |
||||
<required>false</required> |
||||
<editable>true</editable> |
||||
<description>项目根目录</description> |
||||
</parameter> |
||||
<parameter> |
||||
<name>classPath</name> |
||||
<type>java.lang.String</type> |
||||
<required>false</required> |
||||
<editable>true</editable> |
||||
<description>class文件所在目录</description> |
||||
</parameter> |
||||
</parameters> |
||||
</mojo> |
||||
</mojos> |
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>org.apache.maven</groupId> |
||||
<artifactId>maven-plugin-api</artifactId> |
||||
<type>jar</type> |
||||
<version>2.0</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.apache.maven.plugin-tools</groupId> |
||||
<artifactId>maven-plugin-annotations</artifactId> |
||||
<type>jar</type> |
||||
<version>3.2</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.apache.maven</groupId> |
||||
<artifactId>maven-artifact</artifactId> |
||||
<type>jar</type> |
||||
<version>3.0</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.codehaus.plexus</groupId> |
||||
<artifactId>plexus-utils</artifactId> |
||||
<type>jar</type> |
||||
<version>2.0.4</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>dom4j</groupId> |
||||
<artifactId>dom4j</artifactId> |
||||
<type>jar</type> |
||||
<version>1.6.1</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>xml-apis</groupId> |
||||
<artifactId>xml-apis</artifactId> |
||||
<type>jar</type> |
||||
<version>1.0.b2</version> |
||||
</dependency> |
||||
</dependencies> |
||||
</plugin> |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,21 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
|
||||
<!--混淆插件配置文件--> |
||||
<config> |
||||
<property name="classes-naming" value="unique"/> |
||||
<property name="classes-naming" value="iii"/> |
||||
<property name="methods-naming" value="iii"/> |
||||
<property name="fields-naming" value="iii"/> |
||||
<!--方法参数名称保持不变,避免公共api接口等出现异常 --> |
||||
<property name="local-variables-naming" value="keep-parameters"/> |
||||
<!-- 输入和输出jar配置,out指向的是加密后的jar --> |
||||
<input> |
||||
<dir in="" out=""/> |
||||
</input> |
||||
<ignore-classes> |
||||
<class template="class org.springframework.boot.*"/> |
||||
<class template="class cn.aaa.bbb.*"/> |
||||
</ignore-classes> |
||||
<keep-names> |
||||
</keep-names> |
||||
</config> |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,3 @@ |
||||
artifactId=obfuscation |
||||
groupId=com.dwp |
||||
version=1.0.0 |
@ -0,0 +1,7 @@ |
||||
com\dwp\JarFileLoader.class |
||||
com\dwp\ShellExcutor$CommandWaitForThread.class |
||||
com\dwp\ShellExcutor.class |
||||
com\dwp\Obfuscation.class |
||||
com\dwp\DocumentUtil.class |
||||
com\dwp\FileUtil.class |
||||
com\dwp\OSUtil.class |
@ -0,0 +1,6 @@ |
||||
D:\develope\IdeaProjects\obfuscation\src\main\java\com\dwp\Obfuscation.java |
||||
D:\develope\IdeaProjects\obfuscation\src\main\java\com\dwp\FileUtil.java |
||||
D:\develope\IdeaProjects\obfuscation\src\main\java\com\dwp\OSUtil.java |
||||
D:\develope\IdeaProjects\obfuscation\src\main\java\com\dwp\ShellExcutor.java |
||||
D:\develope\IdeaProjects\obfuscation\src\main\java\com\dwp\JarFileLoader.java |
||||
D:\develope\IdeaProjects\obfuscation\src\main\java\com\dwp\DocumentUtil.java |
Binary file not shown.
@ -0,0 +1,88 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
||||
<!-- Generated by maven-plugin-tools 3.9 (enhanced XHTML version with additional elements (used for plugin:report))--> |
||||
|
||||
<plugin> |
||||
<name>obfuscation</name> |
||||
<description></description> |
||||
<groupId>com.dwp</groupId> |
||||
<artifactId>obfuscation</artifactId> |
||||
<version>1.0.0</version> |
||||
<goalPrefix>obfuscation</goalPrefix> |
||||
<isolatedRealm>false</isolatedRealm> |
||||
<inheritedByDefault>true</inheritedByDefault> |
||||
<requiredJavaVersion>1.6</requiredJavaVersion> |
||||
<requiredMavenVersion>2.0</requiredMavenVersion> |
||||
<mojos> |
||||
<mojo> |
||||
<goal>obfuscation</goal> |
||||
<description>混淆插件主类</description> |
||||
<requiresDirectInvocation>false</requiresDirectInvocation> |
||||
<requiresProject>true</requiresProject> |
||||
<requiresReports>false</requiresReports> |
||||
<aggregator>false</aggregator> |
||||
<requiresOnline>false</requiresOnline> |
||||
<inheritedByDefault>true</inheritedByDefault> |
||||
<phase>package</phase> |
||||
<implementation>com.dwp.Obfuscation</implementation> |
||||
<language>java</language> |
||||
<instantiationStrategy>per-lookup</instantiationStrategy> |
||||
<executionStrategy>once-per-session</executionStrategy> |
||||
<threadSafe>false</threadSafe> |
||||
<parameters> |
||||
<parameter> |
||||
<name>basePath</name> |
||||
<type>java.lang.String</type> |
||||
<required>false</required> |
||||
<editable>true</editable> |
||||
<description>项目根目录</description> |
||||
</parameter> |
||||
<parameter> |
||||
<name>classPath</name> |
||||
<type>java.lang.String</type> |
||||
<required>false</required> |
||||
<editable>true</editable> |
||||
<description>class文件所在目录</description> |
||||
</parameter> |
||||
</parameters> |
||||
</mojo> |
||||
</mojos> |
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>org.apache.maven</groupId> |
||||
<artifactId>maven-plugin-api</artifactId> |
||||
<type>jar</type> |
||||
<version>2.0</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.apache.maven.plugin-tools</groupId> |
||||
<artifactId>maven-plugin-annotations</artifactId> |
||||
<type>jar</type> |
||||
<version>3.2</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.apache.maven</groupId> |
||||
<artifactId>maven-artifact</artifactId> |
||||
<type>jar</type> |
||||
<version>3.0</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.codehaus.plexus</groupId> |
||||
<artifactId>plexus-utils</artifactId> |
||||
<type>jar</type> |
||||
<version>2.0.4</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>dom4j</groupId> |
||||
<artifactId>dom4j</artifactId> |
||||
<type>jar</type> |
||||
<version>1.6.1</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>xml-apis</groupId> |
||||
<artifactId>xml-apis</artifactId> |
||||
<type>jar</type> |
||||
<version>1.0.b2</version> |
||||
</dependency> |
||||
</dependencies> |
||||
</plugin> |
Loading…
Reference in new issue