如何生成混淆过的可执行的jar程序

mwsheng 8年前
   <p>最近因为工作需要提供几个Android 相关的小工具,这几个工具最终都是以可执行的jar的方式提供,开发期间遇到了一些问题,在这里专门总结一下备忘一下。</p>    <h2>怎么生成可执行java程序</h2>    <h3>相关源码:</h3>    <ul>     <li><a href="/misc/goto?guid=4959731834352774400" rel="nofollow,noindex">https://github.com/bihe0832/AndroidGetAPKInfo/tree/master/CheckAndroidV2Signature</a></li>    </ul>    <h3>具体案例</h3>    <p>可执行Java程序只需要一个入口程序即可,想要把哪个类作为执行入口,只需要在对应类实现static的main函数即可。例如源码中的 CheckAndroidSignature.java 。</p>    <p>在添加了main函数以后,cd到src目录即可编译运行对应的java程序。例如下面就完成了编译了运行:</p>    <pre>  <code class="language-java">➜  src git:(master) javac com/bihe0832/checksignature/CheckAndroidSignature.java  ➜  src git:(master) ✗ java com.bihe0832.checksignature.CheckAndroidSignature --version  com.tencent.ysdk.CheckAndroidV2Signature version 1.0.1 (CheckAndroidV2Signature - 2)  homepage : https://github.com/bihe0832/AndroidGetAPKInfo  blog : http://blog.bihe0832.com  github : https://github.com/bihe0832</code></pre>    <h2>怎么生成可执行jar</h2>    <p>上一步演示了如果生成可以执行的Java程序,但是这并不方便提供给第三者使用,因此我们需要把可执行的java代码进一步封装为一个可执行的jar。接下来会分别介绍包含第三方jar和不包含第三方jar的Java程序怎么生成可执行jar。两种方法都是直接使用Eclipse导出的方法,没有使用maven等其余方法。</p>    <h3>不包含第三方jar</h3>    <p>相关源码:</p>    <ul>     <li><a href="/misc/goto?guid=4959731834352774400" rel="nofollow,noindex">https://github.com/bihe0832/AndroidGetAPKInfo/tree/master/CheckAndroidV2Signature</a></li>    </ul>    <h3>具体案例</h3>    <p>CheckAndroidV2Signature 是一个完全自己写的,没有依赖第三方jar的java程序,接下来会step by step来介绍导出过程。</p>    <ul>     <li> <p>1.选择项目工程,然后右击选择导出,如下图:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/6d4e06302871e2c12fc6e99d4ce2d38a.jpg"></p> </li>     <li>2.在弹框(Select)中选择Java分类下面的 Jar File ,之后下一步。</li>     <li> <p>3.在新的弹框(JAR File Specification)中,选择你要导出的工程,并选择Jar包含的内容,一般一些IDE的配置文件之类的就不用导出了。然后选择并指定导出文件的路径和地址,之后下一步,如下图:</p> <p><img src="https://simg.open-open.com/show/db3de686365c31162066a707c642c81f.jpg"></p> </li>     <li>4.在新的弹框(JAR Packaging Options)中,保持默认的配置,然后继续下一步。</li>     <li> <p>5.在新的弹框(JAR Mainfest Specification)中,在最下方选择应用的主入口(Select the class of the application entry point)如下图:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/ff93def71fe82366f7434de4b891065a.jpg"></p> </li>     <li>6.设置OK以后直接点击Finish,如果不出意外,就会在之前设置的路径生成对应的jar</li>     <li> <p>7.执行命令检查效果,已经OK</p> <pre>  <code class="language-java">➜  src git:(master) ✗ java -jar ./../CheckAndroidV2Signature.jar --version    com.tencent.ysdk.CheckAndroidV2Signature version 1.0.1 (CheckAndroidV2Signature - 2)    homepage : https://github.com/bihe0832/AndroidGetAPKInfo    blog : http://blog.bihe0832.com    github : https://github.com/bihe0832</code></pre> </li>    </ul>    <h3>包含第三方jar</h3>    <p>在开发中发现,包含第三方jar和不包含的,处理方法会不太一样,目前还没有仔细研究不一样的原因,只确定用下面的方法可以解决。</p>    <p>相关源码:</p>    <ul>     <li><a href="/misc/goto?guid=4959731834451170340" rel="nofollow,noindex">https://github.com/bihe0832/AndroidGetAPKInfo/tree/master/GetApkInfo</a></li>    </ul>    <h3>具体案例</h3>    <p>GetApkInfo 是一个使用了AXMLPrinter和jdom写的java程序,运行时依赖两个jar。接下来会step by step来介绍导出过程:</p>    <ul>     <li> <p>1.选择项目工程,然后右击选择导出,如下图:</p> <p><img src="https://simg.open-open.com/show/30d233a60a087642320cca143eaee3a7.jpg" alt="如何生成混淆过的可执行的jar程序" width="550" height="457"></p> </li>     <li>2.在弹框(Select)中选择Java分类下面的 Runnable JAR file ,然后下一步。</li>     <li> <p>3.在新的弹框(Runnable Jar File Specification)中,选择你程序运行的入口类,指定导出文件的路径和地址,之后点击完成,如下图:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/e8deeb8885b7cfe0907597467e15e100.jpg"></p> </li>     <li> <p>4.如果不出意外,就会在之前设置的路径生成对应的jar。执行命令检查效果,已经OK</p> <pre>  <code class="language-java">➜  java -jar getPackageInfo-inner.jar --version    com.bihe0832.getPackageInfo version 1.0.1 (getPackageInfo - 2)    homepage : https://github.com/bihe0832/AndroidGetAPKInfo    blog : http://blog.bihe0832.com    github : https://github.com/bihe0832</code></pre> </li>    </ul>    <h2>jar 怎么混淆</h2>    <p>我们有时候虽然需要提供可执行jar给第三方,但是并不想很简单的让第三方了解我们的实现逻辑,因此最有效的办法就是代码混淆。Android中的代码混淆我们都很熟,对于Jar文件的代码混淆怎么做呢?</p>    <p>混淆工具</p>    <p>Android的sdk工具包里面已经整合了代码混淆相关的工具,放在sdk目录下的$tools/proguard/bin/中。</p>    <p>混淆规则文件</p>    <pre>  <code class="language-java">-injars       getPackageInfo-inner.jar  # 混淆前的文件  -outjars      getPackageInfo.jar  # 混淆后的文件    -libraryjars  <java.home>/lib/rt.jar # Java运行时    #常规的代码混淆规则    -dontwarn org.**  -keep class org.** { *;}    -keep public class com.bihe0832.packageinfo.Main {   public static void main(java.lang.String[]);  }</code></pre>    <p>关于代码混淆文件有几点说明:</p>    <ol>     <li>混淆前后的文件不要同名</li>     <li>Java可执行程序的入口函数不能被混淆</li>    </ol>    <p>混淆方法</p>    <p>将上面的混淆规则保存为文件,例如 proguard.pro ,把 proguard.pro 和待混淆的文件 getPackageInfo-inner.jar 按照 proguard.pro 中的路径设置,然后运行命令</p>    <pre>  <code class="language-java">➜  $ANDROID_HOME/tools/proguard/bin/proguard.sh @proguard.pro</code></pre>    <p>程序执行完成以后就生成了对应的jar,指定命令的时候注意混淆规则文件签名的 @ 符号。OK,至此就生成了可以混淆的可执行jar。</p>    <p> </p>    <p>来自:http://blog.bihe0832.com/runnable-jar.html</p>    <p> </p>