本文版權歸贛州兆鑫軟件全部,原創未經許可禁止轉載!
本文僅做學習交流目的,提倡軟件正版,反對盜版!html
若是你用到的Jar文件使用了簽名,它會保證裏面的每一個class文件不能被修改,因此即便你成功修改了class文件中的字節碼,獲得的Jar也是沒法運行的。這些通過簽名的Jar包的META-INF文件夾中通常包含了*.SF
和相應的*.RSA
文件。這些文件記錄Jar包中每一個文件的簽名信息,以保證代碼不被篡改。java
使用下面的方法能夠從新生成一個未簽名Jar包。參考自stackoverflow做者Houtman的回答oracle
// 使用JDK編譯代碼 javac JarUnsigner.java // 執行JarUnsigner,若是是同一個文件夾 java -cp . JarUnsigner <inJar> <outJar>
附上源代碼,省得回答被刪jvm
// JarUnsigner.java import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; public class JarUnsigner { private static final String MANIFEST = "META-INF/MANIFEST.MF"; public static void main(String[] args){ if (args.length!=2){ System.out.println("Arguments: <infile.jar> <outfile.jar>"); System.exit(1); } String infile = args[0]; String outfile = args[1]; if ((new File(outfile)).exists()){ System.out.println("Output file already exists:" + outfile); System.exit(1); } try{ ZipFile zipFile = new ZipFile(infile); final ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(outfile)); for (Enumeration e = zipFile.entries(); e.hasMoreElements();) { ZipEntry entryIn = (ZipEntry) e.nextElement(); if (! exclude_file( entryIn.getName() ) ) { /* copy the entry as-is */ zos.putNextEntry( new ZipEntry( entryIn.getName() )); InputStream is = zipFile.getInputStream(entryIn); byte[] buf = new byte[1024]; int len; while ((len = (is.read(buf))) > 0) { zos.write(buf, 0, len); } zos.closeEntry(); } else { if (MANIFEST.equals(entryIn.getName())){ /* if MANIFEST, adjust the entry */ zos.putNextEntry(new ZipEntry(MANIFEST)); // manifest entries until first empty line. i.e. the 'MainAttributes' section // (this method is used so to keep the formatting exactly the same) InputStream mIS = zipFile.getInputStream(entryIn); BufferedReader in = new BufferedReader(new InputStreamReader(mIS)); String line = in.readLine(); byte[] mNL = "\n".getBytes("UTF-8"); while( line != null && !line.trim().isEmpty() ) { zos.write( line.getBytes("UTF-8")); zos.write( mNL ); line = in.readLine(); } zos.write( mNL ); zos.closeEntry(); }else{ /* else: Leave out the Signature files */ } } } zos.close(); System.out.println("Successfully unsigned " + outfile); }catch(IOException ex){ System.err.println("Error for file: " + infile); ex.printStackTrace(); System.exit(1); } } /** * Exclude .SF signature file * Exclude .RSA and DSA (signed version of .SF file) * Exclude SIG- files (unknown sign types for signed .SF file) * Exclude Manifest file * @param filename * @return */ public static boolean exclude_file(String filename){ return filename.equals("META-INF/MANIFEST.MF") || filename.startsWith("META-INF/SIG-") || filename.startsWith("META-INF/") && ( filename.endsWith(".SF") || filename.endsWith(".RSA") || filename.endsWith(".DSA") ); } }
舉一個須要輸入序列號才能試用的庫文件的例子,可是爲了保護Jar包做者權益,對包名進行打碼了。經過Jar包的說明書,能夠知道如何使用它,就知道是什麼地方輸入序列號啦,要否則是個正常人也無法用對吧。例如ide
// 文檔說這樣子能夠驗證序列號 authentication.User("333"); authentication.Serial("94306-56191-128286-2967422");
Save All Sources
,具體步驟這裏省略;authentication
這個類文件,選擇Find Usages
,快捷鍵通常是Ctrl+G
,看到有個叫作p.java的文件用到,作了一些判斷操做Blabla,看屏幕截圖1:Licence OK!
,看屏幕截圖2:Ctrl
鍵,鼠標點擊那個t.a),咱們只要保證他獲得的結果的a屬性等於0就行了,能夠看到只有一種狀況下a屬性纔會等於0,其餘時候都是等於-1的,到這一步IDEA的使命就完成了,看屏幕截圖3:經過上面5步(取決於不一樣的包,不必定都是5步),咱們知道了須要改動t
類裏面的a
方法,讓它裏面操做屬性a
時,值爲-1
的都改成0
就能成功。工具
接下來就要使用dirtyJOE軟件來定位並修改字節碼了,做者也試過Class Editor, Java Bytecode Editor都因年久失修,沒改爲功。經過查閱JVM文檔咱們知道給整數賦值有幾種指令,這裏就說兩種:學習
iconst_<i>
i能夠爲 m1,0,1,2,3,4,5
,分別設置的值爲-1,0,1,2,3,4,5
,指令16進制字節碼分別是02
設置-1,03
設置0,04
設置1,以此類推bipush <i>
i範圍能夠是0-255,指令16進制字節碼是10
,好比代碼裏面有的21就是bipush 21
,16字節碼錶示爲10 15
t.class
文件,切換到 Methods 頁上,以下圖所示:-1
賦值給t$a.a
屬性,雙擊圖中的iconst_ml
,字節碼是02
,改成03
,而後回車便可,可使用Ctrl+F
查找多處進行修改:要保證字節碼的數量不增多,也不減小,由於類和類之間代碼調用跟字節位置關係密切。否則會致使修改的class文件沒法使用。原來一行是1個字節的,繼續用1個字節,2個的就繼續兩個,3個的繼續保持三個。this
這是最簡單的一步,將修改好的class文件,使用zip壓縮工具替換掉便可。若是是你Windows用戶不推薦使用WinRaR,能夠將jar文件(第一步生成的未簽名包)重命名爲zip文件,而後選擇用Windows資源管理器
打開,將修改的class文件複製粘貼進去。idea