aspose系列的产品可以实现文档之间的转换,但是是要收费的,试用的话转换出来的文档有水印,因此下载了jar包尝试破解,特此记录一下。
仓库
<repository>
<id>aspose</id>
<name>aspose maven</name>
<url>http://maven.aspose.com/repository/repo/</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
版本
<aspose.version>21.9</aspose.version>
maven依赖
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-words</artifactId>
<version>${aspose.version}</version>
</dependency>
javassist
<javassist.version>3.25.0-GA</javassist.version>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>${javassist.version}</version>
</dependency>
软件试用需要加载一个license.xml
通过idea自带的反编译工具对代码进行调试,在com.aspose.words.zzX9L类中可以找到认证的方法如下,这个inputstream就是配置文件的输入流,然后在zzXGh中进行了验证,如果不通过就报错,这里他的提示信息也是加密的,但是看到抛出了异常就知道这里肯定要让他为true
void zzXYy(InputStream var1) throws Exception {
if (var1 == null) {
throw new NullPointerException(zzWU7.zzX0r().zzXkZ(new byte[]{116, 115, 101, 114, 109, 97}));
} else if (!this.zzXGh(var1)) {
throw new IllegalStateException(zzWU7.zzX0r().zzXkZ(new byte[]{110, 73, 97, 118, 105, 108, 32, 100, 105, 108, 101, 99, 115, 110, 32, 101, 105, 115, 110, 103, 116, 97, 114, 117, 46, 101, 80, 32, 101, 108, 115, 97, 32, 101, 97, 109, 101, 107, 115, 32, 114, 117, 32, 101, 104, 116, 32, 101, 105, 108, 101, 99, 115, 110, 32, 101, 105, 102, 101, 108, 119, 32, 115, 97, 110, 32, 116, 111, 109, 32, 100, 111, 102, 105, 101, 105, 46, 100}));
} else {
zzWNQ var2 = zzYsl;
if (var2 == null) {
var2 = zzZ7R(zzWU7.zzX0r().zzXkZ(new byte[]{115, 65, 111, 112, 101, 115, 76, 46, 99, 105, 110, 101, 101, 115, 66, 46, 97, 108, 107, 99, 105, 76, 116, 115}), (String)null);
zzYsl = var2;
}
zzWNQ var3 = zzXVi;
if (var3 == null) {
var3 = zzZ7R(zzWU7.zzX0r().zzXkZ(new byte[]{111, 67, 104, 110, 108, 111, 97, 100, 101, 116, 76, 46, 99, 105, 110, 101, 101, 115, 66, 46, 97, 108, 107, 99, 105, 76, 116, 115}), zzJZ);
zzXVi = var3;
}
if (zzYYV.zzlo() > 0) {
throw new IllegalStateException(zzWU7.zzX0r().zzXkZ(new byte[]{110, 73, 97, 118, 105, 108, 32, 100, 105, 108, 101, 99, 115, 110, 32, 101, 105, 115, 110, 103, 116, 97, 114, 117, 46, 101, 80, 32, 101, 108, 115, 97, 32, 101, 97, 109, 101, 107, 115, 32, 114, 117, 32, 101, 104, 116, 32, 101, 105, 108, 101, 99, 115, 110, 32, 101, 105, 102, 101, 108, 119, 32, 115, 97, 110, 32, 116, 111, 109, 32, 100, 111, 102, 105, 101, 105, 46, 100}));
} else if (!var2.contains(this.zzYdU) && !var3.contains(this.zzYdU)) {
boolean var4 = false;
String[] var5 = this.zzFl;
int var6 = var5.length;
int var7 = 0;
while(var7 < var6) {
String var8 = var5[var7];
if (!var8.equals(zzWU7.zzX0r().zzXkZ(new byte[]{115, 65, 111, 112, 101, 115, 84, 46, 116, 111, 108, 97, 102, 32, 114, 111, 32}) + "Java") && !var8.equals(zzWU7.zzX0r().zzXkZ(new byte[]{111, 67, 104, 110, 108, 111, 97, 100, 101, 116, 84, 46, 116, 111, 108, 97, 102, 32, 114, 111, 32}) + "Java")) {
if ((var8.equals(zzWU7.zzX0r().zzXkZ(new byte[]{115, 65, 111, 112, 101, 115, 84, 46, 116, 111, 108, 97})) || var8.equals(zzWU7.zzX0r().zzXkZ(new byte[]{111, 67, 104, 110, 108, 111, 97, 100, 101, 116, 84, 46, 116, 111, 108, 97}))) && "Java".equals(zzWU7.zzX0r().zzXkZ(new byte[]{78, 46, 84, 69}))) {
var4 = true;
break;
}
if (!var8.equals(zzWU7.zzX0r().zzXkZ(new byte[]{115, 65, 111, 112, 101, 115, 84, 46, 116, 111, 108, 97, 80, 32, 111, 114, 117, 100, 116, 99, 70, 32, 109, 97, 108, 105, 121})) && !var8.equals(zzWU7.zzX0r().zzXkZ(new byte[]{111, 67, 104, 110, 108, 111, 97, 100, 101, 116, 84, 46, 116, 111, 108, 97, 80, 32, 111, 114, 117, 100, 116, 99, 70, 32, 109, 97, 108, 105, 121}))) {
if (var8.equals("Aspose.Words for Java")) {
var4 = true;
break;
}
String var9;
String var10;
if ("Java".equals(zzWU7.zzX0r().zzXkZ(new byte[]{78, 46, 84, 69}))) {
var9 = "Aspose.Words" + zzWU7.zzX0r().zzXkZ(new byte[]{102, 32, 114, 111, 32}) + zzWU7.zzX0r().zzXkZ(new byte[]{97, 88, 97, 109, 105, 114, 46, 110, 110, 65, 114, 100, 105, 111, 100});
var10 = zzWU7.zzX0r().zzXkZ(new byte[]{115, 65, 111, 112, 101, 115, 84, 46, 116, 111, 108, 97, 102, 32, 114, 111, 88, 32, 109, 97, 114, 97, 110, 105, 65, 46, 100, 110, 111, 114, 100, 105});
String var11 = "Aspose.Words" + zzWU7.zzX0r().zzXkZ(new byte[]{102, 32, 114, 111, 32}) + zzWU7.zzX0r().zzXkZ(new byte[]{110, 65, 114, 100, 105, 111, 32, 100, 105, 118, 32, 97, 97, 88, 97, 109, 105, 114, 110});
String var12 = zzWU7.zzX0r().zzXkZ(new byte[]{115, 65, 111, 112, 101, 115, 84, 46, 116, 111, 108, 97, 102, 32, 114, 111, 65, 32, 100, 110, 111, 114, 100, 105, 118, 32, 97, 105, 88, 32, 109, 97, 114, 97, 110, 105});
String var13 = "Aspose.Words" + zzWU7.zzX0r().zzXkZ(new byte[]{102, 32, 114, 111, 32}) + zzWU7.zzX0r().zzXkZ(new byte[]{79, 105, 32, 83, 105, 118, 32, 97, 97, 88, 97, 109, 105, 114, 110});
String var14 = zzWU7.zzX0r().zzXkZ(new byte[]{115, 65, 111, 112, 101, 115, 84, 46, 116, 111, 108, 97, 102, 32, 114, 111, 105, 32, 83, 79, 118, 32, 97, 105, 88, 32, 109, 97, 114, 97, 110, 105});
String var15 = "Aspose.Words" + zzWU7.zzX0r().zzXkZ(new byte[]{102, 32, 114, 111, 32}) + zzWU7.zzX0r().zzXkZ(new byte[]{97, 77, 32, 99, 105, 118, 32, 97, 97, 88, 97, 109, 105, 114, 110});
String var16 = zzWU7.zzX0r().zzXkZ(new byte[]{115, 65, 111, 112, 101, 115, 84, 46, 116, 111, 108, 97, 102, 32, 114, 111, 77, 32, 99, 97, 118, 32, 97, 105, 88, 32, 109, 97, 114, 97, 110, 105});
if (var8.equals(var9) || var8.equals(var10) || var8.equals(var11) || var8.equals(var12) || var8.equals(var13) || var8.equals(var14) || var8.equals(var15) || var8.equals(var16)) {
var4 = true;
break;
}
}
if ("Java".equals(zzWU7.zzX0r().zzXkZ(new byte[]{97, 74, 97, 118, 65, 46, 100, 110, 111, 114, 100, 105}))) {
var9 = "Aspose.Words" + zzWU7.zzX0r().zzXkZ(new byte[]{102, 32, 114, 111, 32}) + zzWU7.zzX0r().zzXkZ(new byte[]{110, 65, 114, 100, 105, 111, 100});
var10 = zzWU7.zzX0r().zzXkZ(new byte[]{115, 65, 111, 112, 101, 115, 84, 46, 116, 111, 108, 97, 102, 32, 114, 111, 65, 32, 100, 110, 111, 114, 100, 105});
if (var8.equals(var9) || var8.equals(var10)) {
var4 = true;
break;
}
}
if (var8.equals("Aspose.Words") && "Java".equals(zzWU7.zzX0r().zzXkZ(new byte[]{78, 46, 84, 69}))) {
var4 = true;
break;
}
if (var8.equals("Aspose.Words" + zzWU7.zzX0r().zzXkZ(new byte[]{80, 32, 111, 114, 117, 100, 116, 99, 70, 32, 109, 97, 108, 105, 121}))) {
var4 = true;
break;
}
++var7;
continue;
}
var4 = true;
break;
}
var4 = true;
break;
}
if (!var4) {
throw new IllegalStateException(zzWU7.zzX0r().zzXkZ(new byte[]{104, 84, 32, 101, 105, 108, 101, 99, 115, 110, 32, 101, 115, 105, 110, 32, 116, 111, 118, 32, 108, 97, 100, 105, 102, 32, 114, 111, 116, 32, 105, 104, 32, 115, 114, 112, 100, 111, 99, 117, 46, 116}));
} else {
Date var17 = (new SimpleDateFormat("yyyy.MM.dd")).parse("2021.09.01");
if (var17.after(this.zzl8)) {
throw new IllegalStateException(this.zzVWF.zzVVx(new byte[]{84, 104, 101, 32, 115, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 32, 105, 110, 99, 108, 117, 100, 101, 100, 32, 105, 110, 32, 116, 104, 105, 115, 32, 108, 105, 99, 101, 110, 115, 101, 32, 97, 108, 108, 111, 119, 115, 32, 102, 114, 101, 101, 32, 117, 112, 103, 114, 97, 100, 101, 115, 32, 117, 110, 116, 105, 108, 32}) + (new SimpleDateFormat(this.zzVWF.zzVVx(new byte[]{100, 100, 32, 77, 77, 77, 32, 121, 121, 121, 121}), Locale.ENGLISH)).format(this.zzl8) + this.zzVWF.zzVVx(new byte[]{44, 32}) + this.zzVWF.zzVVx(new byte[]{98, 117, 116, 32, 116, 104, 105, 115, 32, 118, 101, 114, 115, 105, 111, 110, 32, 111, 102, 32, 116, 104, 101, 32, 112, 114, 111, 100, 117, 99, 116, 32, 119, 97, 115, 32, 114, 101, 108, 101, 97, 115, 101, 100, 32, 111, 110, 32}) + (new SimpleDateFormat(this.zzVWF.zzVVx(new byte[]{100, 100, 32, 77, 77, 77, 32, 121, 121, 121, 121}), Locale.ENGLISH)).format(var17) + this.zzVWF.zzVVx(new byte[]{46, 32}) + this.zzVWF.zzVVx(new byte[]{80, 108, 101, 97, 115, 101, 32, 114, 101, 110, 101, 119, 32, 116, 104, 101, 32, 115, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 32, 111, 114, 32, 117, 115, 101, 32, 97, 32, 112, 114, 101, 118, 105, 111, 117, 115, 32, 118, 101, 114, 115, 105, 111, 110, 32, 111, 102, 32, 116, 104, 101, 32, 112, 114, 111, 100, 117, 99, 116, 46}));
} else if ((new Date()).after(this.zzZ5G)) {
throw new IllegalStateException(zzWU7.zzX0r().zzXkZ(new byte[]{104, 84, 32, 101, 105, 108, 101, 99, 115, 110, 32, 101, 97, 104, 32, 115, 120, 101, 105, 112, 101, 114, 46, 100}));
} else if (this.zzl8.getYear() < 2099) {
this.zzxc = zzVXK.zzWo2;
zzXqS = this;
}
}
} else {
throw new IllegalStateException(zzWU7.zzX0r().zzXkZ(new byte[]{104, 84, 115, 105, 108, 32, 99, 105, 110, 101, 101, 115, 105, 32, 32, 115, 105, 100, 97, 115, 108, 98, 100, 101, 32, 44, 108, 112, 97, 101, 101, 115, 99, 32, 110, 111, 97, 116, 116, 99, 65, 32, 112, 115, 115, 111, 32, 101, 111, 116, 111, 32, 116, 98, 105, 97, 32, 110, 32, 97, 101, 110, 32, 119, 105, 108, 101, 99, 115, 110, 46, 101}));
}
}
}
然后我们进入判断的方法,发现var8 是他的返回值
private boolean zzXGh(InputStream var1) throws Exception {
DocumentBuilderFactory var2 = zzXrM.zzXsa();
DocumentBuilder var3 = var2.newDocumentBuilder();
Document var4 = var3.parse(var1);
Element var5 = var4.getDocumentElement();
Element var6 = zzY2m(var5, zzWU7.zzX0r().zzXkZ(new byte[]{97, 68, 97, 116}));
Element var7 = zzY2m(var5, zzWU7.zzX0r().zzXkZ(new byte[]{105, 83, 110, 103, 116, 97, 114, 117, 101}));
boolean var8 = zzWqN((Node)var6, (Node)var7);
Element var9 = zzY2m(var6, zzWU7.zzX0r().zzXkZ(new byte[]{114, 80, 100, 111, 99, 117, 115, 116}));
NodeList var10 = var9.getElementsByTagName(zzWU7.zzX0r().zzXkZ(new byte[]{114, 80, 100, 111, 99, 117, 116}));
this.zzFl = new String[var10.getLength()];
for(int var11 = 0; var11 < this.zzFl.length; ++var11) {
this.zzFl[var11] = var10.item(var11).getFirstChild().getNodeValue();
}
this.zzYdU = zzWqN(var6, zzWU7.zzX0r().zzXkZ(new byte[]{101, 83, 105, 114, 108, 97, 117, 78, 98, 109, 114, 101}));
this.zzl8 = zzWzr(var6, zzWU7.zzX0r().zzXkZ(new byte[]{117, 83, 115, 98, 114, 99, 112, 105, 105, 116, 110, 111, 120, 69, 105, 112, 121, 114}));
this.zzZ5G = zzWzr(var6, zzWU7.zzX0r().zzXkZ(new byte[]{105, 76, 101, 99, 115, 110, 69, 101, 112, 120, 114, 105, 121}));
return var8;
}
其中重点关注zzWqN方法,这个方法返回值是boolean类型,源码如下
private static boolean zzWqN(Node var0, Node var1) throws Exception {
return zzYMS((Node)var0, (Node)var1, (String)null);
}
这个方法中,他又调用了另外一个方法进行验证,但是我们不必管他,直接使用javassist将这里的代码修改为return true,然后将新生成的class文件覆盖即可。
try {
ClassPool.getDefault().insertClassPath("D:\\download\\tim\\3424675994\\FileRecv\\aspose-words-21.9-jdk17.jar");
CtClass c2 = ClassPool.getDefault().getCtClass("com.aspose.words.zzX9L");
CtMethod[] ms = c2.getDeclaredMethods();
for (CtMethod c : ms) {
if(c.getName().equals("zzWqN") && c.getReturnType().getName().equals("boolean")){
System.out.println("设置");
c.setBody("return true;");
}
}
c2.writeFile("D:\\download\\tim\\3424675994\\FileRecv");
} catch (Exception e) {
e.printStackTrace();
}
覆盖后我们再用idea引入这个jar,就看到zzWqN方法源码被修改为
private static boolean zzWqN(Node var0, Node var1) throws Exception {
return true;
}
到这里还没有结束,还需要删除jar包中类文件的签名信息
然后根据源码解析的XML代码,自己建立一个license.xml文件,SerialNumber和Signature值可以修改
try {
License license = new License();
try {
license.setLicense("D:\\download\\kmair\\contract\\file_backup\\license.xml");
} catch (Exception e) {
e.printStackTrace();
}
long old = System.currentTimeMillis();
File file = new File("D:\\download\\kmair\\contract\\file_backup\\pdf\\1.pdf");
//sdasdasdas
FileOutputStream os = new FileOutputStream(file);
Document doc = new Document("D:\\download\\tim\\3424675994\\FileRecv\\k8s集群环境搭建手册.docx");
doc.save(os, SaveFormat.PDF);
System.out.println(new String(new byte[]{110, 73, 97, 118, 105, 108, 32, 100, 105, 108, 101, 99, 115, 110, 32, 101, 105, 115, 110, 103, 116, 97, 114, 117, 46, 101, 80, 32, 101, 108, 115, 97, 32, 101, 97, 109, 101, 107, 115, 32, 114, 117, 32, 101, 104, 116, 32, 101, 105, 108, 101, 99, 115, 110, 32, 101, 105, 102, 101, 108, 119, 32, 115, 97, 110, 32, 116, 111, 109, 32, 100, 111, 102, 105, 101, 105, 46, 100}));
long now = System.currentTimeMillis();
System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒");
} catch (Exception e) {
e.printStackTrace();
}