隨筆-16  評論-54  文章-0  trackbacks-0
          ?????? 上面說到代碼混淆方法之混淆器使用,主要針對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 閱讀(9080) 評論(13)  編輯  收藏

          評論:
          # re: 代碼混淆方法之二(tomcat下面代碼加密) 2006-07-26 14:11 | 膠水
          你上面修改的文件如何不被反編譯呢?如果被反編譯了那個文件,其他加密的classes也可以被解密了。直接將解密后的結果寫入到一個新的文件,然后在反編譯。這個感覺只能防君子不能防小人啊。。。

          if(name.indexOf("OrganizationServiceImp") >=0)
          {
          byte[] base64Array = entry.binaryContent;
          byte[] orginByteArray = Base64.decodeBase64(base64Array);
          //將解密后的byte寫入到一個文件里,然后就可以反編譯咯
          clazz = defineClass(name, orginByteArray, 0,
          orginByteArray.length,
          codeSource);
          }  回復  更多評論
            
          # re: 代碼混淆方法之二(tomcat下面代碼加密) 2006-07-26 19:18 | jspark
          呵呵,是的,說得沒錯,只能防君子不能防小人。

          可以先用代碼混淆、然戶再通過上面辦法加密。  回復  更多評論
            
          # re: 代碼混淆方法之二(tomcat下面代碼加密) 2006-08-31 14:48 | qy
          知道jboss下怎么做嗎  回復  更多評論
            
          # re: 代碼混淆方法之二(tomcat下面代碼加密) 2006-12-03 18:21 | 小孫
          重新打包時提示 找不到BASE64等定義,我已經在WebappClassLoader中import 了相關類??
          我不知道該將下載的commons-codec.jar放到tomcat源文件哪個目錄下,在生成tomcat的過程中才會讀取到!!
          急用!!!
          謝謝!!!  回復  更多評論
            
          # re: 代碼混淆方法之二(tomcat下面代碼加密) 2006-12-03 18:50 | 小孫
          現在已經重新生成tomcat了,運行web應用時,
          提示:
          javax.servlet.ServletException: Illegal UTF8 string in constant pool in class file web/login/LoginService
          org.apache.jasper.servlet.JspServlet.service(JspServlet.java:272)
          javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
          ---
          其中,web.login.LoginService.class是我用commons-codec,加密生成的文件,好像UTF8錯誤,請問怎么解決這個問題  回復  更多評論
            
          # re: 代碼混淆方法之二(tomcat下面代碼加密) 2006-12-14 14:53 | terry[匿名]
          請問怎么再重新打包catalina.jar,平時用JBuilder的,不了解。  回復  更多評論
            
          # re: 代碼混淆方法之二(tomcat下面代碼加密) 2008-03-22 16:39 | fenixshadow
          沒有萬全的辦法,能防君子就不錯了。

          "可以先用代碼混淆、然戶再通過上面辦法加密。"

          一樣可以先解密得到代碼,然后用IDE進行重構。

            回復  更多評論
            
          # re: 代碼混淆方法之二(tomcat下面代碼加密) 2009-03-26 09:28 | 黃祥飛
          其實是可以很完美的加密的。把你解密那部分代碼用JNI調用SO庫返回一個jclass對象就可以實現完美加密了。  回復  更多評論
            
          # Web虎-tomcat,resin,jboss,websphere加密軟件保護 2009-11-13 16:30 | jsp加密
          可看看易用的產品:通過windows文件系統驅動對需要保護的文件進行<b>實時加解密</b>來實現對軟件源碼/版權的綜合保護

          驅動層保護,操作簡便,保護可靠,性能優異;成功案例有北京文化在線/哈爾濱聯得軟件股份公司,廣州knowtel等多家tomcat/websphere環境下的客戶  回復  更多評論
            
          # Web虎-tomcat,resin,jboss,websphere加密軟件保護 2009-11-13 16:46 | tomcat加密
          忘了說:1.現在要用,可免費贈送1套硬件碼版的 2.是騾子是馬,拉出來溜溜  回復  更多評論
            
          # re: 代碼混淆方法之二(tomcat下面代碼加密) 2010-03-02 17:15 | 硬件碼版改為機器碼版了
          @tomcat加密

          沒有改變的是 免費送您繼續免費贈送 全功能、無任何限制的 機器碼版;

          除此之外,還為您提供 加密狗版、打包加密版的免費試用,歡迎通過標題連接來訪  回復  更多評論
            
          # re: 代碼混淆方法之二(tomcat下面代碼加密) 2010-03-14 21:21 | yi guangping
          ujiw yfjm k; j3ujfk  回復  更多評論
            
          # re: 代碼混淆方法之二(tomcat下面代碼加密) 2011-07-21 21:59 | 青青園中葵
          @黃祥飛
          能說一下怎樣從so庫返回jclass對象嗎?是java class對象嗎?  回復  更多評論
            

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 铜梁县| 汶上县| 万山特区| 绥宁县| 家居| 武邑县| 无为县| 佛冈县| 蕲春县| 漳平市| 文化| 当阳市| 南昌市| 寻甸| 蓝山县| 托克托县| 安顺市| 壶关县| 潢川县| 大化| 双辽市| 新邵县| 新兴县| 华亭县| 古交市| 灵寿县| 明光市| 新巴尔虎右旗| 张掖市| 阜新市| 辽宁省| 富源县| 海南省| 万盛区| 将乐县| 读书| 宜州市| 呼和浩特市| 喀喇沁旗| 屏东市| 瑞金市|