国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

深入討論JAVA字節碼加密技術(2)

2019-11-18 12:22:30
字體:
來源:轉載
供稿:網友

  這個累加載器(EncryptedClassLoader)有兩個基本的操作,在給定的類路徑下加密一系列Class文件并且運行一個先前加密的程序。加密后的文件很簡單,有一些極討厭的各個字節的位組成。(當然,XOR運算符不可能被加密,這只是一個范例,請多多包涵。)
  
    通過EncryptedClassLoader來加載類需要注重一些問題,我實現的是繼續自java.net.URLClassLoader并且重載了loadClass()和defineClass()兩個方法來實現自己的兩個功能。一個是專心于JAVA 2 類加載器的委托規則并且在系統類加載器做之前先加載一個經加密過的類;二是在執行defineClass()之前立即調用crypt()方法,否則會執行URLClassLoader.findClass()。
  
    執行下面的語句:
  
  >javac -d bin src/*.java src/my/secret/code/*.java
  
  
  
    我把Main.class和MySecretClass.class進行了.加密:
  
  >java -cp bin EncryptedClassLoader -encrypt bin Main my.
  secret.code.MySecretClass
  encrypted [Main.class]
  encrypted [my/secret/code/MySecretClass.class]
  
  
  
    現在原先編譯的class文件已經被加密后的文件所替代了,假如我想運行原始類文件,需要使用EncryptedClassLoader來操作:
  
  >java -cp bin Main
  Exception in thread "main" java.lang.ClassFormatError:
   Main (Illegal constant pool type)
   at java.lang.ClassLoader.defineClass0(Native Method)
   at java.lang.ClassLoader.defineClass(ClassLoader.java:502)
   at java.security.SecureClassLoader.defineClass
   (SecureClassLoader.java:123)
   at java.net.URLClassLoader.defineClass(URLClassLoader.java:250)
   at java.net.URLClassLoader.access$100(URLClassLoader.java:54)
   at java.net.URLClassLoader$1.run(URLClassLoader.java:193)
   at java.security.AccessController.doPRivileged(Native Method)
   at java.net.URLClassLoader.findClass(URLClassLoader.java:186)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:299)
   at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:265)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:255)
   at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:315)
  
  >java -cp bin EncryptedClassLoader -run bin Main
  decrypted [Main]
  decrypted [my.secret.code.MySecretClass]
  secret result = 1362768201
  
  
  
    現在可以確信,采用任何反編譯工具對加密后的Class文件都不會起作用的。
  
    現在添加一個可靠的密碼保護機制,把它打包成本地可執行文件,并且使其對外收費。這樣子可以嗎?當然不能這樣了。
  
    ClassLoader.defineClass():必然經過的接口
  
    所有的類加載器必須經過明確地API把類定義傳遞到JVM里,這就需要java.lang.ClassLoader.defineClass()方法了。類加載器的API有多個這個方法的重載,但是所有的方法都會調用defineClass(String, byte[], int, int, ProtectionDomain),這是一個在經過一些簡單驗證后放入到JVM里的最終的方法。假如你想建立一個新的Class文件的話,這對于理解每個類加載器都會不可避免的調用該方法是很重要的。
  
    你只能在方法defineClass()里把一些單調的字節數組生成Class對象,并且我們猜測這些字節數組文件會包含一些文檔格式化(查看class文件格式規范well-document.d format)的未加密的class定義,通過攔截對該方法的所有調用可以很簡單的破壞這種加密模式,并且很方便的反編譯你感愛好的Class文件。
  
    做這種攔截并不困難,實際上破壞自己建立的保護模式比用工具更加迅速的。首先,我取得基于J2SDK的java.lang.ClassLoader源文件,并修改defineClass(String, byte[], int, int, ProtectionDomain)方法,在里面加入其他的類。正如下面:
  
  ...
  c = defineClass0(name, b, off, len, protectionDomain);
  //Intercept classes defined by the system loader and its children:
  if (isAncestor (getSystemClassLoader ().getParent ()))
   {
   // Choose your own dump location here [use an absolute pathname]:
   final File parentDir = new File ("c:/TEMP/classes/");
   File dump = new File (parentDir,
   name.replace ('.', File.separatorChar) + "[" +
   getClass ().getName () + "@" +Long.toHexString
   (System.identityHashCode (this)) + "].class");
  
   dump.getParentFile ().mkdirs ();
  
   FileOutputStream out = null;
   try
   {
   out = new FileOutputStream (dump);
   out.write (b, off, len);
   }
   catch (IOException ioe)
   {
   ioe.printStackTrace (System.out);
   }
   finally
   {
   if (out != null) try { out.close (); }
   catch (Exception ignore) {}
   }
   }
  ...
  
  
  
    注重if里的語句可以過濾系統類加載器及其子類加載器,同樣在defineClass()方法可以正常工作的情況下才能載入類。很難以相信不只有一個類加載器實例加載一個類,可通過在文件名堆里面加入類加載器標志我還是最終把這一問題給解決了。:-)
  
    最后一步是用包含java.lang.ClassLoader類的可執行文件臨時替換由JRE使用的文件rt.jar,你也可以使用-Xbootclasspath/p選項。
  
    我再一次運行加密的程序,并恢復了所有的未加密的文件,這么說可以很輕易的把.class文件正確的反編譯。我先聲明我并沒有用EncryptedClassLoader類的內部機制來完成此壯舉的。
  
    在這里注重一點,假如我沒去使用一個系統類,我可以使用別的方法,比如自定義一個JVMPI代理來處理JVMPI_EVENT_CLASS_LOAD_HOOK事件。
  
    學習小結:
  
    我希望你能對本文有所愛好,你必須熟悉到得很重要的一點是在購買市面上任何反編譯工具前要三思而行,除非JVM體系結構進行改革以支持class字節碼在本地能進行譯碼轉換,你才會更好的從傳統的困惑中走出來,上演一場字節碼的改革浪潮!當然也有其他的更有效的方法:對類加載進行調試。盡可能地得到類加載的軌跡是很有價值的,非凡是在類加載時你去捕捉異常情況下使用。因此,JAVA的誕生可能純粹是為了開源項目,當然,其他一些體系結構(如:。NET)也正在傾向于反編譯。目前我就說說這種思想了.

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 彝良县| 咸丰县| 库尔勒市| 自贡市| 凭祥市| 遵化市| 宝山区| 濮阳县| 文山县| 东阿县| 武宁县| 元朗区| 阿拉善盟| 景东| 博兴县| 铁力市| 武义县| 额济纳旗| 东乌珠穆沁旗| 蕲春县| 丹凤县| 株洲县| 东阳市| 民权县| 黄大仙区| 新竹市| 读书| 平度市| 永寿县| 姜堰市| 金阳县| 公主岭市| 修文县| 甘洛县| 遂昌县| 罗平县| 崇义县| 宜君县| 延寿县| 揭东县| 白河县|