标题: 闲谈Java逆向工程 创建: 2019-09-12 13:50 更新: 2020-03-05 15:31 链接: https://scz.617.cn/misc/201909121350.txt 无意中看到一个blog: https://www.cnblogs.com/hac425/ 捋了一遍,发现小伙子很能折腾,嗯,这种肯定不能是小姑娘。推荐给诸君,不局限 于Java逆向工程,他涉猎面较广。就Java逆向工程实践而言,推荐他的这几篇: -------------------------------------------------------------------------- 使用sa-jdi.jar dump内存中的class https://www.cnblogs.com/hac425/p/9416705.html 破解jeb mips 2.3.3 - [2017-11-2] https://www.cnblogs.com/hac425/p/9416950.html https://bbs.pediy.com/thread-222503.htm https://drive.google.com/open?id=1PJ5T3IgvYBhtq9_uAqQlpepjLA4uHPdA (jeb_2.3.3_demo_cracked.zip) 破解jeb 2.3.7 demo https://www.cnblogs.com/hac425/p/9416948.html -------------------------------------------------------------------------- hac425破解的是JEB DEMO版。 破解JEB这事我干过: -------------------------------------------------------------------------- https://bbs.pediy.com/thread-189980.htm 用Javassist分析jeb.jar - [2014-7-30] https://scz.617.cn/misc/201407301745.txt https://scz.617.cn/misc/201507271722.txt JEB 2.0.6 52pojie破解方案简评 - [2016-7-28] https://scz.617.cn/misc/201607281139.txt -------------------------------------------------------------------------- 1.5的DEMO版我给补齐了功能,网上最早的2.0.6版安装密码我给出来的,不过也因此 关上了一扇偷窥之门,要说不遗憾,是不可能的。很多人奇怪几年过去了为什么网上 只能找到2.2.7正式版的破解,这是因为我和bluerust干过的一件事,等他老了,你 们可以听他讲这个八卦。后来再未关注过JEB正式版破解,不知如今什么局面。 hac425这几篇提到Java逆向工程中的几大技术手段: Serviceability Agent(SA) BTrace Javassist 动态调试(他用的是IntelliJ IDEA,可以用别的) ClassFileTransformer SA有很多能力,我给个学习指南: -------------------------------------------------------------------------- 1) 利用SA查看JIT之后的汇编代码 2) 利用SA在内存中寻找bytecode 3) 利用SA、cdb定位bytecode对应的解释执行代码 4) sun.jvm.hotspot.CLHSDB 5) sun.jvm.hotspot.HSDB 6) 已知JIT后代码的地址,反查Java信息 -------------------------------------------------------------------------- 放狗搜,这都是成熟技术。 BTrace在这里: https://github.com/btraceio/btrace https://github.com/btraceio/btrace/wiki 用过Solaris的DTrace吗?BTrace有点类似。下面这个BTrace脚本用于查看 java.lang.System.exit()调用栈回溯: -------------------------------------------------------------------------- import com.sun.btrace.annotations.*; import static com.sun.btrace.BTraceUtils.*; @BTrace public class TracingScript { @OnMethod ( clazz = "java.lang.System", method = "exit" ) public static void TraceFunc ( ) { println( "jstack() is :" ); println( "[" ); jstack(); println( "]" ); } } -------------------------------------------------------------------------- 这有什么用呢?比如某些ReadyAPI的破解在使用过程中会不定时突然自动退出,所谓 闪退。用上述BTrace脚本很容易看到调用栈回溯: -------------------------------------------------------------------------- jstack() is : [ java.lang.System.exit(System.java) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(Method.java:498) org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93) groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325) groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1443) org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:891) org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:168) com.smartbear.ready.utils.ReflectionUtils.callMethod(ReflectionUtils.groovy:38) com.smartbear.ready.module.ConcurrentXmlLoadProcess.a(ConcurrentXmlLoadProcess.java:149) com.smartbear.ready.module.ConcurrentXmlLoadProcess.a(ConcurrentXmlLoadProcess.java:125) com.smartbear.ready.module.ConcurrentXmlLoadProcess.b(ConcurrentXmlLoadProcess.java:102) com.smartbear.ready.module.ConcurrentXmlLoadProcess.a(ConcurrentXmlLoadProcess.java:90) com.smartbear.ready.module.ConcurrentXmlLoadProcess$1.run(ConcurrentXmlLoadProcess.java:83) java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) java.util.concurrent.FutureTask.run(FutureTask.java:266) java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) java.lang.Thread.run(Thread.java:748) ] -------------------------------------------------------------------------- 据此处理com.smartbear.ready.module.ConcurrentXmlLoadProcess类即可解决闪退。 跟gdb一样,BTrace有两种用法,一种是启动时用,一种是Attach时用。第一种用法 需要事先将BTrace脚本用BTrace自带工具编译成class再用,第二种用法就保持脚本 源码状态即可。如果是第二种用法,推荐在VisualVM中安装"BTrace Workbench"插件, 就不需要单独安装BTrace了。我用BTrace剁过soapUI Pro、JEB等,这种东西看别人 说没感受,得用,用过都说好。 VisualVM在这里: https://visualvm.github.io/index.html https://visualvm.github.io/gettingstarted.html Javassist在这里: http://jboss-javassist.github.io/javassist/ Getting Started with Javassist http://www.javassist.org/tutorial/tutorial.html 《用Javassist分析jeb.jar》以及hac425的JEB破解都给出很好的演示,如果从未用 过,现在用起不算晚。有些人修改复杂jar包时,很费劲地反编译、修改、再编译, 用Javassist可以避开很多麻烦。 -------------------------------------------------------------------------- import javassist.*; import javassist.bytecode.*; class Modify_Protection { private static void Modify_LicenseReader () throws Throwable { ClassPool pool; CtClass old_class; CtMethod old_method; String MethodName; pool = ClassPool.getDefault(); old_class = pool.get( "com.jp.protection.pub.LicenseReader" ); MethodName = "isSkipEncryption"; old_method = old_class.getDeclaredMethod( MethodName ); old_method.setBody ( "{" + " return( true );" + "}" ); old_class.detach(); old_class.writeFile( "./Javassist/Protection-4.6" ); } /* end of Modify_LicenseReader */ public static void main ( String[] argv ) throws Throwable { Modify_LicenseReader(); } } -------------------------------------------------------------------------- 这是一个简单Javassist示例,编译、运行上述代码,将修改函数: com.jp.protection.pub.LicenseReader.isSkipEncryption() 使之恒返回true。为什么干这事?我在看雪上提过: soapUI Pro 4.5.1的新破解方案 - [2012-10-29] https://bbs.pediy.com/thread-158097.htm 在这篇我提供了一个示例性质的scz.key,结果后来soapUI Pro的绝大多数破解都在 用它,直至新一代的ReadyAPI出现。 原理很简单,com.jp.protection.pub.LicenseReader.decodeLicense()判断了 isSkipEncryption()的返回值,如果返回true,就不对key文件进行公钥解码,而直 接使用明文状态的key文件。显然,明文状态的key文件,想让它哪天到期都可以。 Patch如下class: com.smartbear.ready.module.ConcurrentXmlLoadProcess com.jp.protection.pub.LicenseReader 就完成了ReadyAPI的破解,但不能通过GUI安装伪造版License,必须手工放入: %USERPROFILE%\.soapui\soapui.key %USERPROFILE%\.loadui\loadUI.key %USERPROFILE%\.readyapi\servicev.key 对于非Windows用户,比如Mac用户,这个目录不同。考虑到用户友好性,还是想通过 GUI安装伪造版License,此时需要修改另一个函数: com.smartbear.ready.license.util.LicenseUtil.isTrialActivationAvailable() 使之恒返回true,即可通过GUI安装伪造版License。属于锦上添花型,不是必须的。 再说一下JEB。hac425提到新版JEB支持MIPS反编译,这是啥意思,可以理解成MIPS版 Hex-Rays? 没用过IDEA,我是用Eclipse动态调试。hac425提到可以在IDEA动态调试JEB时直接调 用JEB的函数完成对字符串的反混淆,有点意思,我理解这类似在gdb里call目标进程 的一个函数。 他还提到把jar转成dex,然后用JEB静态分析。不过对于PC上的jar,JD-GUI、Luyten 这些足够了,最主要的是后面这几个都是免费使用。 本来想写一篇《ReadyAPI逆向工程》,发现有人在2015年写过: 试手破解soapUI and readyAPI - [2015-10-02] https://blog.csdn.net/gogcc/article/details/48859225 他把需要Patch的点都提到了。八个小卦,上文里面说"发现一个真理",那篇就是 《soapUI Pro 4.5.1的新破解方案》。 假设申请了ReadyAPI试用版License,有14天(2周)试用期,可以用RunAsDate之类的 工具欺骗程序运行时间而长久使用,也可以Patch这里: com.jp.protection.pub.LicenseBaseImpl.setLicenseExpireDate() 想多久就多久。不过,还是伪造License显得是那么回事。 CSDN上一堆高分下载ReadyAPI破解,我没试过。现在天朝技术研究环境艰难,值此中 秋来临之际,友情提供临时下载点: https://scz.617.cn/private/ReadyAPI-x64-2.8.2.exe https://scz.617.cn/private/ReadyAPI-x64-2.8.2-crack-ex.7z (已失效,勿试) 随时可能删除,各位随缘下载,不谢。话说那些CSDN赚分的,你们太TM黑,本怪看不 下去了。 此破解未经广泛测试,本人WEB安全白痴一枚,无力测试SOAP相关功能,可能有重大 BUG,仅供学习参考。 我准备掏1000块钱请郑同舟花周末两天时间教会我SOAP,然后我跨洋教会bluerust, 再然后我们仨一起出去打怪。嗯,这一段是胡扯。