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基础
简单快速入门
- 数据类型
Java | Smali |
---|---|
void | V |
boolean | Z |
byte | B |
short | S |
char | C |
int | I |
long | J |
float | F |
double | D |
对象 | L |
数组 | [ |
- 语法
语法 | 含义 |
---|---|
.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 | 调用静态函数 |
- 跳转语句
跳转语句 | 含义 |
---|---|
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文件初体验
简单的以压缩文件的形式解压得到如下文件信息:
- AndroidManifest.xml:应用的全局配置文件
- assets文件夹:原始资源文件夹,对应着Android工程的assets文件夹,一般用于存放原始的网页、音频等等。
- classes.dex:源代码编译成class后,转成jar,再压缩成dex文件,dex是可以直接在Android虚拟机上运行的文件。
- lib文件夹:引用的第三方sdk的so文件。
- META-INF文件夹:Apk签名文件。
- res文件夹:资源文件,包括了布局、图片等等。
- 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文件
奇技淫巧
- 根据string信息
- 根据反编译后的jar文件确定想要找的信息
- 根据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 <参数>]] ... 主类文件和构造函数参数
应用实例
学习
检查自己的代码漏洞,应用安全方向的使用个性化
比如修改应用显示的名字,图标等信息。
文字信息修改文件\res\values\string.xml
图片资源在\res\bitmap
或\res\mipmap
目录下汉化
-->简单汉化:在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"
在线转换工具去广告
为什么有广告…这个原因太多,也不好说广告到底是好是坏…在此仅为技术分享,不涉及利益。
一般广告的控件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
other
更多工具及使用可以参考http://www.androiddevtools.cn/
error
安装出错INSTALL_FAILED_UPDATE_INCOMPATIBLE
,安装包签名不一致导致
- adb uninstall 包名
- 删掉data/data/包名
- 在
/data/system/packages.xml
文件中删除该应用包含的包名信息 - 重新挂载
mount -o remount,rw /system
- 添加权限
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/