想让你的资源文件被混淆吗?快来试试AndResGuard吧

ifuqiang 8年前
   <p>最近闲下来没什么事情,遂没事找事做,试试各种新轮子。AndResGuard是腾讯的 shwenzhang 开源在 github 上的项目,他帮助你缩小APK大小,他的原理类似Java Proguard,但是只针对资源,将原本冗长的资源路径变短,例如将res/drawable/wechat变为r/d/a。</p>    <p>我选择通过命令行的方式将包打出,因为之前试用了Tinker,感觉项目被搞得乱七八糟的了。</p>    <h3>环境变量的设置</h3>    <ul>     <li>android环境变量。这个没啥说的,特别注意build-tools是有版本号区分的,我们要使用其中的zipalign这个优化工具</li>     <li>7zip环境变量。由于支持7z极限压缩,所以需要单独设置一下。 <pre>  <code class="language-java">window: 对于window应下载命名行版本,若将7za指定到环境变量,即无须设置。地址:[http://sparanoid.com/lab/7z/download.html](http://sparanoid.com/lab/7z/download.html)  linux:sudo apt-get install p7zip-full  mac:brew install p7zip</code></pre> </li>    </ul>    <h3>前期准备</h3>    <ul>     <li>下载 AndResGuard ,将其中tool_output文件夹单独拿出来。<br> 简单说明一下,jar包不多说了;bat跟sh分别是windows跟linux的执行脚本,这里面的执行命令稍后要进行修改,符合我们自身情况才行;config就是混淆压缩属性的配置文件;keystore就是app签名文件<br> <img src="https://simg.open-open.com/show/4e219ac8b8754c3bbfd11dc9dc256ba0.png"> <p>AndResGuard</p> </li>     <li>去除release.keystore,换成我们自己的app签名文件。</li>     <li>修改config.xml配置文件。后面我会结合官方文章进一步说明</li>     <li>修改build_apk脚本。由于我是mac,所以只演示了如何修改build_apk.sh</li>    </ul>    <h3>如何写config配置文件</h3>    <p>配置文件中主要有五大项,即 <strong> <em>property</em> </strong> , <strong> <em>whitelist</em> </strong> , <strong> <em>keepmapping</em> </strong> , <strong> <em>compress</em> </strong> , <strong> <em>sign</em> </strong> 。</p>    <ol>     <li> <p>Property主要设置一些通用属性。</p> <p>-- <em>sevenzip</em> ,是否使用7z重新压缩签名后的apk包。前提条件是安装好7z并且加入环境变量中,同时要求加入签名信息,不然不使用</p> <p>-- <em>metaname</em> ,由于重打包时需要删除签名信息,考虑到这个文件名可能会被改变,所以使用者可手动输入签名信息对应的文件名。默认为META_INF。这个我也不知道是干嘛的</p> <p>-- <em>keeproot</em> ,是否将res/drawable混淆成r/s。true的话则不会将res/drawable混淆成r/s</p> </li>     <li> <p>Whitelist主要是用来设置白名单。</p> <p>-- <em>isactive</em> ,是否打开白名单功能</p> <p>-- <em>path</em> ,白名单的列表,格式为package_name.R.type.specname。由于一个resources.arsc中可能会有多个包,所以这里要求写全包名。同时支持*,?通配符,例如: com.tencent.mm.R.drawable.emoji_*,com.tencent.mm.R.drawable.emoji_?。linux用/, window用\。</p> <p>注意:</p> <p>1、 若想通过getIdentifier方式获得资源,需要放置白名单中。 部分手机桌面快捷图标的实现有问题,务必将程序桌面icon加入白名单。</p> <p>2、 对于一些第三方sdk,例如友盟,可能需要将部分资源添加到白名单中。</p> </li>     <li> <p>Keepmapping主要用来指定旧的mapping文件,为了保持一致性,我们支持输入旧的mapping文件,可保证同一资源文件在不同版本混淆后的名称保持一致。该文件在重打包生成,需额外保存。</p> <p>-- <em>isactive</em> ,是否打开keepmapping模式</p> <p>-- <em>path</em> ,旧mapping文件的位置,linux用/, window用\</p> </li>     <li> <p>Compress主要用来指定文件重打包时是否压缩指定文件,默认我们重打包时是保持输入apk每个文件的压缩方式(即Stored或者Deflate)。</p> <p>-- <em>isactive</em> ,是否打开compress模式;</p> <p>-- <em>path</em> ,需要被压缩文件的相对路径(相对于apk最顶层的位置)。</p> <p>这里path也有几个注意点:</p> <p>1、 一定要使用/作为分隔符,同时支持通配符*,?,例如*.png(压缩所有.png文件),res/drawable/emjio_?.png,resouces.arsc(压缩 resources.arsc)。</p> <p>2、 若想得到最大混淆:输入四项个path:*.png,*.jpg,*.jpeg,*.gif。</p> <p>3、 若你的resources.arsc原文件小于1M,可加入resourcs.arsc这一项!在2.3版本以下源文件大于1M不能压缩,若不需要支持低版本,也可以直接加入。</p> <p>4、 流媒体不能压缩。但是.png、.jpg是可以压缩的,只是AssetManger读取时候的方式不同。</p> <p>5、 操作系统对7z的影响。实验证明,linux与mac的7z效果更好</p> </li>     <li> <p>Sign主要是对处理后的文件重签名,需要我们输入签名文件位置,密码等信息。若想使用7z功能就一定要填入相关信息。出于保密不想写在config.xml,可用-signature命令行设置模式,config.xml中的签名信息会被命令行覆盖,这里不再使用</p> </li>    </ol>    <p>这是我在提供的config.xml上的简单配置</p>    <pre>  <code class="language-java"><?xml version="1.0" encoding="UTF-8"?>  <resproguard>      <issue id="property">          <seventzip value="true"/>          <metaname value="META-INF"/>          <keeproot value="false"/>      </issue>      <issue id="whitelist" isactive="true">          <path value="com.renyu.sostar.R.mipmap.ic_launcher"/>      </issue>      <issue id="keepmapping" isactive="false">      </issue>      <issue id="compress" isactive="false">          <path value="*.png"/>          <path value="*.jpg"/>          <path value="*.jpeg"/>          <path value="*.gif"/>          <path value="resources.arsc"/>      </issue>      <issue id="sign" isactive="true">          <path value="android.keystore"/>          <storepass value="abcd1234"/>          <keypass value="abcd1234"/>          <alias value="android.keystore"/>      </issue>  </resproguard></code></pre>    <h3>使用命令行</h3>    <p>打开build_apk.sh进行修改</p>    <pre>  <code class="language-java">java -jar AndResGuard-cli-1.1.16.jar input.apk -config config.xml -out outapk -signature release.keystore testres testres testres</code></pre>    <p>最简单的就是直接java -jar AndResGuard-cli-1.1.16.jar input.apk,此时会读取运行路径中的config.xml文件,并将结果输出到运行路径中的input.apk中。</p>    <p>下面看看如何自定义</p>    <p>-- <strong>config</strong> ,指定具体config文件的路径;</p>    <p>-- <strong>out</strong> ,指定生成文件具体的输出路径,其中混淆的mapping会在输出文件夹中以resource_mapping_(输入apk的名称).txt命名。</p>    <p>-- <strong>signature</strong> ,指定签名信息,若在命令行设置会覆盖config.xml中的签名信息,顺序为签名文件路径、storepass、keypass、storealias。</p>    <p>-- <strong>mapping</strong> , 指定旧的mapping文件,保证同一资源文件在不同版本混淆后的名称保持一致。若在命令行设置会覆盖config.xml中的信息。</p>    <p>-- <strong>7zip</strong> ,指定7zip的路径,若已添加到环境变量则不需要设置。此处必须为全路径,例如linux: /shwenzhang/tool/7za,Windows需要加上.exe 结尾。</p>    <p>-- <strong>zipalign</strong> ,指定zipalign的路径,若已添加到环境变量则不需要设置。此处必须为全路径,例如linux: /shwenzhang/sdk/tools/zipalign,Windows需要加上.exe结尾。</p>    <p>-- <strong>repackage</strong> ,如果想要出渠道包等需求,我们可能希望利用7zip直接重打包安装包。</p>    <p>关于渠道包的问题我不是很理解,我觉得通过脚本一样可以直接遍历文件夹中的所有apk,分别生成新包</p>    <p>这样就很明了了,7zip与zipalign路径都通过环境变量自动可以获取到,mapping在第一次使用的时候是没有的,之后使用只要带上就行了,最后也就是config、out与signature</p>    <pre>  <code class="language-java">java -jar AndResGuard-cli-1.1.16.jar app-release.apk -config config.xml -out outapk -signature android.keystore abcd1234 abcd1234 android.keystore</code></pre>    <h3>我们得到什么</h3>    <p>运行吧</p>    <p><img src="https://simg.open-open.com/show/30ae8797bb63c8d62648274e68ab8559.png"></p>    <p>重打包相关信息</p>    <p><img src="https://simg.open-open.com/show/4446d31f42c623fc4fc60dac7f2b6b93.png"></p>    <p>执行结果</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/4d8fe341f3a27d7eb3b5ad52b60b28fb.png"></p>    <p>混淆效果</p>    <table>     <thead>      <tr>       <th>文件</th>       <th>描述</th>      </tr>     </thead>     <tbody>      <tr>       <td>app-release_signed_7zip_aligned.apk</td>       <td>若选择7z重打包模式,将得到一个对齐后可供发布的apk</td>      </tr>      <tr>       <td>app-release_signed_7zip.apk</td>       <td>若选择7z重打包模式,将得到一个7z重打包后的apk</td>      </tr>      <tr>       <td>app-release_signed_aligned.apk</td>       <td>若选择sign模式,将得到一个对齐后可供发布的apk</td>      </tr>      <tr>       <td>app-release_signed.apk</td>       <td>若选择sign模式,将得到一个签名后的apk</td>      </tr>      <tr>       <td>app-release_unsigned.apk</td>       <td>处理完成,未重签名的apk</td>      </tr>      <tr>       <td>resource_mapping_app-release</td>       <td>资源混淆的mapping文件,keepmapping要保留的</td>      </tr>      <tr>       <td>resources.arsc</td>       <td>修改后的resources.arsc文件</td>      </tr>     </tbody>    </table>    <p>看看效果</p>    <p>文件大小少了600k,并且混淆完美</p>    <h3>参考文章</h3>    <p><a href="/misc/goto?guid=4959731883834996480" rel="nofollow,noindex">如何使用资源混淆工具</a></p>    <p><a href="http://mp.weixin.qq.com/s?__biz=MzAwNDY1ODY2OQ==&mid=208135658&idx=1&sn=ac9bd6b4927e9e82f9fa14e396183a8f#rd" rel="nofollow,noindex">安装包立减1M--微信Android资源混淆打包工具</a></p>    <p> </p>    <p>来自:http://www.jianshu.com/p/bc7b0831e925</p>    <p> </p>