**

Android安全:反编译、二次打包、重新签名

**

一、 前言

记录一下Android 反编译以及二次打包、重新签名的过程笔记。

二、反编译三件套的介绍

反编译三件套:
· Apktool
    反编译xml文件和dex文件,并可以将编译后的项目重新打包成apk。
· dex2jar
    将classes.dex 转换为[.jar文件]
· jd-gui
    查看[.jar]文件
下载地址:链接:https://pan.baidu.com/s/1Quu5pI5mQbTwJyzUsiZtTQ  提取码:pbp3

#三、 三件套的使用

我们可以通过Apktool可以将apk文件进行反编译,但是直接把apk的扩展名改为[.zip] 也可以对其进行解压并得到一些资源文件

android 反编译然后打包 android反编译重新打包_android

· META-INF: 保存APP的签名信息
· classes.dex:.dex是Dalvik虚拟机上的可执行文件,需要使用dex2jar将其转换为jar文件
· AndroidManifest.xml:Android清单文件,向Android系统提供应用的全局配置文件。
· assets:存放一些资源文件字体、声音等
· lib:存放第三方库
· original:存放未经过反编译的等 AndroidManifest.xml文件
· res:存放资源文件,例如图片、颜色、字符等。
· smali:smali里存放的是java编译成的smali代码,smali相当于Android 虚拟机上允许的语言。

1、apktool工具:解压apk文件

将 apktool.bat文件和apktool.jar文件存放在统一目录下。

android 反编译然后打包 android反编译重新打包_反编译_02


进入cmd切换到aoktool目录下运行命令:apktool d(反编译) <path>.apk,对指定路径的apk的资源文件、源码文件解码,解码后的资源文件可以正常使用EditPlus打开。

android 反编译然后打包 android反编译重新打包_android 反编译然后打包_03


如果解压包不包含classes.dex文件,在上述命令行添加 -s,表示禁止将dex文件解码成smali:如下图:

android 反编译然后打包 android反编译重新打包_android_04


你的apk名字是啥,这里就应该写啥。然后就会出现一个以你apk名字命名的文件夹。

android 反编译然后打包 android反编译重新打包_Android_05


smali文件夹可以直接打开,里面的文件结构和目录跟原始的java文件目录是一致的。不过里面的文件并不是我们熟悉的java代码,这里我对smali做一个简单的解释。

Android虚拟机Dalvik并不是执行java虚拟机JVM编译后生成的class文件,而是执行在重新整合打包后生成的dex文件,dex文件反编译之后就是smali代码,可以说,smali语言是Dalvik的反汇编语言。2、dex2jar工具:打包jar文件

使用dex2jar工具将apktool工具解压的dex文件转换成jar文件。

android 反编译然后打包 android反编译重新打包_Android_06


打开cmd命令行,切换到dex2jar所在目录,运行命令:d2j-dex2jar.bat <path>.dex

android 反编译然后打包 android反编译重新打包_android 反编译然后打包_07


在dex2jar根路径下生成对应的jar包文件,该文件统一命令为:classes-dex2jar.har

android 反编译然后打包 android反编译重新打包_jar_08


3、jd-gui工具:辅助查看源码

classes-dex2jar.jar文件无法直接查看,借助jd-gui工具浏览classes-dex2jar.jar的源码文件。搜索并下载jd-gui或前往官网。

运行jd-gui.exe,选择制定的classes.dex2jar.jar文件。

android 反编译然后打包 android反编译重新打包_android_09

四、二次打包

这里就不演示反编译了,见上面,翻一遍
将反编译的文件里, 找到AndroidManifest.xml中package值,可对其进行修改,如要覆盖安装则不需修改。
同理找到res/string.xml中app_name可以修改应用名。assets中也可以替换任何你想替换的资源、在smali文件中找到对应代码进行修改。
打包: 重新打包后的apk在要打包的文件夹里的dist目录下

java  -jar  apktool的名字  b(打包)  要打包的文件夹名字

注意:重新打包编译apk,生成新的APK后,由于改动了文件内容,所以必须进行重新签名。

五、重新签名

运行jarsigner,如果没有设置PATH环境变量,那可以从JDK安装路径下的bin目录中找到,比如我本机的就是C:\Program Files\Java\jre1.8.0_221\bin\jarsigner.exe 常用的参数就是指定keystore的未知和签名后的文件,举例如下:注意:如何生成签名文件见下面教程

jarsigner -keystore C:\myKey.key -signedjar apk-signed.apk apk-unsigned.apk myKey

待签名的文件是apk-unsigned.apk,签名后的apk是apk-signed.apk。我们也可以不指定-signedjar参数,则在待签名的apk上直接签名。最后一个myKey是我的keystore的别名。

签名完成后再用WinRAR打开,会发现META-INF目录下多了MYKEY.RSA和MYKEY.SF两个文件,他们分别是:
MANIFEST.MF中保存了所有其他文件的SHA-1并base64编码后的值。
MYKEY.SF中也有其他文件的SHA-1并base64编码的值,而且还多一个MANIFEST.MF文件的SHA-1并base64编码后的值
MYKEY.RSA包含了公钥信息和发布机构信息
后两个文件的名称和我的key别名转换为大写后一致。

方法一(推荐):

复制命令到记事本保存为apk-sign.bat后运行

set/p keystore_path=请输入.keystore的文件路径:
set/p alias_path=请输入keystore的alias:
set/p unsign_path=请输入待签名的apk文件路径:
set/p sign_path=请输入签名后生成的apk文件路径:
jarsigner -verbose -keystore %keystore_path% -signedjar %sign_path% %unsign_path% %alias_path%
pause

运行后根据提示填上对应的信息,最后输入keystore的密码,提示jar已签名,就完成了。

android 反编译然后打包 android反编译重新打包_jar_10

方法二

除了方法一也可以在命令行里直接用一行命令解决,但需要4个参数:

①、keystore文件路径
②、签名后生成的apk路径
③、待签名的apk路径
④、keystore的alias(别名)

jarsigner -verbose -keystore keystore文件路径 -signedjar 签名后生成的apk路径 待签名的apk路径 别名

举例:

1、 例如,我已有的.keystore文件在D:\app\keystore的目录下,名为demo.keystore

android 反编译然后打包 android反编译重新打包_jar_11


2、待签名的apk在D:\app\apk的目录下,文件名是unsign.apk

android 反编译然后打包 android反编译重新打包_android 反编译然后打包_12


3、签名后会产生一个新的apk,然后我要让新的apk也生成在D:\app\apk目录下

4、keystore里面可能会存在多个别名,所以要注明一下别名,这里我的别名就是demo

jarsigner -verbose -keystore D:\app\keystore\demo.keystore -signedjar D:\app\apk\unsign.apk D:\app\apk\sign.apk demo

六、如何生成签名文件

1、点击Android Studio导航栏上的Build -> Generate Signed APK,首次点击可能会提示让我们输入操作系统的密码,输入密码后点击OK会弹出创建签名APK的对话框

android 反编译然后打包 android反编译重新打包_jar_13


2、点击Create new按扭创建新的签名文件。

android 反编译然后打包 android反编译重新打包_Android_14


最后生成生成的签名文件