代码混淆还原怎么解决(代码混淆原理)
代码混淆一.基本概念java的bytecode很容易通过JAD等反编译工具还原出源代码这样势必不满足安全的定义如何一定程度上保护需要防止被反编译的源代码呢?混淆(obfuscate)技术注意:用obfuscate防盗版是根本不可能,连汇编这种东西都能被**掉,而java代码基本上等同于开源的同义词。
用obfuscate只是为了增加反编译的难度,保护源代码的知识产权混淆包照常运行,没有任何问题可以使用反编译工具如jd-gui查看混淆后的包,验证混淆效果二.混淆技术名称混淆 name obfuscode
将有意义的类,字段、方法名称更改为无意义的字符串生成的新名称越 短,字节代码越小在名称混淆的字节代码中,包,类,字段和方法名称已重命名,并且永远不能恢复原始名称流混淆 Flow Obfuscation用于if, switch, while,for等关键字,对字节码进行细微的修改,模糊控制流,而不改变代码在运行时的行为。
通常情况下,选择和循环等逻辑构造会被更改,因此它们不再具有直接等效的Java源代码流模糊的字节码通常强制反编译器将一系列标签和非法的goto语句插入到它们生成的源代码中源代码有时会因为反编译错误而变得更加模糊。
其他异常混淆 Exception Obfuscation字符串加密混淆 String Encryption引用混淆 Reference Obfuscation三.常用工具1.proguardproguard是一个免费的 Java类文件的压缩,优化,混肴器。
它删除没有用的类,字段,方法与属性使字节码最大程度地优化,使用简短且无意义的名字来重命名类、字段和方法官网地址:https://www.guardsquare.com/en/products/proguard
2.yGuardyGuard是一款免费的Java混淆器(非开源),它有Java和.NET两个版本yGuard 完全免费,基于 Ant 任务运行,提供高可配置的混淆规则官网地址:https://www.yworks.com/products/yguard。
3.allatori第二代Java混淆器所谓第二代混淆器,不仅仅能进行字段混淆,还能实现流混淆命名混淆,流混淆,调试信息混淆,字符串编码,以及水印技术对于教育和非商业项目来说这个混淆器是免费的支持war和jar格式,支持对需要混淆代码的应用程序添加有效日期。
官网地址:http://www.allatori.com/4.总结推荐使用 proguard :开源, 使用简单 ,文档丰富完善四.工具对比工具官网地址官方文档开源免费名称混淆流混淆maven支持功能proguard
https://www.guardsquare.com/proguardhttps://www.guardsquare.com/manual/home√√✕√yGuardhttps://www.yworks.com/products/yguard
https://yworks.github.io/yGuard/√√✕√allatorihttps://allatori.com/✕(免费用于教育和非商业项目)√√√减小包大小;混淆代码;添加水印五.详细内容
1.yGuard(https://yworks.github.io/yGuard/)易于设置:yGuard 是一个 Ant 任务!作为 Ant 任务,yGuard 可以无缝集成到您在 Ant、Maven 和 Gradle 等众多构建系统中的部署过程中
高级收缩:yGuard 通过依赖分析提供精细的代码收缩功能可配置/安全代码:yGuard 提供高度可配置的名称混淆,可保护您的知识产权免受逆向工程开源:yGuard 是完全开源的!与昂贵的商业产品相反,yGuard 是并且永远都是免费的。
Java 兼容性:要运行 yGuard 软件,您需要 JDK 1.7.x 或更高版本以及 Ant 1.5.x 或更高版本(它可能与任一软件的早期版本兼容,但尚未经过测试)yGuard 与所有已发布的 Java 版本(最高 Java 17)兼容。
但是,根据使用的版本,功能可能会略有不同该文档包含不同版本支持的功能的详细说明如果您打算将 yGuard 与 Java 以外的东西一起使用,还有一个关于3rd 方 JVM 支持的部分ProGuard是一个开源的 Java 类文件收缩器、优化器、混淆器和预验证器。
因此,ProGuard 处理的应用程序和库更小、更快,并且在一定程度上可以抵御逆向工程收缩步骤检测并删除未使用的类、字段、方法和属性优化器步骤优化字节码并删除未使用的指令混淆步骤使用简短无意义的名称重命名剩余的类、字段和方法。
最后的预验证步骤将预验证信息添加到类中,这是 Java Micro Edition 和 Java 6 及更高版本所必需的yGuard1.maven引用方式
maven-antrun-plugin
>com.yworksyguard3.1.0
>packagerun
refid="maven.compile.classpath"name="mvn.classpath"/>
>2.yguard配置解析写在前面yguard共分为两大任务配置:
rename 混淆名称 :主要用于修改类名,属性名,方法名以及参数名等shrink 收缩代码 : 主要用于从多个入口点中删除所有无法访问的类、字段和方法keep keep是rename和shrink的子元素,用于指定从父级rename或shrink任务中排除的元素。
注意事项注意事项1 :如果项目需要shrink, shrink最好是配置在rename之前即在进行代码混淆之前,先进行代码压缩 因为压缩代码需要指定压缩的根代码举个例子:比如制定main方法: 。
如果先混淆,DplDbtransferApplication类名被修改的话(比如为A.class),该配置将会无效,所有代码都会被 shrink 删除,因为已经找不到DplDbtransferApplication这个类了(类名被修改)。
其他配置请参考官方文档配置说明基础配置
out="${project.build.directory}/${project.build.finalName}.${project.packaging}" />
createStubs="true">
class="${mainclass}" />
conservemanifest = "false"replaceClassNameStrings="true"scramble = "false"annotationClass="com.ewa.pipe.dbtransfer.dpl.Test"
>
value="pedantic"/> keep配置说明class元素class用于在rename和shrink过程中排除某些类,字段和方法。
其是keep的子元素以下是配置说明(- 表示会被收缩,即被删除 ):可见性(是否被收缩)publicprotectedfriendlyprivatenone----public*---protected
**--friendly***-private****属性说明name 指定要保留的类名 在shrink中,只会保留类名称,类中的属性和方法都会被删除掉classes 保持类的可见性 :其值是上述:none , public , protected , friendly , private 。
默认为nonemethods 保留方法的可见性 , 值同classes的描述默认为nonefields 保留属性的可见性 , 值同classes的描述默认为noneextends 保留对继承了该类的可见性 。
1.在shrink中凡是继承了该类的子类都不会被删除 2.在rename中凡是继承了该类的子类都不会被修改名称implements 保留对实现该接口的可见性 1.在shrink中凡是实现该接口的类都不会被删除。
2.在rename中凡是实现该接口的类都不会被修改名称注意事项以上属性可以单独使用,一可以混合使用其 extends/implements 可以和classes, methods,fields混合使用。
参考列2说明列1:
="public"methods="public"fields="public"/>
extends="com.arm.code.mix.base.BaseClass"/>列2:
>
="private"fields="private"/>
methods="private"fields="private"/>列3:一下举列几个模式集的列子,模式集可以参考ant
/> methodmethod 用于在rename和shrink过程中排除方法其是keep的子元素。
以下是配置说明(- 表示会被收缩,即被删除 ):
name="void main(java.lang.String[])"/>
/>
/>
name="com.mycompany.myapp.data.*"/>fieldfield 您可以按名称指定应从收缩或名称混淆中要保留的字段
name="field"/> 3.几种情况下的使用方式springboot项目
1.注意事项yguard插件执行要放在 spring boot打包项目之前,因为反置的话,会造成jar中的springboot的启动相关类被混淆,而造成启动项目失败2.项目使用失败的问题收集总结本地打包之后启动项目失败:由于是本地idea将jdk设置成jdk17了,导致打包失败。
设置为jdk8后成功启动项目使用mybaties plus,项目里只有一个接口:public interface TimePullLogMapper extends BaseMapper{} , 造成混淆后打包报错:spring至少一个bean实现。
后面加上: 后正常==service的接口和实现都要暴露,不然spring的注入和nacos的服务发现都会存在问题。
3.配置模版
>简介ProGuard 是一个开源的 Java 类文件收缩器、优化器、混淆器和预验证器因此,ProGuard 处理的应用程序和库更小、更快,并且在一定程度上可以抵御逆向工程收缩步骤检测并删除未使用的类、字段、方法和属性。
优化器步骤优化字节码并删除未使用的指令混淆步骤使用简短无意义的名称重命名剩余的类、字段和方法最后的预验证步骤将预验证信息添加到类中,这是 Java Micro Edition 和 Java 6 及更高版本所必需的。
对反射的处理反射和内省对于任何代码的自动处理都存在特殊的问题在 ProGuard 中,代码中动态创建或调用(即按名称)的类或类成员也必须指定为入口点例如,Class.forName()构造可以在运行时引用任何类。
通常不可能计算必须保留哪些类(使用它们的原始名称),因为类名可能是从配置文件中读取的,例如因此,您必须在 ProGuard 配置中指定它们,同样简单-keep选项Class.forName("SomeClass")
SomeClass.classSomeClass.class.getField("someField")SomeClass.class.getDeclaredField("someField")SomeClass.class.getMethod("someMethod", null)
SomeClass.class.getMethod("someMethod", new Class[] { A.class,... })SomeClass.class.getDeclaredMethod("someMethod", null)
SomeClass.class.getDeclaredMethod("someMethod", new Class[] { A.class,... })AtomicIntegerFieldUpdater.newUpdater(SomeClass.class, "someField")
AtomicLongFieldUpdater.newUpdater(SomeClass.class, "someField")AtomicReferenceFieldUpdater.newUpdater(SomeClass.class, SomeType.class, "someField")
支持可单独使用首先,下载一个ProGuard 版本或者构建 ProGuard从源头然后可以通过调用目录中的脚本直接从命令行执行 ProGuard bin:linux/mac:bin/proguard.sh -injars path/to/my-application.jar \ -outjars path/to/obfuscated-application.jar \ -libraryjars path/to/java/home/lib/rt.jar。
windows:bin\proguard.bat -injars path/to/my-applicati^ -outjars path/to/obfuscated-application.jar ^ -libraryjars path/to/java/home/lib/rt.jar
Gradle 模式ant模式Maven模式:(没有正式提供 maven 集成,也无法提供支持,但有可用的解决方案,但 Guardsquare 不保证它们提供的功能)来源实现:https://github.com/wvengen/proguard-maven-plugin。
https://github.com/dingxin/proguard-maven-plugin错误解析[proguard] Error: The input doesnt contain any classes. Did you specify the proper -injars options?
处理:com/ewa/pipe/**, inFilter标签设置为包路径地址,把‘.’换成‘/’ injar : 指定target中的一个目标地址:这里指定编译后的 classes文件夹。
inFilter 指定的是 classes的内部的文件夹(package)地址 com/arm/code/**
>classes以下是一个例子说明,如果你想更多的有用信息,请查看文档(
https://www.guardsquare.com/manual/configuration/usage)false
true
com/arm/code/**
classes${project.build.directory}
>${project.build.finalName}.${project.packaging}-target 1.8
-dontshrink-dontoptimize
-dontskipnonpubliclibraryclasses-dontskipnonpubliclibraryclassmembers
-allowaccessmodification
-useuniqueclassmembernames-keeppackagenames
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
-keepclassmembers public class * {void set*(***);*** get*();}
-keep class com.arm.code.mix.base.SpringBoot{
>; }
${java.home}/lib/rt.jar${java.home}/lib/jce.jar
${java.home}/lib/ext/sunjce_provider.jar