吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 23674|回复: 35
收起左侧

[原创] FineReport 8.0 注册分析

  [复制链接]
benzcomp 发表于 2018-10-30 10:09
FineReport 8.0的注册使用RSA加密,关于RSA算法很容易搜到,破解思路就是,替换原版的公钥,用自己的RSA私钥加密格式化的注册信息,即可成功注册。
首先,加解密算法在FRCoreContext.class里,通过反编class文件可以得到FRCoreContext的源码,可以得到RSA的N、e,用他们就可以吧正版的license文件解密。
通过对FRCoreContext的分析可以知道,license的生成算法是:
1、license授权信息的HEX每32字节分成若干组;
2、每组前导插入7F;
3、各组做RSA加密运算;
4、各组之间插入RSA的N值,最终得到的HEX串就是注册文件的二进制内容。

license制作步骤:
1、按照格式编辑lic文件明文,如下格式:
{"BI_MAKER":"0","CONCURRENCY":"0","FS_USER":"0","PRICE":"","APPNAME":"","MACADDRESS":"","BI_USER":"0","FUNCTION":"265735294061","ISAFTER701":true,"MOBILE_FS_USER":"0","REPORTLETSCOUNT":"","APPCONTENT":"","DEADLINE":4102444799499,"VERSION":"8.0","reportletscount":"","PRINCIPAL":"","COMPANYNAME":"","UUID":"","MUTICONNECTION":"0","BI_MOBILE":"0","PROJECTNAME":"","KEY":""}
对于这段明文来说    "DEADLINE":4102444799499    (2100-1-1到1970-1-1的毫秒数)
                    "FUNCTION":"265735294061"  (定制版对应的编号,可以在fr-core-8.0.jar中的FUNC.class找到定义)
保存成UTF-8编码格式的文本文件 lic.txt
2、用WinHEX打开lic.txt,复制HEX码
3、文件明码的HEX码每64个字符为一组分割,最前面加"7F"或"7E"、"7D"等,目的是让加密后的密文保证为256位字符,
4、RSA分组加密,加密后的密文要保证双字节数256个(手工做的话可以使用,大数计算器等程序)
5、每一组中间插入公钥(N),结尾不加!最终是一串6400位的字符。
6、用WinHEX粘贴ascii-hex,保存文件就是 FineReport.lic 了
7、用winrar打开fr-core-8.0.jar,拖出 com\fr\base\FRCoreContext.class
8、用UltraEdit找原版的N,用自己的 N 替换
9、再把FRCoreContext.class替换回去
10、替换fr-core-8.0.jar文件
11、FineReport.lic 放到 resources 目录下

如上方式替换文件的方法,有一个缺点,每次升级fr-core-8.0.jar都会被替换为新版本,还需要再次操作第7-11步,后来想到一个不影响升级的办法:
把fr-core-8.0.jar复制一份,并且重命名为cr_FRCoreContext.jar,文件名可以随意命名,只要保证文件名升序排序,在fr-core-8.0.jar之前就行。
用winrar打开cr_FRCoreContext.jar,把cr_FRCoreContext.jar\com\fr\base\FRCoreContext.class以外的所有文件都删掉,然后用替换N的FRCoreContext.class覆盖同名文件。
最后,把cr_FRCoreContext.jar放到\WebReport\WEB-INF\lib目录里,只要能排在fr-core-8.0.jar前面就行了。
===========================================================================================
[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
FRCoreContext源码:
public class FRCoreContext
{
  public static final ThreadLocal TMAP = new ThreadLocal();
  private static byte[] lic_bytes = null;
  private static byte[] lock_bytes = null;
  private static final long ONE_YEAR_MILLISECOND = 31536000000L;
  private static final int MAX_DIGIT = 255;
  private static boolean onlinePassed = true;
  private static String;
  private static final String uuid = UUID.randomUUID().toString();
  private static final long ONLINE_CHECK_TIME_DELAY = 0L;
  private static final long ONLINE_CHECK_TIME_PERIOD = 10800000L;
  private static Timer ONLINE_CHECK_TIMER;
  private static int failCount;
  private static boolean shouldFireLicChange = false;
  private static final int MAX_FAIL_COUNT = 8;
  private static final BigInteger N = new BigInteger("61103299352066102812915201580370346997919089893149305765565972348630053713717591736527153881172892494135635969333391530396986735629281282430026953431657619628355730192943385620088393498664105803897708601718035436482482749378713844253725606147581454234307387984660050507963063894825237808748868429675256901161");  //RSA的N
  private static final BigInteger D = new BigInteger("65537");
 
  …… 
    private static String byte2hex(byte[] paramArrayOfByte)    //byte转hex码,paramArrayOfByte输入license文件
  {
    StringBuffer localStringBuffer = new StringBuffer();
    String str = "";
    for (int i = 0; i < paramArrayOfByte.length; i++)
    {
      str = Integer.toHexString(paramArrayOfByte[i] & 0xFF);
      if (str.length() == 1) {
        localStringBuffer.append('0');
      }
      localStringBuffer.append(str);
    }
    return localStringBuffer.toString().toUpperCase();
  }
 
  private static void decode(String paramString, OutputStream paramOutputStream)  //解密函数
  {
    String[] arrayOfString = paramString.split(byte2hex(N.toByteArray()));        //删除license中插入的 N ,还原出有效注册信息的加密内容
    try
    {
      for (int i = 0; i < arrayOfString.length; i++) {
        paramOutputStream.write(tinyDecode(hex2byte(arrayOfString[i])));        //删掉密文数组的第一个元素,然后tinyDecode执行RSA解密,得到license明文[/i][/i][i][i]
      }                                                                               
    }
    catch (IOException localIOException)
    {
      FRContext.getLogger().error(localIOException.getMessage(), localIOException);
    }
  }
……
  private static byte[] hex2byte(String paramString)    //hex转byte
  {
    if (paramString == null) {
      return null;
    }
    int i = paramString.length();
    if (i % 2 == 1) {                                                //每一段加密后的密文必须保证双字节数256个,而要保证双字节靠每一段明文前面插入的7F、7E等来控制,反正最后都是要截掉的,插入的字符就是控制密文长度的作用
      return null;
    }
    byte[] arrayOfByte = new byte[i / 2];
    for (int j = 0; j != i / 2; j++) {
      arrayOfByte[j] = ((byte)Integer.parseInt(paramString.substring(j * 2, j * 2 + 2), 16));
    }
    return arrayOfByte;
  }
 
 
  private static byte[] tinyDecode(byte[] paramArrayOfByte)    //RSA解密算法
  {
    paramArrayOfByte = new BigInteger(paramArrayOfByte).modPow(D, N).toByteArray();
    return ArrayUtils.subarray(paramArrayOfByte, 1, paramArrayOfByte.length);
  }
}

免费评分

参与人数 4威望 +1 吾爱币 +10 热心值 +3 收起 理由
wcb0414 + 1 这种方法对新发布的8.0是没有用的,新版本的N值除了这里有一个,还有一个在.
Hmily + 1 + 8 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
兲之墨脉 + 1 + 1 谢谢@Thanks!
qaz003 + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

guoki 发表于 2018-11-16 09:47
benzcomp 发表于 2018-11-9 19:20
10已搞定
谁有V2 Conference 7.0的版本,可以找我来换

楼主 可以说下10的思路吗? 我现在使用 instrument + javassist 去把 类加载器 加载的隐藏类 dump出来 ..
这些加载文件好像还加密的,难道真的要去反编译 fineassist.dll文件吗?
 楼主| benzcomp 发表于 2018-11-11 16:58
xdnice 发表于 2018-11-10 22:23
请大神提供下思路,我现在找不到dealFragment这个方法,不知道怎么入手了。

看这个吧
FineReport 9.0 注册分析
https://www.52pojie.cn/thread-819149-1-1.html
(出处: 吾爱破解论坛)
redapple2015 发表于 2018-10-30 10:34
cnitren 发表于 2018-10-30 10:40
这个牛,不过能力有限,还是看不太懂!
zxpr 发表于 2018-10-30 10:57
学习以后,以后说不定会用到呢
xie83544109 发表于 2018-10-30 10:58

多谢楼主分享哟
收徒不,有偿的
明晓林 发表于 2018-10-30 13:58
老铁很稳啊,不过8.0用户貌似不多,大部分还在7
andyzgs 发表于 2018-10-30 14:06
mark一下,以后肯定用的着。。
coolfire1983 发表于 2018-10-30 16:14
学习了 ,对我来说 有点复杂啊!
i-ii 发表于 2018-10-30 21:55
好东西啊,谢谢楼主分享
0531chuxin 发表于 2018-10-30 21:59
感觉挺厉害的啊
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-5-25 10:39

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表