Android反编译实践

1分钟速览,使用apktool反编译涉及的命令如下:

# 查看原APK签名信息
keytool -printcert -file STARTCOR.RSA 
# 反编译
./apktool d fileName.apk
# 重打包
./apktool b filePath
# 生成keystore签名文件
keytool -genkey -alias ziv.keystore -keyalg RSA -validity 20000 -keystore ziv.keystore
# 签名重打包后的apk
jarsigner -verbose -keystore ziv.keystore -signedjar fileName_signed.apk fileName.apk ziv.keystore

需要注意的是,生成keystore文件时输入的密码一定要牢记,在后续签名apk的时候需要使用

--------------------------------------------------速览结束--------------------------------------------------

前期准备

工具下载

apltool https://ibotpeaches.github.io/Apktool/install/
dex2jar https://sourceforge.net/projects/dex2jar/
jd-gui http://jd.benow.ca/

Smali基础

简单快速入门

  1. 数据类型
Java Smali
void V
boolean Z
byte B
short S
char C
int I
long J
float F
double D
对象 L
数组 [
  1. 语法
语法 含义
.field 定义变量
.method 方法
.parameter 方法参数
.prologue 方法开始
.line 12 此方法位于第12行
invoke-super 调用父函数
const/high16 v0, 0x7fo3 把0x7fo3赋值给v0
invoke-direct 调用函数
return-void 函数返回void
.end method 函数结束
new-instance 创建实例
iput-object 对象赋值
iget-object 调用对象
invoke-static 调用静态函数
  1. 跳转语句
跳转语句 含义
if-eq vA, vB, :cond_n 如果vA等于vB则跳转到:cond_n
if-ne vA, vB, :cond_n 如果vA不等于vB则跳转到:cond_n
if-lt vA, vB, :cond_n 如果vA小于vB则跳转到:cond_n
if-ge vA, vB, :cond_n 如果vA大于等于vB则跳转到:cond_n
if-gt vA, vB, :cond_n 如果vA大于vB则跳转到:cond_n
if-le vA, vB, :cond_n 如果vA小于等于vB则跳转到:cond_n
if-eqz vA, :cond_n 如果vA等于0则跳转到:cond_n
if-nez vA, :cond_n 如果vA不等于0则跳转到:cond_n
if-ltz vA, :cond_n 如果vA小于0则跳转到:cond_n
if-gez vA, :cond_n 如果vA大于等于0则跳转到:cond_n
if-gtz vA, :cond_n 如果vA大于0则跳转到:cond_n
if-lez vA, :cond_n 如果vA小于等于0则跳转到:cond_n

详细Smali相关在单独章节介绍

Apk文件初体验

简单的以压缩文件的形式解压得到如下文件信息:

  1. AndroidManifest.xml:应用的全局配置文件
  2. assets文件夹:原始资源文件夹,对应着Android工程的assets文件夹,一般用于存放原始的网页、音频等等。
  3. classes.dex:源代码编译成class后,转成jar,再压缩成dex文件,dex是可以直接在Android虚拟机上运行的文件。
  4. lib文件夹:引用的第三方sdk的so文件。
  5. META-INF文件夹:Apk签名文件。
  6. res文件夹:资源文件,包括了布局、图片等等。
  7. resources.arsc:记录资源文件和资源id的映射关系。

实现步骤

反编译apk

使用java -jar ../../apltool/apktool.jar d Demo.apk得到反编译后的smali文件
其他参数信息

-f 如果目标文件夹已存在,强制删除现有文件夹
-o 指定反编译的目标文件夹的名称(默认会将文件输出到以Apk文件名命名的文件夹中)
-s 保留classes.dex文件(默认会将dex文件解码成smali文件)
-r 保留resources.arsc文件(默认会将resources.arsc解码成具体的资源文件)

如:java -jar apktool.jar d yourApkFile.apk -o destiantionDir -s
错误信息brut.android.UndefinedResObject表示当前apktool.jar版本太低

将dex文件转为jar文件

使用dex2jar工具
d2j-dex2jar classes.dex

使用enjarify工具
https://github.com/Storyyeller/enjarify

查看jar文件

下载好对应平台的jd-gui运行,File->Open或直接拖动相应的jar文件在窗口内即可查看

定位关键信息修改Smali文件

奇技淫巧

  1. 根据string信息
  2. 根据反编译后的jar文件确定想要找的信息
  3. 根据AndroidManifest.xml和res信息

重编译apk

java -jar ../../apltool/apktool.jar b -f Demo/

重编译后的Apk是没有签名信息的,安装时会提示失败,错误信息Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]

