Aspose Word Java字节码分析与破解研究

周六闲来无事,想到之前很容易对aspose.cell v21.4完成破解研究(见博客),但是对aspose.words没有完成破解分析。

这次换个思路,基于License进行class文件分析。

一:从官网下载

下载地址:Java Word Processor API | Aspose.Words for Java;

或者使用maven方式进行jar包下载:

<!-- maven配置 -->

    <repositories>
        <repository>
            <id>AsposeJavaAPI</id>
            <name>Aspose Java API</name>
            <url>https://repository.aspose.com/repo/</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>com.aspose</groupId>
            <artifactId>aspose-words</artifactId>
            <version>21.12</version>
            <type>pom</type>
        </dependency>
    </dependencies>

需注意:从官网下载的jar包为实时混淆,混淆的class名各不相同,因此本博客列出关键方法,但是方法名不保证一致。 

二:License安装

Licensing and Subscription | Documentation

关键代码:

com.aspose.words.License license = new com.aspose.words.License();
license.setLicense("path:\\Aspose.Words.Java.lic");

给出License示例:

<License>
	<Data>
		<LicensedTo>Aspose Scotland Team</LicensedTo>
		<EmailTo>billy.lundie@aspose.com</EmailTo>
		<LicenseType>Developer OEM</LicenseType>
		<LicenseNote>Limited to 1 developer, unlimited physical locations</LicenseNote>
		<OrderID>140408052324</OrderID>
		<UserID>94236</UserID>
		<OEM>This is a redistributable license</OEM>
		<Products>
			<Product>Aspose.Total for Java</Product>
		</Products>
		<EditionType>Enterprise</EditionType>
		<SerialNumber>9a59547c-41f0-428b-ba72-7c4368f151d7</SerialNumber>
		<SubscriptionExpiry>20221231</SubscriptionExpiry>
		<LicenseVersion>3.0</LicenseVersion>
		<LicenseInstructions>http://www.aspose.com/corporate/purchase/license-instructions.aspx</LicenseInstructions>
	</Data>
	<Signature>FO3PHsblgDt8F59sMT1l1amyi9qk2V6E8dQkIP7LdTJSxDibNEFu1zOinQbqFfKv/ruttvcxoROkc1tUe0DtO6cP1Zf6J0VemgSY8i/LZECTGszRqJVQRZ0MoVnBhuPAJk5eli7fhVcF8hWd3E4XQ3LzfmJCuaj2NEteRi5Hrfg=</Signature>
</License>

进入License.class文件,基于IDEA自带反编译功能,我们可以看到源码:下图zzWf9为混淆类,可能每人下载类均不相同,记住该类名。

public class License {
    public License() {
        zzZ3T.zzZAj();
    }

    public void setLicense(String licenseName) throws Exception {
        if (licenseName == null) {
            throw new NullPointerException(zzZ3T.zzZAj().zzMk(new byte[]{105, 108, 101, 99, 115, 110, 78, 101, 109, 97, 101}));
        } else {
            (new zzWf9()).zzY98(licenseName, zzZdu.zzXGb());
        }
    }

    public void setLicense(InputStream stream) throws Exception {
        if (stream == null) {
            throw new NullPointerException(zzZ3T.zzZAj().zzMk(new byte[]{116, 115, 101, 114, 109, 97}));
        } else {
            (new zzWf9()).zzY98(stream);
        }
    }
}

可以看到License类中有zzWf9的2个重载方法,关键在于zzY98方法(最后提示混淆方法不保证一致!)。

进入核心验证方法:

