Android逆向工程初探
简介
本文介绍,如何使用APKtool反编译apk,使用dex2jar和jd-gui查看源码,并使用签名工具,对修改后的apk进行二次签名。
如何配置smali调试环境,动态调试和修改smali源码。并简单介绍了smali的语法和代码调试跟踪思路。
最后介绍了apk内部数据库如何获取。
准备工作
参考如下博客: https://blog.csdn.net/yanzi1225627/article/details/48215549
反编译
使用apktool
反编译命令
1
java -jar apktool.jar d xxx.apk
查看源码
将apk->jar包
- dex2jar将apk转成相应jar包 工具所在目录下执行
1
./d2j-dex2jar.sh usr/~~~~/apk(apk路径)
- 将生成的jar包丢进打开的JD-GUI工具中 https://blog.csdn.net/yanzi1225627/article/details/48215549
源码情况
- 裸奔
- 混淆
- 加固
- 有签名防护
- 有反调试
- smali文件故意制造语法错误导致部分失败
修改源码smali
### smali语法
https://blog.csdn.net/lostinai/article/details/48975661
调试smali
smali调试环境
- smalidea插件地址:https://bitbucket.org/JesusFreke/smali/downloads/
-
准备反编译后的smali工程,manifest中开启appdebug
1 2 3
<application android:debuggable="true" tools:ignore="HardcodedDebugMode" .... .... />
开启debug 后可在logcat打印查看。
-
添加romete调试选项,并开启手机调试功能。
1
提示如下: 下午2:53 * daemon not running; starting now at tcp:5037
- 打开Android monitor查看apk对应端口号(右侧)
-
修改调试remete调试端口 开启debug
1
Connected to the target VM, address: 'localhost:8601', transport: 'socket'
静态插桩法调试
通过插入log 查看变量值或者跟踪代码逻辑
1
2
3
4
5
6
7
8
9
10
11
插入两个字符串log :
````
const-string/jumbo v0, "czh"
const-string/jumbo v1, "sss"
invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
````
变量强制转换代码:
1
2
invoke-static {v1}, Ljava/lang/Integer;->toString(I)Ljava/lang/String;
注意long 占两个寄存器eg: v0,v1
动态单步调试
- 关键代码打点
-
关键跳转如:绑定事件ClickListener ,虚方法,实方法。
1 2 3 4 5 6 7 8 9 10 11
.line 204 iget-object v0, p0, Lcom/~~~~/chat/modules/speeddating/fragment/SpeedDatingPullFragment;->btn_refresh:Landroid/view/View; new-instance v1, Lcom/qingshu520/chat/modules/speeddating/fragment/SpeedDatingPullFragment$3; const/16 v2, 0x3e8 invoke-direct {v1, p0, v2}, Lcom/~~~~/chat/modules/speeddating/fragment/SpeedDatingPullFragment$3;-><init>(Lcom/~~~~~/chat/modules/speeddating/fragment/SpeedDatingPullFragment;I)V invoke-virtual {v0, v1}, Landroid/view/View;->setOnClickListener(Landroid/view/View$OnClickListener;)V
上述代码则将点击事件,定位到SpeedDatingPullFragment$3文件中
- 动态调试可以动态给成员变量赋值,左侧可查看所有断点类型,方法调用栈
二次打包
命令
1
apktool b xxx
xxx为反编译后的文件 dist文件夹下会生成未签名的apk
签名
-
生成签名文件
1 2
keytool -genkey -keystore nelakeystore -keyalg RSA -validity 10000 -alias nelakey
-
签名
1 2
jarsigner -verbose -keystore nelakeystore -signedjar target-sign.apk target.apk nelakey
其中有签名时效等等问题。
获取数据库文件
获取app内本地数据库
- adb shell 进入
- sdcard->android->data->data->包名
- cp xxx.db /sdcard
- adb devices //注意 adb shell 命令下是不可以执行adb pull的
- adb pull xxx.db 目标文件夹
数据库状态
- 加密SQLCipher
- 裸奔
参考
https://blog.csdn.net/zgzczzw/article/details/52669215
https://www.jianshu.com/p/53078d03c9bf