无为清净楼资源网 Design By www.qnjia.com
本来不想再跟进FR的解密,前几天看到“FXXXXRXXXXX 10.0 另一破解思路”(https://www.52pojie.cn/thread-1117200-1-1.html)这篇文章,只是想以此做下尝试。
反向过程中发现,classx文件的加密又有所改变,以往发布的方法完全照做已无法轻松实现PJ,特此再做一下经验分享吧。
关于思路及关键文件分析请参考以前发布的文章https://www.52pojie.cn/thread-1012601-1-1.html,在此不再赘述。
总体原则:不对官方文件进行修改,减少不必要的人为麻烦,只采用外挂拦截或修改配置文件方式,动态PJ,尽量不影响在线升级。
以前的PJ方式就是,重写com.fr.license.selector.EncryptedLicenseSelector,修改解密函数decrypt(),返回注册明文,然后,使其在真正的类前加载实现的。
但是,好像是在3月份的某一个版本后,10.0和11.0的发布版本都对该方法的PJ进行了反制。
老版本:
[Java] 纯文本查看 复制代码
新版本:
[Java] 纯文本查看 复制代码
唯一的区别是decrypt()添加了native 前缀,而且,其他方法的注册认证也不再调用getBytes(),而是改为直接调用decrypt(),所以,老方法就失效了,修改后的com.fr.license.selector.EncryptedLicenseSelector被提前加载后,系统启动会挂起其他模块对该native函数的调用过程。
那么,如何使原来的方法继续有效?“FXXXXRXXXXX 10.0 另一破解思路”一文提供了有效的思路:
仍然使用修改版的EncryptedLicenseSelector,然后,利用 Java Instrumentation 去拦截。
操作步骤:
1、构建com.fr.license.selector.EncryptedLicenseSelector
[Java] 纯文本查看 复制代码
构建生成com.fr.license.selector.EncryptedLicenseSelector.class文件,待用;
2、构建FineCrackAgent
借用2316361和Teahome的代码,在此,一并表示感谢。
git clone 2316361 的分享 https://github.com/2316361/FineCrack
修改FineCrackAgent.java
[Java] 纯文本查看 复制代码
构建生成FineCrack-jar-with-dependencies.jar
3、加密com.fr.license.selector.EncryptedLicenseSelector.class
文章开始所说的classx文件加密方式的改变。
老版本是对class全文件进行RSA加密(具体加密方式参考9.0和10.0版本的分析),新版本加密改为:
a、只对文件每256字节的前24字节进行加密;
b、文件结尾不足256字节部分,超过24字节长度时,不加密;不足24字节时,加密。
按照该加密规则,完成两次加密后,打包成jar,放入fine-core-11.0.jar相同目录。
4、FineCrack-jar-with-dependencies.jar随便放到哪个目录
修改X:\FineReport_11.0\bin\designer.vmoptions 增加 -javaagent:X:\FineReport_11.0\FineCrack-jar-with-dependencies.jar
tomcat、resin等部署时,在JAVA_OPTS增加探针破解库路径,如:
JAVA_OPTS="$JAVA_OPTS -javaagent:/usr/local/tomcat8/webapps/webroot/WEB-INF/lib/FineCrack-jar-with-dependencies.jar"
5、注册文件fanruan.lic
格式没变,只要修改版本号即可
[XML] 纯文本查看 复制代码
反向过程中发现,classx文件的加密又有所改变,以往发布的方法完全照做已无法轻松实现PJ,特此再做一下经验分享吧。
关于思路及关键文件分析请参考以前发布的文章https://www.52pojie.cn/thread-1012601-1-1.html,在此不再赘述。
总体原则:不对官方文件进行修改,减少不必要的人为麻烦,只采用外挂拦截或修改配置文件方式,动态PJ,尽量不影响在线升级。
以前的PJ方式就是,重写com.fr.license.selector.EncryptedLicenseSelector,修改解密函数decrypt(),返回注册明文,然后,使其在真正的类前加载实现的。
但是,好像是在3月份的某一个版本后,10.0和11.0的发布版本都对该方法的PJ进行了反制。
老版本:
[Java] 纯文本查看 复制代码
import com.fr.license.selector.AbstractLicenseSelector;import com.fr.license.selector.EncryptedLicenseSelector;import com.fr.log.FineLoggerFactory;import com.fr.stable.Hidden;@Hiddenpublic abstract class EncryptedLicenseSelector extends AbstractLicenseSelector { byte[] getBytes() { byte[] arrayOfByte = readRawBytes(); return decrypt(arrayOfByte); } protected void decryptFailed(Throwable paramThrowable) { FineLoggerFactory.getLogger().error("Read license failed." + paramThrowable.getMessage(), paramThrowable); } abstract byte[] readRawBytes(); public byte[] decrypt(byte[] paramArrayOfbyte);}
新版本:
[Java] 纯文本查看 复制代码
import com.fr.license.selector.AbstractLicenseSelector;import com.fr.license.selector.EncryptedLicenseSelector;import com.fr.log.FineLoggerFactory;import com.fr.stable.Hidden;@Hiddenpublic abstract class EncryptedLicenseSelector extends AbstractLicenseSelector { byte[] getBytes() { byte[] arrayOfByte = readRawBytes(); return decrypt(arrayOfByte); } protected void decryptFailed(Throwable paramThrowable) { FineLoggerFactory.getLogger().error("Read license failed." + paramThrowable.getMessage(), paramThrowable); } abstract byte[] readRawBytes(); public native byte[] decrypt(byte[] paramArrayOfbyte);}
唯一的区别是decrypt()添加了native 前缀,而且,其他方法的注册认证也不再调用getBytes(),而是改为直接调用decrypt(),所以,老方法就失效了,修改后的com.fr.license.selector.EncryptedLicenseSelector被提前加载后,系统启动会挂起其他模块对该native函数的调用过程。
那么,如何使原来的方法继续有效?“FXXXXRXXXXX 10.0 另一破解思路”一文提供了有效的思路:
仍然使用修改版的EncryptedLicenseSelector,然后,利用 Java Instrumentation 去拦截。
操作步骤:
1、构建com.fr.license.selector.EncryptedLicenseSelector
[Java] 纯文本查看 复制代码
import com.fr.license.selector.AbstractLicenseSelector;import com.fr.license.selector.EncryptedLicenseSelector;import com.fr.log.FineLoggerFactory;import com.fr.stable.Hidden;@Hiddenpublic abstract class EncryptedLicenseSelector extends AbstractLicenseSelector {byte[] getBytes() {byte[] arrayOfByte = readRawBytes();return decrypt(arrayOfByte);}protected void decryptFailed(Throwable paramThrowable) {FineLoggerFactory.getLogger().error("Read license failed." + paramThrowable.getMessage(), paramThrowable);}abstract byte[] readRawBytes();public byte[] decrypt(byte[] paramArrayOfbyte);}
构建生成com.fr.license.selector.EncryptedLicenseSelector.class文件,待用;
2、构建FineCrackAgent
借用2316361和Teahome的代码,在此,一并表示感谢。
git clone 2316361 的分享 https://github.com/2316361/FineCrack
修改FineCrackAgent.java
[Java] 纯文本查看 复制代码
package crack;import crack.transformer.MultiMethodTransformer;import crack.transformer.SingleMethodTransformer;import javassist.ClassPool;import javassist.CtClass;import java.lang.instrument.ClassDefinition;import java.lang.instrument.Instrumentation;public class FineCrackAgent { public static void agentmain(String args, Instrumentation inst) throws Exception { ClassPool pool = new ClassPool(true); CtClass cl = pool.get("java.lang.reflect.Modifier"); cl.getDeclaredMethod("isNative").setBody("{ return true; }"); inst.redefineClasses(new ClassDefinition[] { new ClassDefinition(Class.forName(cl.getName(), false, null), cl.toBytecode()) }); System.out.println(cl.getName() + " 替换完成!"); Class<?>[] classes = inst.getAllLoadedClasses(); for (Class<?> clazz : classes) { String name = clazz.getName(); if (name.equals("com.fr.license.security.LicFileRegistry")) { inst.addTransformer(new SingleMethodTransformer(name, "check", 1, 2, new byte[]{4, -84}, null), true); inst.retransformClasses(clazz); System.out.println(name + " 替换完成!"); } if (name.equals("com.fr.license.entity.AbstractLicense")) { inst.addTransformer(new MultiMethodTransformer(name, "support", 1, 2, new byte[]{4, -84}, null), true); inst.retransformClasses(clazz); System.out.println(name + " 替换完成!"); } if (name.equals("com.fr.license.selector.EncryptedLicenseSelector")) { inst.addTransformer(new SingleMethodTransformer(name, "decrypt", 1, 2, new byte[]{43, -80}, null), true); inst.retransformClasses(clazz); System.out.println(name + " 替换完成!"); } } }}
构建生成FineCrack-jar-with-dependencies.jar
3、加密com.fr.license.selector.EncryptedLicenseSelector.class
文章开始所说的classx文件加密方式的改变。
老版本是对class全文件进行RSA加密(具体加密方式参考9.0和10.0版本的分析),新版本加密改为:
a、只对文件每256字节的前24字节进行加密;
b、文件结尾不足256字节部分,超过24字节长度时,不加密;不足24字节时,加密。
按照该加密规则,完成两次加密后,打包成jar,放入fine-core-11.0.jar相同目录。
4、FineCrack-jar-with-dependencies.jar随便放到哪个目录
修改X:\FineReport_11.0\bin\designer.vmoptions 增加 -javaagent:X:\FineReport_11.0\FineCrack-jar-with-dependencies.jar
tomcat、resin等部署时,在JAVA_OPTS增加探针破解库路径,如:
JAVA_OPTS="$JAVA_OPTS -javaagent:/usr/local/tomcat8/webapps/webroot/WEB-INF/lib/FineCrack-jar-with-dependencies.jar"
5、注册文件fanruan.lic
格式没变,只要修改版本号即可
[XML] 纯文本查看 复制代码
{"VERSION":"11.0","DEADLINE":4102444799499,"CONCURRENCY":"0"}
无为清净楼资源网 Design By www.qnjia.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
无为清净楼资源网 Design By www.qnjia.com
暂无评论...
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
2024年09月29日
2024年09月29日
- 纪钧瀚《钢琴阅读时光 雨中书店聆听轻音乐》[FLAC/分轨][399.62MB]
- 证声音乐图书馆《走向自然 疗心爵士乐》[320K/MP3][87.4MB]
- 证声音乐图书馆《走向自然 疗心爵士乐》[FLAC/分轨][184.94MB]
- 陈慧娴.2018-Priscilla-Ism演唱会3CD(2024环球红馆40复刻系列)【环球】【WAV+CUE】
- 郑秀文.1999-我应该得到(国)【华纳】【WAV+CUE】
- 陈家慧.2011-钢琴酒吧2CD【龙吟唱片】【WAV+CUE】
- 证声音乐图书馆《雨季 蓝调吉他 Rainy Blues》[320K/MP3][45.01MB]
- 证声音乐图书馆《雨季 蓝调吉他 Rainy Blues》[FLAC/分轨][109.13MB]
- 赞多《序章》[320K/MP3][45.54MB]
- 许巍.2004-每一刻都是崭新的【步升大风】【WAV+CUE】
- 群星.2024-四方馆影视原声带【韶愔音乐】【FLAC分轨】
- 陈雷.1997-安锁咧【金圆唱片】【WAV+CUE】
- 关淑怡.2013-MY.FAVORITE.SK.3CD【环球】【WAV+CUE】
- Sweety.2006-花言乔语【丰华】【WAV+CUE】
- 李恕权.2003-回·20年全精选2CD【SONY】【WAV+CUE】