void zzY98(InputStream var1) throws Exception {
        if (var1 == null) {
            throw new NullPointerException(zzZ3T.zzZAj().zzMk(new byte[]{116, 115, 101, 114, 109, 97}));
        } else if (!this.zzXvE(var1)) {
            throw new IllegalStateException(zzZ3T.zzZAj().zzMk(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 {
            zzWhX var2 = zzWcN;
            if (var2 == null) {
                var2 = zzYf8(zzZ3T.zzZAj().zzMk(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);
                zzWcN = var2;
            }

            zzWhX var3 = zzX3l;
            if (var3 == null) {
                var3 = zzYf8(zzZ3T.zzZAj().zzMk(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}), zzZDr);
                zzX3l = var3;
            }

            if (zznY.zzZHa() > 0) {
                throw new IllegalStateException(zzZ3T.zzZAj().zzMk(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.zzWO4) && !var3.contains(this.zzWO4)) {
                boolean var4 = false;
                String[] var5 = this.zzWJJ;
                int var6 = var5.length;
                int var7 = 0;

                while(var7 < var6) {
                    String var8 = var5[var7];
                    if (!var8.equals(zzZ3T.zzZAj().zzMk(new byte[]{115, 65, 111, 112, 101, 115, 84, 46, 116, 111, 108, 97, 102, 32, 114, 111, 32}) + "Java") && !var8.equals(zzZ3T.zzZAj().zzMk(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(zzZ3T.zzZAj().zzMk(new byte[]{115, 65, 111, 112, 101, 115, 84, 46, 116, 111, 108, 97})) || var8.equals(zzZ3T.zzZAj().zzMk(new byte[]{111, 67, 104, 110, 108, 111, 97, 100, 101, 116, 84, 46, 116, 111, 108, 97}))) && "Java".equals(zzZ3T.zzZAj().zzMk(new byte[]{78, 46, 84, 69}))) {
                            var4 = true;
                            break;
                        }

                        if (!var8.equals(zzZ3T.zzZAj().zzMk(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(zzZ3T.zzZAj().zzMk(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(zzZ3T.zzZAj().zzMk(new byte[]{78, 46, 84, 69}))) {
                                var9 = "Aspose.Words" + zzZ3T.zzZAj().zzMk(new byte[]{102, 32, 114, 111, 32}) + zzZ3T.zzZAj().zzMk(new byte[]{97, 88, 97, 109, 105, 114, 46, 110, 110, 65, 114, 100, 105, 111, 100});
                                var10 = zzZ3T.zzZAj().zzMk(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" + zzZ3T.zzZAj().zzMk(new byte[]{102, 32, 114, 111, 32}) + zzZ3T.zzZAj().zzMk(new byte[]{110, 65, 114, 100, 105, 111, 32, 100, 105, 118, 32, 97, 97, 88, 97, 109, 105, 114, 110});
                                String var12 = zzZ3T.zzZAj().zzMk(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" + zzZ3T.zzZAj().zzMk(new byte[]{102, 32, 114, 111, 32}) + zzZ3T.zzZAj().zzMk(new byte[]{79, 105, 32, 83, 105, 118, 32, 97, 97, 88, 97, 109, 105, 114, 110});
                                String var14 = zzZ3T.zzZAj().zzMk(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" + zzZ3T.zzZAj().zzMk(new byte[]{102, 32, 114, 111, 32}) + zzZ3T.zzZAj().zzMk(new byte[]{97, 77, 32, 99, 105, 118, 32, 97, 97, 88, 97, 109, 105, 114, 110});
                                String var16 = zzZ3T.zzZAj().zzMk(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(zzZ3T.zzZAj().zzMk(new byte[]{97, 74, 97, 118, 65, 46, 100, 110, 111, 114, 100, 105}))) {
                                var9 = "Aspose.Words" + zzZ3T.zzZAj().zzMk(new byte[]{102, 32, 114, 111, 32}) + zzZ3T.zzZAj().zzMk(new byte[]{110, 65, 114, 100, 105, 111, 100});
                                var10 = zzZ3T.zzZAj().zzMk(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(zzZ3T.zzZAj().zzMk(new byte[]{78, 46, 84, 69}))) {
                                var4 = true;
                                break;
                            }

                            if (var8.equals("Aspose.Words" + zzZ3T.zzZAj().zzMk(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(zzZ3T.zzZAj().zzMk(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.12.01");
                    if (var17.after(this.zzWec)) {
                        throw new IllegalStateException(this.zzY4i.zzXJX(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.zzY4i.zzXJX(new byte[]{100, 100, 32, 77, 77, 77, 32, 121, 121, 121, 121}), Locale.ENGLISH)).format(this.zzWec) + this.zzY4i.zzXJX(new byte[]{44, 32}) + this.zzY4i.zzXJX(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.zzY4i.zzXJX(new byte[]{100, 100, 32, 77, 77, 77, 32, 121, 121, 121, 121}), Locale.ENGLISH)).format(var17) + this.zzY4i.zzXJX(new byte[]{46, 32}) + this.zzY4i.zzXJX(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.zzYS9)) {
                        throw new IllegalStateException(zzZ3T.zzZAj().zzMk(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.zzWec.getYear() < 2099) {
                        this.zzWnu = zzYjw.zzVS4;
                        zzWhV = this;
                    }
                }
            } else {
                throw new IllegalStateException(zzZ3T.zzZAj().zzMk(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}));
            }
        }
    }

这个方法有2个注意点:

1、日期判断硬编码:21.12版本注册日期应为2021.12.01日之后,2099年之前;

2、第4行zzXvE方法进行License校验(因为验证不通过提示就是License Invalid)。

本License内容原为.NET,<Product>Aspose.Total for .NET</Product>,这时signature验证通过,但是本博客修改为<Product>Aspose.Total for Java</Product>,因此在校验时会提示License Invalid。

综上,哎~对了,又到了字节码编辑的时候了。但是接下来有个地方是有难度的,

三、class文件编辑

主要在zzWf9.zzXvE校验方法,其中有2个地方修改:

源码:

private boolean zzXvE(InputStream var1) throws Exception {
        DocumentBuilderFactory var2 = zzXcV.zzWQB();
        DocumentBuilder var3 = var2.newDocumentBuilder();
        Document var4 = var3.parse(var1);
        Element var5 = var4.getDocumentElement();
        Element var6 = zzWKk(var5, zzZ3T.zzZAj().zzMk(new byte[]{97, 68, 97, 116}));
        Element var7 = zzWKk(var5, zzZ3T.zzZAj().zzMk(new byte[]{105, 83, 110, 103, 116, 97, 114, 117, 101}));
        boolean var8 = zzWxF((Node)var6, (Node)var7);
        Element var9 = zzWKk(var6, zzZ3T.zzZAj().zzMk(new byte[]{114, 80, 100, 111, 99, 117, 115, 116}));
        NodeList var10 = var9.getElementsByTagName(zzZ3T.zzZAj().zzMk(new byte[]{114, 80, 100, 111, 99, 117, 116}));
        this.zzWJJ = new String[var10.getLength()];

        for(int var11 = 0; var11 < this.zzWJJ.length; ++var11) {
            this.zzWJJ[var11] = var10.item(var11).getFirstChild().getNodeValue();
        }

        this.zzWO4 = zzZqK(var6, zzZ3T.zzZAj().zzMk(new byte[]{101, 83, 105, 114, 108, 97, 117, 78, 98, 109, 114, 101}));
        this.zzWec = zzWxF(var6, zzZ3T.zzZAj().zzMk(new byte[]{117, 83, 115, 98, 114, 99, 112, 105, 105, 116, 110, 111, 120, 69, 105, 112, 121, 114}));
        this.zzYS9 = zzWxF(var6, zzZ3T.zzZAj().zzMk(new byte[]{105, 76, 101, 99, 115, 110, 69, 101, 112, 120, 114, 105, 121}));
        return var8;
    }

1、zzXvE,方法体第7行,

boolean var8 = zzWxF((Node)var6, (Node)var7);

这一行需要跟踪调试,经多次调试发现最后是由ThreadLocal对象进行控制,列出zzWf9关键调用链:

// 进入方法一:
private static boolean zzWxF(Node var0, Node var1) throws Exception {
        return zzZp8((Node)var0, (Node)var1, (String)null);
    }

// 进入方法二:
private static boolean zzZp8(Node var0, Node var1, String var2) throws Exception {
        byte[] var3;
        if (var0 != null) {
            StringBuilder var4 = new StringBuilder();
            zzZp8(var4, var0);
            var3 = var4.toString().getBytes("UTF-16LE");
        } else {
            var3 = new byte[0];
        }

        byte[] var6;
        if (var1 != null) {
            String var5 = var1.getFirstChild().getNodeValue();
            var6 = zzZbv.zz3m(var5);
        } else {
            var6 = new byte[0];
        }

        if (var2 == null) {
            if (zzWjD(var0)) {
                var2 = var6.length == 128 ? zzZDr : zzWxc;
            } else {
                var2 = var6.length == 128 ? zzYAU : zzX1P;
            }
        }

        return zzZp8(var3, var6, var2);
    }

// 进入方法三:
private static boolean zzZp8(byte[] var0, byte[] var1, String var2) throws Exception {
        String var3 = zzZ3T.zzZAj().zzMk(new byte[]{81, 65, 66, 65});
        byte[] var4 = zzZbv.zz3m(var3);
        byte[] var5 = zzZbv.zz3m(var2);
        return zzxN.zzZp8(var5, var4, var0, var1);
    }

 发现进入zzxN.zzZp8方法,列出zzxN调用链:

// 进入方法一:
static boolean zzZp8(byte[] var0, byte[] var1, byte[] var2, byte[] var3) throws Exception {
        return zzZqK(var0, var1, var2, var3);
    }

// 进入方法二:
private static boolean zzZqK(byte[] var0, byte[] var1, byte[] var2, byte[] var3) throws Exception {
        boolean var4 = false;
        if (var3.length != var0.length) {
            zznY.zzWUu(1);
            var4 = true;
        }

        byte[] var5 = zzZbv.zzXvz(var3);
        zzZto var6;
        byte[] var7;
        byte[] var8 = zzZbv.zzZo9(var7 = zzZbv.zzZp8(var6 = new zzZto(var0, var1), var5), var6.getModulus().bitLength() >> 3);
        byte[] var9 = zzWxF(var0, var2, var8.length);
        if (var8.length != var9.length) {
            var4 = true;
        } else {
            for(int var10 = 0; var10 < var8.length; ++var10) {
                var4 = var4 || var8[var10] != var9[var10];
            }
        }

        zzTq var14;
        (var14 = new zzTq(var7)).zzYBj(var5.length, var9.length, false);
        zzXUN var11;
        (var11 = new zzXUN()).write(var7, 0, var7.length);
        var14.zzZp8(var11, var9, var5.length);
        if (var14.zzWw9()) {
            var5[0] = 0;
            var5[1] = 17;
        }

        zzZ3V var12 = new zzZ3V(var14, var8, true, var14.zzWw9());
        int[] var13 = new int[var7.length];
        zzXcS.zzZp8(var7, 0, var13, 0, var7.length);
        var12.zzZp8(var14);
        var12.zzZ8j();
        var12.zzbx(true);
        var14.zzZ7L(true);
        zzZ3T.zzZAj().zzMk(new byte[]{50, 49, 52, 51, 54, 53, 56, 55, 48, 57, 66, 65, 68, 67, 70, 69});
        var12.zzZ8j();
        var12.zzWs3(zzZ3T.zzZAj().zzMk(new byte[]{115, 65, 111, 112, 101, 115, 87, 46, 114, 111, 115, 100}));
        return !var4;
    }

 在该方法中发现返回校验结果了,再次寻找关键代码,经多次调试终于发现倒数第5行:

var12.zzbx(true);

该方法为关键方法,进入zzZ3V.zzbx方法,列出调用链:

final void zzbx(boolean var1) throws Exception {
        this.zzJu = 0;
        if (this.zzWza.zzGe() > 0L) {
            int var2 = (int)this.zzWza.zzGe() / 2 + 1;
            byte[] var3 = this.zzWza.zzWnM();
            if (zznY.zzZxN() == 255) {
                zznY.zzWWo(128);
            }

            int var4 = var3.length - 1;

            for(int var5 = 0; var5 < var2; ++var5) {
                if ((var3[var4] & 255) == 255) {
                    ++this.zzhe;
                }

                if (var3[var4] != (byte)this.zzZ3G.zz8A()[var4]) {
                    zznY.zzWUu(128);//注意这行
                }

                --var4;
            }
        }

    }

 特别注意这行:zznY.zzWUu(128);

终于来到最后的zznY类:

static void zzWUu(int var0) {
        zzXKA.set(Integer.valueOf(var0));
    }

在这一行,需要进行修改使这个ThreadLocal设置值为0(具体请自己调试,后续有>0判断)。

2、zzXvE,最后返回修改为true;

4、总结:

1、zznY.zzWUu修改,每次设置值为0:

static void zzWUu(int var0) {
        byte var1 = 0;//需自己修改字节码文件
        zzXKA.set(Integer.valueOf(var1));
    }

2、zzWf9.zzXvE修改,返回校验结果true:

private boolean zzXvE(InputStream var1) throws Exception {
        DocumentBuilderFactory var2 = zzXcV.zzWQB();
        DocumentBuilder var3 = var2.newDocumentBuilder();
        Document var4 = var3.parse(var1);
        Element var5 = var4.getDocumentElement();
        Element var6 = zzWKk(var5, zzZ3T.zzZAj().zzMk(new byte[]{97, 68, 97, 116}));
        Element var7 = zzWKk(var5, zzZ3T.zzZAj().zzMk(new byte[]{105, 83, 110, 103, 116, 97, 114, 117, 101}));
        boolean var8 = zzWxF((Node)var6, (Node)var7);
        Element var9 = zzWKk(var6, zzZ3T.zzZAj().zzMk(new byte[]{114, 80, 100, 111, 99, 117, 115, 116}));
        NodeList var10 = var9.getElementsByTagName(zzZ3T.zzZAj().zzMk(new byte[]{114, 80, 100, 111, 99, 117, 116}));
        this.zzWJJ = new String[var10.getLength()];

        for(int var11 = 0; var11 < this.zzWJJ.length; ++var11) {
            this.zzWJJ[var11] = var10.item(var11).getFirstChild().getNodeValue();
        }

        this.zzWO4 = zzZqK(var6, zzZ3T.zzZAj().zzMk(new byte[]{101, 83, 105, 114, 108, 97, 117, 78, 98, 109, 114, 101}));
        this.zzWec = zzWxF(var6, zzZ3T.zzZAj().zzMk(new byte[]{117, 83, 115, 98, 114, 99, 112, 105, 105, 116, 110, 111, 120, 69, 105, 112, 121, 114}));
        this.zzYS9 = zzWxF(var6, zzZ3T.zzZAj().zzMk(new byte[]{105, 76, 101, 99, 115, 110, 69, 101, 112, 120, 114, 105, 121}));
        return true;//自己修改字节码文件
    }

修改上述两处,即可完成对Aspose.Words jar破解,需配合License文件。

示例代码:

//读取word文件,保存为PDF文件。
License license = new License();
license.setLicense("E:\\Aspose.License.xml");

Document doc = new Document("E:\\Aspose.Crack.docx");

SaveOutputParameters parameters = doc.save("E:\\cracked.pdf", SaveOptions.createSaveOptions(SaveFormat.PDF));

System.out.println(parameters.getContentType());

 转化后文件,无水印无页码限制:

 

搞定收工。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sword_happy

您的鼓励亦是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值