暴力破解aspose.excel.19.7

 

一、前言

之前发布了一篇破解aspose.word破解文章,其实是生活所迫买不起授权,不得已才会去破解.emmm,在写一篇破解aspose.excel的文章吧,平衡一下.

二、分析

由于aspose产品系列是没有做联网校验的,所以破解起来比较容易,只要找到核心逻辑,用javassist重新生成一下类即可.

//以下为忽略其他代码核心代码
public class License {
    private String[] b;
    private int c;
    private String d;
    private String e;
    private String f;
    private String g;
    static License a = null;
    private static final String h;
    private static final String i;
    private static final String j;

    public License() {
    }

    public static boolean isLicenseSet() {
        return a != null;
    }

    public static Date getSubscriptionExpireDate() {
        return a == null ? null : a.a();
    }

    public void setLicense(InputStream stream) {
        Document var2 = null;
        if (stream != null) {
            try {
                DocumentBuilderFactory var3 = DocumentBuilderFactory.newInstance();
                DocumentBuilder var4 = var3.newDocumentBuilder();
                var2 = var4.parse(stream);
            } catch (Exception var5) {
                throw new CellsException(9, zd.a(new byte[]{124, 115, -70, -126, 106, 43, -66, 83, 56, 75, -22, -73, 44, 49, -40, 90, -47, -73, -69, 27, -69, -6, -73, 28, -30, -71, -72, -97, 26, 108, -93, -68, -102, 13, -101, -97, 26, 76, -128, -55, 19, -102, 90, 45, -102}), var5);
            }
        }

        this.a(var2);
    }



    private void a(Document var1) {
        if (var1 != null) {
            zcev.a(var1);
            var1.getDocumentElement().normalize();
            Element var2 = var1.getDocumentElement();
            Node var3 = var2.getElementsByTagName(zd.a(new byte[]{-52, 93, -104, -53, -86, -121, 91, 74, -102})).item(0);
            Node var4 = var2.getElementsByTagName(zd.a(new byte[]{92, -4, -120, -14, -82, 78, 106, -116, -53, 41, 59, 19, 110, 26})).item(0);
            if (var3 != null && var4 != null && a(zcev.a(var3), var4.getLastChild().getNodeValue())) {
                int var7;
                try {
                    Node var5 = zcev.a(var3.getChildNodes(), zd.a(new byte[]{-67, -111, -128, -97, -103, -11, 17, -62, 0, -80, -126, -117, -92, 62, 51, 83, -126, -102}));
                    NodeList var6 = var3.getChildNodes();

                    for(var7 = var6.getLength() - 1; var7 > -1; --var7) {
                        Node var8 = var6.item(var7);
                        String var9 = var8.getNodeName();
                        if (var9.equals(zd.a(new byte[]{42, 40, -81, -43, 48, -59, 75, -54, 90, 19, 111, -65, -44, -46, 90}))) {
                            NodeList var18 = var5.getChildNodes();
                            this.b = new String[var18.getLength()];

                            for(int var11 = var18.getLength() - 1; var11 > -1; --var11) {
                                Node var12 = var18.item(var11).getLastChild();
                                this.b[var11] = b(var12 == null ? zd.a(new byte[]{-64, -102, -102, -102}) : var12.getNodeValue());
                            }
                        } else {
                            Node var10;
                            if (var9.equals(zd.a(new byte[]{-38, 105, 45, -73, 11, -33, 90, -28, -47, 126, 48, 9, 93, -1, 50, 42, -102}))) {
                                var10 = var8.getLastChild();
                                this.c = k(var10 == null ? zd.a(new byte[]{58, -116, 96, 39, 88, 45, 105, 3, 26, -102, -102}) : var10.getNodeValue());
                            } else if (var9.equals(zd.a(new byte[]{49, -103, 60, -104, -127, 75, 24, -88, 7, 16, 38, 23, 60, 106, -119, 36, 56, 104, -102}))) {
                                var10 = var8.getLastChild();
                                this.d = var10 == null ? zd.a(new byte[]{-79, 118, -52, 23, -5, 75, 19, -102, -102, -102}) : var10.getNodeValue();
                            } else if (var9.equals(zd.a(new byte[]{23, -24, -91, 57, -80, -76, -20, -108, 70, 111, 40, -51, -26, 15, -56, -100, -17, 83, -12, 26}))) {
                                var10 = var8.getLastChild();
                                this.e = var10 == null ? zd.a(new byte[]{-84, -104, 89, 23, -28, 72, 122, -102, -102}) : var10.getNodeValue();
                            } else if (var9.equals(zd.a(new byte[]{88, 108, 51, 119, -9, -115, -124, -35, 58, 60, 114, -102, 84, 35, -73, 74, -102}))) {
                                var10 = var8.getLastChild();
                                this.f = var10 == null ? zd.a(new byte[]{-22, -11, 6, -13, 36, 3, 26, -102, -102}) : var10.getNodeValue();
                            } else if (var9.equals(zd.a(new byte[]{126, -92, -32, 77, -41, 115, 3, 64, 104, -82, 38, -36, 56, -116, 63, 123, -29, 26, -128, 34, 3, -70, -16, -86, -102}))) {
                                var10 = var8.getLastChild();
                                this.g = var10 == null ? zd.a(new byte[]{56, -68, 65, -91, 31, -13, 83, 29, -102, -102, -102}) : var10.getNodeValue();
                            }
                        }
                    }
                } catch (CellsException var13) {
                    throw var13;
                } catch (Exception var14) {
                    throw new CellsException(9, zd.a(), var14);
                }

                if (i(this.d)) {
                    a(this.b);
                    String var15 = za.d;
                    if (var15 != null && this.e != null) {
                        boolean var16 = true;
                        var7 = Integer.parseInt(this.e.substring(0, 4));
                        int var17 = Integer.parseInt(var15.substring(0, 4));
                        if (var7 < var17) {
                            var16 = false;
                        } else if (var7 == var17) {
                            var7 = Integer.parseInt(this.e.substring(4, 6));
                            var17 = Integer.parseInt(var15.substring(5, 7));
                            if (var7 < var17) {
                                var16 = false;
                            } else if (var7 == var17 && Integer.parseInt(this.e.substring(6)) < Integer.parseInt(var15.substring(8))) {
                                var16 = false;
                            }
                        }

                        if (!var16) {
                            throw new CellsException().toString());
                        }
                    }

                    if (this.f != null && (new Date()).after(j(this.f))) {
                        throw new CellsException();
                    }

                    a = this;
                    zbfo.a();
                    return;
                }
            }
        }

