首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

代码搅混方法之tomcat解密代码

2012-10-16 
代码混淆方法之tomcat解密代码说到代码混淆方法之混淆器使用,主要针对proguard进行了说明。其实,只要我们的

代码混淆方法之tomcat解密代码

说到代码混淆方法之混淆器使用,主要针对proguard进行了说明。其实,只要我们的类被其他地方的类调用到的话,那么代码混淆器就似乎没有办法了,因为代码混淆如果把代码的签名一起改了的话,其他地方是肯定调用不到,并会出错。而且,针对代码调用,有几点是我们肯定不能避免的:一是jsp页面,如果在jsp页面调用了某个类,那么如果类被混淆了的话,jsp页面肯定会出错;二是xml配置文件,比如在hibernate开发中,对于hbm.xml文件,就没办法了。不过,很庆幸的是,proguard的功能很强,可以通过配置,只针对私有方法、私有变量做混淆。但是,这种混淆效果肯定是不如所愿。下面将说明代码混淆方法之二(tomcat下面代码加密)

?????? 应用服务器加密的方法不外就是通过修改该应用服务器的类转载器,来载入我们的类。首先我们通过一定算法,将我们的class文件加密,并部署到应用服务器。然后修改修改该应用服务器的类转载器,通过解密算法将class文件反编译并加载。从而达到class文件的加密。下面主要针对tomcat下面的加密、解密说明。

???? 首先得研究一下tomcat的类装载机制:tomcat的类装载机制主要分为下面几种:

???1、Bootstrap: 由虚拟机提供
???2、System:类路径等相关
?? 3、Common:tomcat下面的公共包
?? 4、Catalina:tomcat自己的包,比如server目录下面
?? 5、Shared:各个war包的共享包
?? 6、Webapp:各个war包自己的相关类包

???由于一般的典型情况是,我们是要加密自己的应用程序,那么,我们就要覆盖上面所说的Webapp类装载器。tomcat的Webapp类装载器位于${tomcat.home}\server\lib\catalina.jar下面的类org.apache.catalina.loader.WebappClassLoader。我们从tomcat的网站下面下载tomcat的源代码,WebappClassLoader的源代码位于目录\jakarta-tomcat-catalina\catalina\src\share\org\apache\catalina\loader下面,打开源代码,可以看到里面的调用机制是这样的:
??? ?该类里面提供了很多诸如addRepository、addJar之类的方法,这是tomcat给类路径添加相应的目录和包,比如在启动时,tomcat会将我们的应用程序下面的WEB-INF/lib/*.jar和WEB-INF/classes/**.class添加到资源路径下面。
????
????首先,在加载类的时候,会调用loadClass方法。我们先定位到下面这个方法???
???? public Class loadClass(String name, boolean resolve)
??????? throws ClassNotFoundException?

???? 仔细观察该方法,可以发现,tomcat提供了很多缓存机制,首先分别从各个级别的缓存加载类,如果加载到类,就直接返回,否则会调用下面的方法: clazz = findClass(name);

???? 继续定位到方法 public Class findClass(String name) throws ClassNotFoundException?
???? 该方法里面有一句调用 clazz = findClassInternal(name); 这个很关键,也就是我们最需要关心的一个方法了。再仔细阅读一下,就能发现,tomcat从本地的资源库里面找,并先查找资源缓存,如果找到的话,直接返回缓存类。若找不到,就会读取类文件的byte[]数组,并最后调用defineClass方法。defineClass文件是类装载的最后一个类定义方法。下面就是findClassInternal方法的代码小段

?????????? if (entry.loadedClass == null) {
??????????? synchronized (this) {
??????????????? if (entry.loadedClass == null) {
?????????????????
??????????????????clazz = defineClass(name, entry.binaryContent, 0,
??????????????????????????????????????? entry.binaryContent.length,
??????????????????????????????????????? codeSource);???????????????
?????????????????}
??????????????????? entry.loadedClass = clazz;
??????????????????? entry.binaryContent = null;
??????????????????? entry.source = null;
??????????????????? entry.codeBase = null;
??????????????????? entry.manifest = null;
??????????????????? entry.certificates = null;
??????????????? } else {
??????????????????? clazz = entry.loadedClass;
??????????????? }
??????????? }
??????? } else {
??????????? clazz = entry.loadedClass;
??????? }

??????entry是一个存放类属性的bean,其中类的数组流存放在binaryContent,那么我们的加密解密就从这里入手。为了方便起见,我们用base64算法加密,加密方法很简单。通过调用base64加密方法,把原有的class文件加密;推荐的base64加密方法是commons包的codec工程。可以从apache上面下载。把加密后的class文件替换tomcat下面的部署类文件。 那么在类装载时就可以解密,并加载了。例如,为了测试,个人只对OrganizationServiceImp.class进行加密,那么通过修改以上的装载方法,就可以实现解密,修改后的代码为如下,其中黑体为修改的

??????? if (entry.loadedClass == null) {
??????????? synchronized (this) {
??????????????? if (entry.loadedClass == null) {
??????????????? ?
??????????????? ?if(name.indexOf("OrganizationServiceImp") >=0)
??????????????? ?{
????????????????????byte[] base64Array = entry.binaryContent;
????????????????????byte[] orginByteArray = Base64.decodeBase64(base64Array);
????????????????????clazz = defineClass(name, orginByteArray, 0,
??????????????????????orginByteArray.length,?
???????????????????????????????codeSource);
?????????????????}
??????????????? ?else
??????????????? ?{
??????????????? ??clazz = defineClass(name, entry.binaryContent, 0,
??????????????????????????????????????? entry.binaryContent.length,
??????????????????????????????????????? codeSource);
???????????????????????????????????????
??????????????? ?}

??????????????????? entry.loadedClass = clazz;
??????????????????? entry.binaryContent = null;
??????????????????? entry.source = null;
??????????????????? entry.codeBase = null;
??????????????????? entry.manifest = null;
??????????????????? entry.certificates = null;
??????????????? } else {
??????????????????? clazz = entry.loadedClass;
??????????????? }
??????????? }
??????? } else {
??????????? clazz = entry.loadedClass;
??????? }
??????
??????
运行服务器,一切正常,说明解密、加密成功,到此完成tomcat服务器下面的解密、加密。可以看出,tomcat下面的类装载机制其实挺简单,不像其他服务器,比如weblogic、websphere服务器那么复杂。若能在这些服务器下面实现类似的效果,将是一个多么爽的事。个人在近几天将对weblogic服务器下面的部署应用进行类似的研究

热点排行