?????? 上面說到代碼混淆方法之混淆器使用,主要針對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服務器下面的部署應用進行類似的研究
posted on 2006-07-25 12:25
jspark 閱讀(9078)
評論(13) 編輯 收藏