        a = null;
        zyn.a();
    }

    Date a() {
        return j(this.e);
    }

    Date b() {
        return j(this.f);
    }


    private static Date j(String var0) {
        if (var0 != null && var0.length() >= 8) {
            SimpleDateFormat var1 = new SimpleDateFormat(zd.a(new byte[]{-45, 76, 65, 94, 38, 26, -102, -48, -10, -102, -60, 122}));

            try {
                return var1.parse(var0);
            } catch (ParseException var3) {
                throw new IllegalArgumentException(zd.a(new byte[]{118, -23, 102, -26, -97, 62, -97, -46, 110, 6, -109, -9, -8, -94, -127, -119, -100, -100, -15, 43, -55, -98, -39, -103, 32, -35, -15, -105, -33, 90, 84, 35, -73, 74, -74, -98, 42, 89, -98, 82, -102}));
            }
        } else {
            return null;
        }
    }

}

通过以上代码可以分析出,通过setLicense方法,设置许可证,然后经过一顿看不懂的操作,完成许可的验证.但核心逻辑只有几行代码

a = this; //设置对象为this,为了给其他对象调用,改属性是static的,但只有包权限
zbfo.a(); //设置flag为false,具体啥用不晓得
private static Date j(String var0) //验证许可的过期时间

于是思路就是,重写掉setLicense方法,在方法体里面保留以下代码

this.a = new com.aspose.cells.License();
com.aspose.cells.zbfo.a();

重写private static Date j(String var0)方法,使得返回的date为最大值

return new java.util.Date(java.lang.Long.MAX_VALUE);

最后用javassist进行修改,代码如下:

 ClassPool aDefault = ClassPool.getDefault();
 CtClass ctClass = aDefault.get("com.aspose.cells.License");
 CtMethod ctMethod = ctClass.getMethod("setLicense", "(Ljava/io/InputStream;)V");
 ctMethod.setBody("{ this.a = new com.aspose.cells.License();com.aspose.cells.zbfo.a();}");
 CtMethod jMethod = ctClass.getDeclaredMethod("j");
 Method.setBody("{return new java.util.Date(java.lang.Long.MAX_VALUE);}");
 ctClass.writeFile("/Users/doge/test");

把生成好的class文件覆盖到jar包里面就ok啦.