前段时间在做一个关心软件授权方面的研究,即给一个软件进行授权管理,其中就涉及到如何创建license,并利用license来保护我们的软件。
这其中最主要的问题,即是如何保护真正的授权部分代码了。即将真正进行授权访问的代码给保护起来,并不让软件使用人通过某种方法来进行软件的破解或者盗用。一般来说,破解软件最简单的方法即是修改授权部分代码的实现,让授权部分验证始终返回true。如果想办法不让使用者查看最终的授权部分代码,那么则只能通过其它方法来进行破解了。
那么,我们可以通过一种手段来在程序内部来修改授权部分的实现,使真实的授权部分隐藏在其它代码部分,而可视的授权代码并不参与实际的授权授权,这样的话,对于破解者来说,修改表向的代码实现并不能真正修改代码实现,因为真实的实现已经通过其它代码将原始实现替换掉了。
以下是一种修改的示意图:
即在调用授权代码之前将授权原代码进行修改,然后调用授权代码时即调用已经修改后的授权代码,而真实的授权代码是查看不了的(通过某种方式注入),这样即达到一种授权方式的隐藏。
可以通过javassist来修改java类的一个方法,来修改一个方法的真实实现。修改的方法可以是动态方法,也可以是静态方法。修改的前提即是当前修改的类还没有被当前jvm加载,如果当前的类已经被加载,则不能修改。
ClassPool classPool = ClassPool.getDefault(); CtClass ctClass = classPool.get("com.develop.Txt"); CtMethod ctMethod = ctClass.getDeclaredMethod("i"); ctMethod.setBody("{try{Integer i = null;" + "int y = i.intValue();System.out.println(\"this is a new method\");"); ctClass.toClass();
上面的方法即是修改一个方法的实现,当调用ctClass.toClass()时,当前类即会被当前的classLoader加载,并实例化类。
需要注意的是,在调用ctClass.toClass()时,会加载此类,如果此类在之前已经被加载过,则会报一个duplicate load的错误,表示不能重复加载一个类。所以,修改方法的实现必须在修改的类加载之前进行。
即使不调用toClass,那么如果当前修改的类已经加载,那么修改方法实现,同样不起作用,即修改一个已经加载的类(不论是修改静态方法,还是修改动态方法)是没有任何效果的。修改之前必须在类加载之前进行。
当然,使用aspectj也可以同样达到修改的效果,不过修改指定的类,则需要为修改这个类添加一个aspect,然后将这个aspect加入配置文件中以使其生效,比起javassist来说,修改一个类还是使用javassist相对简单一点。
转载请标明出处:i flym
本文地址:https://www.iflym.com/index.php/code/use-javassist-to-modify-java-object-method.html