准备工作

  1. 下载原始jar包:aspose-html-22.8-jdk11.jar
  2. 准备反编译工具,这里推荐使用jd-gui或者jadx

破解思路

  • Aspose 系列产品主要依赖许可证文件(license.xml)的注册来工作。首先,让我们看看 Aspose 是如何注册许可证的:
1
2
3
4
5
6
7
8
9
InputStream is;
try {
is = Files.newInputStream(Paths.get("C:\\xxx\\license.xml"));
License license = new License();
license.setLicense(is);
is.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
  • license.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<License>
<Data>
<Products>
<Product>Aspose.Total for Java</Product>
<Product>Aspose.Words for Java</Product>
</Products>
<EditionType>Enterprise</EditionType>
<SubscriptionExpiry>20991231</SubscriptionExpiry>
<LicenseExpiry>20991231</LicenseExpiry>
<SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>
</Data>
<Signature>
sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=
</Signature>
</License>
  • 破解的思路很简单,就是查看 setLicense 方法中实际做了哪些操作,然后对源码进行修改。我们使用 JD-GUI 反编译 jar 包,找到 License 类,位于 com.aspose.html 包下。

  • 我们可以看到有两个 setLicense 方法,而代码中调用的是第二种形式。

  • 这里使用了传入的文件流,我们可以重点查看z16调用的m1方法:

1
z16.m1(byteArrayInputStream);
  • 我们进入 z16 类,逐步查看里面的实现,找到一个可疑的方法。

  • 在这段代码中,m1 方法的主要功能是验证许可文件的签名,以确保文件的合法性和未被篡改。

    1. 获取许可类型:
    • 通过 switch 语句,根据许可的类型(如 “Professional” 或 “Enterprise”)进行区分,以确定许可文件的类型。
    1. 处理节点数据:
    • 将传入的 XML Node 数据转化为字符串并以 UTF-16LE 编码转换为字节数组 (arrayOfByte1)。
    • 从第二个节点 paramNode2 中提取 Base64 编码的签名,并将其解码为字节数组 (arrayOfByte2)。
    1. 选择签名算法:
    • 根据许可文件的安全要求,选择使用 SHA1withRSA 或 SHA256withRSA 作为签名算法。如果系统启用了 FIPS 安全模式,则需要使用 FIPS 认证的提供程序 (m186)。
    1. 公钥选择:
    • arrayOfString1 和 arrayOfString2 数组中存储了多个可能的公钥或公钥片段,通过索引选择合适的公钥。
    • 使用 m5 方法从字符串中生成公钥 (PublicKey)。
    1. 签名验证:
    • 使用 initVerify 方法初始化公钥验证。
    • 调用 update 方法传入已编码的数据字节数组 (arrayOfByte1),然后使用 verify 方法验证 Base64 解码后的签名 (arrayOfByte2) 是否匹配。
    1. 返回结果:
    • 验证成功后返回许可状态 paramz3,如果验证失败,则抛出异常并返回失败状态 (z3.m205)。
  • 那么破解的思路非常简单:直接让这个方法返回 paramz3 就行了。

修改字节码文件

  • 接下来,我们使用 Javassist 修改字节码文件。首先添加依赖:
1
2
3
4
5
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.28.0-GA</version>
</dependency>
  • 我们只需要需要修改 z16 类中的 m1(Node node, Node node2, z3 z3Var) 方法,让它直接返回 paramz3。修改的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
try {
String jarPath = "D:\\html\\aspose-html-22.8-jdk11.jar";
ClassPool classPool = ClassPool.getDefault();
classPool.insertClassPath(jarPath);

// z16类里的m1方法,同时三个参数类型分别是Node, Node, z3,这个z3我找了一下,是z16里的一个枚举类
CtClass ctClass = classPool.getCtClass("com.aspose.html.z16");
CtClass[] paramTypes = new CtClass[3];
paramTypes[0] = classPool.get("org.w3c.dom.Node");
paramTypes[1] = classPool.get("org.w3c.dom.Node");
paramTypes[2] = classPool.get("com.aspose.html.z16f$z3");
CtMethod ctMethod = ctClass.getDeclaredMethod("m1", paramTypes);

// 修改方法体,使其直接返回第三个参数
ctMethod.setBody("{\n" +
" return $3;\n" +
" }");

ctClass.writeFile("D:\\html\\");

System.out.println("Modification completed successfully.");
} catch (Exception e) {
e.printStackTrace();
}
  • 编译执行之后会生成一个.class文件,我们把这个.class文件替换到原来的jar包中,并且删除jar包中原本的.RSA和.SF文件,使用mvn install安装一下这个jar包就可以调用了。

注意事项

  • ASPOSE.SLIDE、ASPOSE.WORDS等其他产品,破解思路基本都是一样的,都是看setLicense方法的实现,然后修改源码。
  • 破解版的 jar 包可能存在后台向外部服务器发送数据的风险,因此本文仅限于学习研究,不涉及商业用途。请勿将其用于非法活动。

怎么偷偷用?

  • 且听下回分解,这周就休一天,歇了