Aspose最版本aspose-words:jdk17:23.6 版本,代码分析心得
aspose 为收费软件,以下仅仅用于学习技术,请勿做任何商业用途,如果需要请到官网购买正版!
本文的逆向分析参考了了博客: https://blog.youkuaiyun.com/qiumin333/article/details/130177125
POM配置如下:
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-words</artifactId>
<version>23.6</version>
<classifier>jdk17</classifier>
</dependency>
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-words</artifactId>
<version>23.6</version>
<classifier>javadoc</classifier>
</dependency>
<repositories>
<repository>
<id>AsposeJavaAPI</id>
<name>Aspose Java API</name>
<url>https://releases.aspose.com/java/repo/</url>
</repository>
</repositories>
代码逆向分析:
License类:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.aspose.words;
import com.aspose.words.internal.zzYal;
import com.aspose.words.internal.zzZE5;
import java.io.InputStream;
public class License {
public License() {
zzYal.zzZ9g();
}
public void setLicense(String licenseName) throws Exception {
if (licenseName == null) {
throw new NullPointerException(zzYal.zzZ9g().zzWkU(new byte[]{105, 108, 101, 99, 115, 110, 78, 101, 109, 97, 101}));
} else {
(new zzWXG()).zzZyR(licenseName, zzZE5.zzW3M());
}
}
public void setLicense(InputStream stream) throws Exception {
if (stream == null) {
throw new NullPointerException(zzYal.zzZ9g().zzWkU(new byte[]{116, 115, 101, 114, 109, 97}));
} else {
new zzWXG();
zzWXG.zzYFZ(stream);
}
}
}
zzWXG类 zzYFZ方法:
static void zzYFZ(InputStream var0) throws Exception {
if (var0 == null) {
throw new NullPointerException(zzYal.zzZ9g().zzWkU(new byte[]{116, 115, 101, 114, 109, 97}));
} else {
zzYKl var1 = zzws(var0);
zzX54(var1);
if (var1.zzWtQ()) {
throw new IllegalStateException(zz0D.zzY5k(zzZHl.zzZVX(zzWjW.zzXGO()), new Object[]{var1.zzY0M().zzY5k(zzYal.zzZ9g().zzWkU(new byte[]{100, 100, 77, 32, 77, 77, 121, 32, 121, 121, 121}), zzXP5.zzYP8()), zzYKl.zzZlw().zzY5k(zzYal.zzZ9g().zzWkU(new byte[]{100, 100, 77, 32, 77, 77, 121, 32, 121, 121, 121}), zzXP5.zzYP8())}));
} else if (var1.zzWgw()) {
throw new IllegalStateException(zzZHl.zzZVX(zzWjW.zzXbd()));
} else {
/* 把注册成功的解析完成的注册信息放到数组中
这里很关键,最终我们要构造一个 zzYKl 对象放到 zzZzA数组中去
*/
synchronized(zzXNY) {
if (zzZzA.indexOf(var1) == -1) {
zzZzA.add(var1);
}
}
}
}
}
// zzws方法 ,主要看 几个会抛异常的方法 var7.zzYJ1() 和 !zzZGo(var7.getData(), var7.zzYnU(), var7.zzWrz())
private static zzYKl zzws(InputStream var0) throws Exception {
DocumentBuilderFactory var1 = zzXsu.zzsM();
DocumentBuilder var2 = var1.newDocumentBuilder();
Document var3 = var2.parse(var0);
Element var4 = var3.getDocumentElement();
Element var5 = zzv8(var4, zzYal.zzZ9g().zzWkU(new byte[]{97, 68, 97, 116}));
Element var6 = zzv8(var4, zzYal.zzZ9g().zzWkU(new byte[]{105, 83, 110, 103, 116, 97, 114, 117, 101}));
if (var5 != null && var6 != null) {
zzYKl var7 = zzX54(var5, var6);
//注册码是否有效
if (var7.zzYJ1() == 0) {
throw new IllegalStateException(zzZHl.zzZVX(zzWjW.zzXab()));
// 验证签名 getData() Data标签数据,zzYnU() Signature标签数据,zzWrz() 1
} else if (!zzZGo(var7.getData(), var7.zzYnU(), var7.zzWrz())) {
throw new IllegalStateException(zzZHl.zzZVX(zzWjW.zzVT5()));
} else {
return var7;
}
} else {
throw new IllegalStateException(zzZHl.zzZVX(zzWjW.zzYyR()));
}
}
破解Java方法(只需要在程序启动的时候调用这个方法一次即可):
/**
* aspose-words:jdk17:23.6 版本
*/
public static void registerWord() {
// 构造一个注册信息
try {
Class<?> zzXgCClass = Class.forName("com.aspose.words.zzYKl");
Constructor<?> constructors = zzXgCClass.getDeclaredConstructors()[0];
constructors.setAccessible(true);
Object instance = constructors.newInstance(null, null);
// zzZoV = 1
Field zzXFN = zzXgCClass.getDeclaredField("zzZoV");
zzXFN.setAccessible(true);
zzXFN.set(instance, 1);
// zzW8s = 0
// zzX6D = "8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7" // SerialNumber
// zzw9 SubscriptionExpiry
// zzZq3 LicenseExpiry
// zzW5k <Data> ...
// zzYON 签名 Signature
// zzXjC zzZoT 对象 空
Class<?> zzWXGClass = Class.forName("com.aspose.words.zzWXG");
constructors.setAccessible(true);
Object zzWXGInstance = constructors.newInstance(null, null);
Field zzZzA = zzWXGClass.getDeclaredField("zzZzA");
zzZzA.setAccessible(true);
ArrayList<Object> zzwPValue = new ArrayList<>();
zzwPValue.add(instance);
zzZzA.set(null, zzwPValue);
// 生成文档会掉这个来判断 zzVSF
Class<?> zzXQoClass = Class.forName("com.aspose.words.zzVSF");
Field zzHA = zzXQoClass.getDeclaredField("zzDB");
zzHA.setAccessible(true);
zzHA.set(null, 128);
Field zzWod = zzXQoClass.getDeclaredField("zzXac");
zzWod.setAccessible(true);
zzWod.set(null, false);
} catch (Exception e) {
e.printStackTrace();
}
}