签名安装

生成签名文件

keytool -genkey -alias demo.keystore -keyalg RSA -validity 20000 -keystore demo.keystore

签名Apk

jarsigner -verbose -keystore ziv.keystore -signedjar Demo_resign.apk -digestalg SHA1 -sigalg MD5withRSA Demo.apk ziv.keystore
adb install -r Demo_resign.apk

jarsigner参数解释

$jarsigner -h
用法:jarsigner [选项] jar 文件别名(key的别名)
       jarsigner -verify [选项] jar 文件
[-keystore ]           密钥库位置
[-storepass <口令>]         用于密钥库完整性的口令
[-storetype <类型>]         密钥库类型
[-keypass <口令>]           专用密钥的口令(如果不同)
[-sigfile <文件>]           .SF/.DSA 文件的名称
[-signedjar <文件>]         已签名的 JAR 文件的名称
[-digestalg <算法>]         摘要算法的名称
[-sigalg <算法>]            签名算法的名称
[-verify]                   验证已签名的 JAR 文件
[-verbose]                  签名/验证时输出详细信息
[-certs]                    输出详细信息和验证时显示证书
[-tsa ]                时间戳机构的位置
[-tsacert <别名>]           时间戳机构的公共密钥证书
[-altsigner <类>]           替代的签名机制的类名
[-altsignerpath <路径列表>] 替代的签名机制的位置
[-internalsf]               在签名块内包含 .SF 文件
[-sectionsonly]             不计算整个清单的散列
[-protected]                密钥库已保护验证路径
[-providerName <名称>]      提供者名称
[-providerClass <类>        加密服务提供者的名称
[-providerArg <参数>]] ...  主类文件和构造函数参数

应用实例

  1. 学习
    检查自己的代码漏洞,应用安全方向的使用

  2. 个性化
    比如修改应用显示的名字,图标等信息。
    文字信息修改文件\res\values\string.xml
    图片资源在\res\bitmap\res\mipmap目录下

  3. 汉化
    -->简单汉化:在res目录下创建values-zh-rCN文件夹新建string.xml文件,对应翻译所有原本res\values\string.xml文件中的内容即可
    -->高级汉化:当字符内容在代码中的时需要修改定位到的.smali文件。
    如:const-string v5, "ServiceMode"不能直接替换ServiceMode为服务模式,需要替换为对应中文的16进制unicode表示,即const-string v5, "\u670d\u52a1\u6a21\u5f0f"
    在线转换工具

  4. 去广告
    为什么有广告…这个原因太多,也不好说广告到底是好是坏…在此仅为技术分享,不涉及利益。
    一般广告的控件com.xxx.AdView是以该标识表示,关键信息的定位在这里就显得尤为重要,将这部分信息修改设置为

android:layout_width="0.0dip"
android:layout_height="0.0dip"
android:background="#ff000000"

代表含义是,设置空间大小为0*0,背景透明

拓展

他山之石,可以攻玉

ClassyShark

Google出品ClassyShark
GitHub:https://github.com/google/android-classyshark
使用java -jar ClassyShark.jar运行后直接打开你想查看的apk文件即可

APKParser

运行在Android移动端的分析工具APKParser
GitHub:https://github.com/jaredrummler/APKParser

ApkParser

other

更多工具及使用可以参考http://www.androiddevtools.cn/

error

安装出错INSTALL_FAILED_UPDATE_INCOMPATIBLE,安装包签名不一致导致

  1. adb uninstall 包名
  2. 删掉data/data/包名
  3. /data/system/packages.xml文件中删除该应用包含的包名信息
  4. 重新挂载mount -o remount,rw /system
  5. 添加权限chmod 777 /system

参考文件
https://ibotpeaches.github.io/Apktool/documentation/
https://www.cnblogs.com/cuiyubo/p/6721397.html
https://blog.csdn.net/wh_19910525/article/details/7915738/

你可能感兴趣的:(Android反编译实践)