參考文檔:
- ProGuard官網
- ProGuardMaven插件文檔
- ProGuard官方配置文檔
- ProGuard配置中文文檔
- CSDN-ProGuard使用演示
- 知乎-ProGuard使用演示
一、概述
代碼混淆是將計算機程序的代碼轉換成一種功能上等價,但是難以閱讀和理解的形式。
二、常見的混淆思路
-
符號混淆
將函數(shù)的符號,如函數(shù)名、變量名去除或混淆。
-
控制流混淆
混淆程序正常的控制流,使其在功能保持不變的情況下,使其不能清晰地反映原程序的正常邏輯。
-
計算混淆
混淆程序的計算流程,或計算流程中使用的數(shù)據(jù),使分析者難以分辨某一段代碼所執(zhí)行的具體計算。
-
虛擬機混淆
將一組指令集合(如一組x86指令)轉化為一組攻擊者未知的自定義指令集,并用與程序綁定的解釋器解釋執(zhí)行。
三、ProGuard工具
? ProGuard是一個壓縮、優(yōu)化和混淆Java字節(jié)碼文件的免費的工具,它可以刪除無用的類、字段、方法和屬性??梢詣h除沒用的注釋,最大限度地優(yōu)化字節(jié)碼文件。它還可以使用簡短的無意義的名稱來重命名已經存在的類、字段、方法和屬性。常常用于Android/Java開發(fā)用于混淆最終的項目,增加項目被反編譯的難度。
? 處理流程:
? 1)壓縮(shrink):檢測并刪除未使用的類,字段,方法和屬性
? 2)優(yōu)化(Optimize):分析并優(yōu)化方法的字節(jié)碼
? 3)混淆(obfuscate):使用簡短無意義的名稱如a,b等重命名類、方法和屬性。
? 4)預檢(preverify):Java平臺上對處理后的代碼進行預檢
四、引入項目
? ProGuard官方默認提供Gradle插件,不提供Maven插件。但是官方推薦了兩個Maven插件wvengen/proguard與dingxin/proguard,我們使用第一個插件。
項目使用的框架及語言版本:
- | 版本 |
---|---|
Spring | 2.7.* (2.0+版本都可以,1.5和3.0+未測試) |
Java | 8 |
proguard | 2.6.0 |
1. 配置xml
<build>
<plugins>
<!-- 代碼混淆proguard maven插件 -->
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.6.0</version>
<executions>
<!-- package時執(zhí)行proguard -->
<execution>
<phase>package</phase>
<goals>
<goal>proguard</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- 輸入的jar包 -->
<injar>${project.build.finalName}.jar</injar>
<!-- 輸出的jar包 -->
<outjar>${project.build.finalName}.jar</outjar>
<!-- 是否進行混淆,默認為true -->
<obfuscate>true</obfuscate>
<!-- 配置文件,通常為proguard.cfg,主要對options選項進行配置,所有的options選項都可以進行配置 -->
<proguardInclude>${project.basedir}/proguard.cfg</proguardInclude>
<!-- 額外的jar,項目編譯所需的jar -->
<libs>
<lib>${java.home}/lib/rt.jar</lib>
<!--<lib>${java.home}/lib/jce.jar</lib>-->
<lib>${java.home}/lib/jsse.jar</lib>
</libs>
<!-- 對輸入jar進行過濾,如對META-INFO文件不處理 -->
<inLibsFilter>!META-INF/**,!META-INF/versions/**</inLibsFilter>
<!-- 輸出路徑配置,必須包含injar標簽中填寫的jar -->
<outputDirectory>${project.build.directory}</outputDirectory>
<!-- 上面使用了conf配置文件,options無需配置 -->
<!--<options></options>-->
</configuration>
</plugin>
</plugins>
</build>
2. proguard.cfg文件配置
? 該文件主要是對項目代碼混淆時的參數(shù)配置,這里放在項目根目錄與pom文件同級
# 指定 java 版本
-target 1.8
# 關閉對代碼進行優(yōu)化壓縮,開啟會刪除從未使用的類或者類成員變量等
-dontshrink
# 列出未使用的代碼,可打印到標準輸出或寫入指定文件
#-printusage
# 關閉字節(jié)碼級別的優(yōu)化,如果不開啟則設置如下配置,默認開啟。
-dontoptimize
# 關閉預檢,預檢主要針對JavaME,Java6以后都不用預檢
-dontpreverify
# 不生成大小寫混寫的類名
-dontusemixedcaseclassnames
# 對類成員的命名混淆采取唯一策略
-useuniqueclassmembernames
# 混淆類名之后,對使用Class.forName('className')之類的地方進行相應替代
-adaptclassstrings
#對異常、注解信息予以保留
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
# 此選項將保存接口中的所有原始名稱(不混淆)-->
-keepnames interface ** { *; }
# 此選項將保存所有軟件包中的所有原始接口文件(不進行混淆)
#-keep interface * extends * { *; }
#保留參數(shù)名,因為控制器,或者Mybatis等接口的參數(shù)如果混淆會導致無法接受參數(shù),xml文件找不到參數(shù)
-keepparameternames
# 保留枚舉成員及方法
-keepclassmembers enum * { *; }
# 不混淆所有類,保存原始定義的注釋-
-keepclassmembers class * {
@org.springframework.context.annotation.Bean *;
@org.springframework.beans.factory.annotation.Autowired *;
@org.springframework.beans.factory.annotation.Value *;
@org.springframework.stereotype.Service *;
@org.springframework.stereotype.Component *;
}
#忽略warn消息
-ignorewarnings
#忽略note消息
#-dontnote
#打印配置信息
#-printconfiguration
# 排除混淆 指定的類名且類中的方法也不混淆
-keep class com.example.proguard.ProguardDemoApplication{<methods>;}
keep可以幫助我們保留我們不需要進行混淆的類、方法或屬性,關于上述配置文件中的keep關系整理:
保留內容 | 防止刪除或重命名 | 防止重命名 |
---|---|---|
類和類成員 | -keep | -keepnames |
僅類成員 | -keepclassmembers | -keepclassmembernames |
如果類成員存在,保留類和類成員 | -keepclasswithmembers | -keepclasswithmembernames |
更多屬性配置,請參照:ProGuard配置中文文檔
3. 項目結構
├── pom.xml
├── proguard.cfg
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── proguard
│ │ ├── ProguardDemoApplication.java
│ │ └── controller
│ │ └── IndexController.java
│ └── resources
│ └── application.yml
└── test
4. 注意事項
- 不混淆反射代碼。(class.forName(“類名”))
- 不混淆需要bean注入的類。(因為我們沒有給bean指定id,那么此時的bean的唯一標識的就是name。)
- 不混淆aop切面的類或方法。(原因與上述大致)
- 混淆之后可能會有很多奇怪的問題導致項目啟動失敗,需要根據(jù)實際情況進行放行(不混淆)。
- 對于混淆成功了的項目也需要多進行測試,保證其功能與接口完成與未混淆的源碼功能一致。
五、成功演示
1. 未混淆代碼反編譯演示
將項目正常打包后通過反編譯工具(JD)進行查看:
2. 混淆后代碼反編譯演示
將項目代碼混淆后通過反編譯工具查看
3. 使用命令啟動混淆后的jar包
java -jar proguard-1.0.0-SNAPSHOT.jar
請求接口進行測試
文章來源:http://www.zghlxwxcb.cn/news/detail-725751.html
六、源碼
Gitee碼云,免費下載及參考。文章來源地址http://www.zghlxwxcb.cn/news/detail-725751.html
到了這里,關于使用開源工具ProGuard實現(xiàn)Java代碼混淆的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!