Java逆向小记(一)
目录
1 、 反编译
a) 由于 Java 代码会被编译为字节码,所以反编译 Java 代码成为可能。
b) 常用的反编译工具如 jad 等。
c) 如果在 javac 中添加了 -g ,可以生成所有调试信息,但如果添加了 -g:none ,则不会生成任何调试信息。
d) 如果使用了代码混淆工具,反编译后的代码可能还是不能成为可读的 Java 代码。
2 、 代码混淆
a) 通过代码混淆,可以防止算法或框架被逆向使用。
b) 可以通过删除调试信息,混乱命名,编码字符串,修改控制流(如大量 goto 语句),插入混淆代码(如大量 JVM INSTR ),删除无用代码,精简字节码等方式进行代码混淆。
c) 混淆后,会出现维护困难等问题。如动态加载类加载不到,反射不了,反序列化失败,命名空间冲突或错误。当然,这些问题可以通过一些方式解决,比如不修改。
d) 代码混淆后,也并非无法反编译。可以通过控制流、 API 等方式查看反编译结果,也可以远程调试来判断,当然,反编译的过程多少需要点运气。
3 、 修改类的非公共方法和变量
a) 对于非 private 属性,可以使用 -Xbootclasspath 置于引导类目录之前
b) 对于所有非 public 属性和方法,可以通过反射 setAccessible(true) 的方式访问
c) 但如果在启动参数中添加了 -Djava.security.manager 时,会出现 java.security.AccessControlException: access denied 问题
d) 对于 c) 的问题,需要修改 java policy ,赋予如下权限
grant {
permission java.lang.RuntimePermission “ accessDeclaredMembers ” ;
permission java.lang.reflect.ReflectPermission “ suppressAccessChecks ” ;
}
并在启动参数中,使用 -Djava.security.policy 指定此 java.policy
4 、 替换修改类
a) 当需要使用第三方库,却找不到公共 API 时;当使用第三方类或接口,却不够灵活时;当产品或 API 中有 Bug ,但你已经等不及发行者出补丁时;当你需要深度整合某个产品,但架构不够开放时;当使用第三方代码,运行结果不正确时,都需要替换和修改类。
b) 一般先找到启动点,跟踪到你需要修改的执行序列,出错堆栈很有帮助。
c) 搜索字符串也是一种方法,从日志、帮助文档中查找要修改的类。
d) 完成对已有的代码的修改后,可以直接替换原有包,或在 CLASSPATH 中将补丁路径设置在被替换包路径之前。可以在在替换代码中加入日志(比如在 static 块中)来确定新类被加载。
e) 另外,在 MANIFEST.MF 中有一个 Sealed 选项,用来限制所有本包中的类必须在同一个 JAR 包内,如果这样的话,把 Sealed 改成 false 就可以了。
f) 最后,要注意的是你替换或修改的类会不会给你带来法律上的麻烦。