我试图学习如何使用ProGuard,这并不像我想象的那么容易。起初我发现了一个简单的Java代码来尝试它,一个简单的two class Swing calculator。
可以通过以下链接找到代码,但我发现在此处发布代码太过冗长。无论如何,它是一个普通的应用程序,在Calc.main()
上有一个入口点,没有包。
然后我用以下内容编译了两个来源:
$ javac *.java
并创建了.jar
文件(因为看起来ProGuard似乎只适用于jar):
$ jar cvef Calc calc.jar *.class
added manifest
adding: Calc.class(in = 3869) (out= 2126)(deflated 45%)
adding: Calc$ClearListener.class(in = 468) (out= 327)(deflated 30%)
adding: CalcLogic.class(in = 1004) (out= 515)(deflated 48%)
adding: Calc$NumListener.class(in = 1005) (out= 598)(deflated 40%)
adding: Calc$OpListener.class(in = 1788) (out= 1005)(deflated 43%)
写了名为obfuscate.pro
的ProGuard文件:
-injars calc.jar
-outjars calc_obf.jar
-libraryjars <java.home>/lib/rt.jar
-keep public class Calc extends javax.swing.JFrame {
public static void main(java.lang.String[]);
}
最后运行ProGuard:
$ ~/progs/proguard/proguard4.8/bin/proguard.sh @obfuscate.pro
ProGuard, version 4.8
Reading program jar [/home/lucas/tmp/calc.jar]
Reading library jar [/usr/lib/jvm/java-7-openjdk-i386/jre/lib/rt.jar]
Error: The output jar is empty. Did you specify the proper '-keep' options?
好吧,显然没有用。我厌倦了弄乱ProGruard参数,特别是那些-keep
选项,但没有成功。我在与我的问题相关的文档中找到的所有内容都无法帮助我。然后我求助于你......出了什么问题?怎么做对了?
答案 0 :(得分:5)
我使用以下配置文件使其工作:
-injars calc.jar
-outjars calc_obf.jar
-libraryjars <java.home>/lib/rt.jar
-keep class Calc {
public static void main(java.lang.String[]);
}
最值得注意的是,我在public
前放弃了class Calc
。
答案 1 :(得分:1)
我遇到了类似的问题,通过取出Java修饰符解决了这个问题。
可见性修饰符等Java修饰符是可选的 ProGuard配置文件-keep选项(以及相关选项-keepclassmembers等)
来自手册: -keep [,修饰符,...] class_specification
除非有特殊原因,否则你可以将它们排除在外。
答案 2 :(得分:0)
这是gradle的解决方案
创建一个可运行的jar,并将所有依赖库复制到目录“ dependencies”,然后在清单中添加类路径。
task createJar(type: Jar) {
println("Cleaning...")
clean
manifest {
attributes('Main-Class': 'com.abc.gradle.hello.App',
'Class-Path': configurations.default.collect { 'dependencies/' +
it.getName() }.join(' ')
)
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it)
}
} with jar
println "${outputJar} created"
}
复制依赖项
task copyDepends(type: Copy) {
from configurations.default
into "${dependsDir}"
}
使用Proguard对库进行模糊处理
task proguard(type: proguard.gradle.ProGuardTask) {
println("Performing obfuscation..")
configuration 'proguard.conf'
injars "${outputJar}"
outjars "${buildDir}/libs/${rootProject.name}_proguard.jar"
libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
libraryjars "${dependsDir}"
}
这是完整的build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'net.sf.proguard:proguard-gradle:6.0.3'
classpath 'net.sf.proguard:proguard-base:6.0.3'
}
}
plugins {
id 'java'
id 'application'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.slf4j:slf4j-api:1.7.30'
implementation 'ch.qos.logback:logback-classic:1.2.3'
implementation 'ch.qos.logback:logback-core:1.2.3'
testImplementation 'junit:junit:4.13'
}
def outputJar = "${buildDir}/libs/${rootProject.name}.jar"
def dependsDir = "${buildDir}/libs/dependencies/"
def runnableJar = "${rootProject.name}_fat.jar";
task copyDepends(type: Copy) {
from configurations.default
into "${dependsDir}"
}
task createJar(type: Jar) {
println("Cleaning...")
clean
manifest {
attributes('Main-Class': 'com.abc.gradle.hello.App',
'Class-Path': configurations.default.collect { 'dependencies/' +
it.getName() }.join(' ')
)
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
} with jar
println "${outputJar} created"
}
task proguard(type: proguard.gradle.ProGuardTask) {
println("Performing obfuscation..")
configuration 'proguard.conf'
injars "${outputJar}"
outjars "${buildDir}/libs/${rootProject.name}_proguard.jar"
libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
libraryjars "${dependsDir}"
}
Proguard.conf
-keep public class * {
public * ;
}
用于模糊处理的分级命令
gradle createJar
gradle copyDepends
gradle proguard