声明:本文仅供学习交流,请勿用于非法用途。
上一次去除时间限制之后,时间显示上会有点问题,并且提示是试用版,这次我们来修改它
搜索网上8.0的破解信息,找到发现和pw这个类有渊源
尝试修改其中的字符串,发现信息并没有被改掉,可能原作者尝试改这个类没有成功,后面尝试了其他方法去修改,不管怎么说,这个类应该是有影响的,下面尝试在9.0中找到对应的类
经过测试,License信息在以下三个地方出现
1.控制台
2.我同意界面
3.About界面
我们看About界面类的加载情况
ZKM8
ZKM9
分析ZKM8加载的几个类与pw的关系
仔细分析发现
hc中有两个方法的参数引用了h0,h0继承pw
根据这个提示,我们找ZKM9的类似关系
_7的两个方法参数用到了jj这个类,jj继承了um
但是实际测试中发现,改um这个类没什么实际价值,接下来我们跟踪jj这个类看一下
我们使用AspectJ这个工具
跟踪jj类的方法代码,为了方便观察,同时跟踪main方法
public aspect Tracing {
private pointcut mainMethod() :
execution(public static void main(String[]));
before() : mainMethod() {
System.out.println(“> ” + thisJoinPoint);
}
private pointcut jjMethod() :
execution(* com.zelix.jj.*(..));
before() :jjMethod() {
System.out.println(“> ” + thisJoinPoint);
Object[] args = thisJoinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
if (args[i] != null) {
System.out.println(“args[” + i + “]: ” + args[i].toString());
}
}
}
after() :jjMethod() {
System.out.println(“< ” + thisJoinPoint);
}
after() returning(Object o) :jjMethod(){
if (o != null) {
System.out.println(“Return value: ” + o.toString());
}
}
private pointcut qsMethod() :
execution(* com.zelix.qs.*(..));
before() :qsMethod() {
System.out.println(“> ” + thisJoinPoint);
Object[] args = thisJoinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
if (args[i] != null) {
System.out.println(“args[” + i + “]: ” + args[i].toString());
}
}
}
after() :qsMethod() {
System.out.println(“< ” + thisJoinPoint);
}
after() returning(Object o) :qsMethod(){
if (o != null) {
System.out.println(“Return value: ” + o.toString());
}
}
}
我们这里在eclipse运行加载时编织项目
在控制台弹出的消息中搜索相关文字如下
我们在javaassist中修改这个方法的部分返回值发现,这个方法只能修改控制台上字符串的变化,界面的文字可能在另一个地方修改
进一步跟踪jj这个类的方法我们发现有个a方法可以帮助我们定位各swing界面对应的类
清空控制台,反复点击菜单看控制台变化,可以得出如下表
类 | 界面 | 界面标题 |
com.zelix.qs | 我同意界面 | Zelix KlassMaster Evaluation |
com.zelix.af | 初始帮助界面 | Initial Helper Dialog |
com.zelix.ak | 主程序界面 | Zelix KlassMaster (evaluation only) |
com.zelix.v | 打开文件界面 | Zelix KlassMaster – Open Classes |
com.zelix.a6 | 保存文件界面 | Zelix KlassMaster – Select a Folder |
com.zelix.o | Trim界面 | Zelix KlassMaster – Trim Exclusions |
com.zelix.r | Obfuscate界面 | Zelix KlassMaster – Obfuscate Name Exclusions |
com.zelix.ao | Build Helper | |
com.zelix.ao | ZKM Script Helper | |
com.zelix.aq | Zelix KlassMaster – Stack Trace Translate | |
com.zelix.a8 | Zelix KlassMaster – ProGuard Configuration Translate | |
com.zelix.a2 | Classpath | |
com.zelix.aw | 帮助界面 | Zelix KlassMaster – Help |
com.zelix.qs | About界面 | |
com.zelix.uj | Layout布局 |
可以看出,我同意界面和About界面都用的qs这个类,改界面的license信息就要重点分析这个类
仔细观察前面改过的方法,有个5个参数的a方法改完返回值之后影响到了界面的显示
根据这个信息我们在qs这个类中找到
这里正好与界面中License Type的字符串拼接逻辑相互吻合。
代码中的abe类的d方法和c方法都是一些反射调用
我们用AspectJ跟踪abe.c((long)6789659459489445282L, (int)var5_5)这段代码
private pointcut abecMethod() :
execution(* com.zelix.abe.c(..));
before() :abecMethod() {
Object[] args = thisJoinPoint.getArgs();
if (args.length == 2 && args[0] != null && args[0] instanceof Long && (long) args[0] == 6789659459489445282L) {
System.out.println(“4545”);
}
}
after() returning(Object o) :abecMethod(){
if (o != null) {
Object[] args = thisJoinPoint.getArgs();
if (args.length == 2 && args[0] != null && args[0] instanceof Long
&& (long) args[0] == 6789659459489445282L) {
System.out.println(“Return value: ” + o.toString());
System.out.println(“Return type: ” + o.getClass().getName());
}
}
}
跟踪结果如下
返回的类型是反射类型的com.zelix.qs.g
g是qs里面的一个静态数组,通过javaassist改写输出这个数组的内容大致如下
private static String[] g = new String[] { “License No.:”, “none”, “License Type:”, “30 day evaluation expiring”,
“Licensee:”, “free free – free”, “”, “admin@lanyus.com” };
在上文中qs类调用jj.a的方法是写在qs.a(5个参数)中的,我们使用insertbefore重新对g进行赋值,经过反复测试,改写成功。
以上就改写了两处license信息,主界面的标题栏有个带括号的evaluate only,在jj类的某个方法里可以一并改写,我同意界面的标题栏也有evaluate字样,暂时没深入分析改,有时间再说。
附件下载: