最近对逆向技术比较感兴趣,研究了一下,收获不少,这里记录一下。
注:本文仅供学习参考,不可做任何不合法或不道德的用途
首先介绍一下常用的逆向工具,要逆向一个APP,通常目的是 文案翻译、去广告、api破解等,而要实现这些目的,一般需要以下操作:
- 反编译apk
- 阅读代码
- 修改源码、资源、Manifest等
- 重新打包签名
网上介绍比较多的是用 apktools进行反编译,用dex2jar来还原java源码
使用apktools反编译和重新打包是非常方便的,但要用dex2jar来阅读源码就比较繁琐且难读了
所以我通常先用jadx来获取和阅读源码,操作非常简单,将apk文件拖入jadx 的GUI界面就行了,在了解APP逻辑后,要开始改动apk时,再通过apktools反编译,然后改动smali代码,再重新打包
这里以Google Play某个头部APP为例,修改包名 和 翻译文案,并在启动页中插入一个Toast,演示一下apktools和jadx的用法
使用jadx阅读源码
首先将apk拖如jadx工具,得到java源码:
这时已经可以开始阅读源码了,但毕竟不是专业IDE,代码跟踪肯定不如AndroidStudio,所以如果有大量的代码需要阅读,jadx可以导出Gradle格式的目录,然后将导出的代码添加到任意一个支持java的IDE即可,不需要编译成功,只要建立代码索引,能跟踪代码就足够了,这里以Android Studio为例:
导出Gradle项目
在AndroidStudio中创建一个工程,将导出的Gradle项目中 src/main/java 目录下的java源码,copy到新建的工程(为了提高效率,一些已知的三方库可以直接删掉,我们只需要阅读业务部分源码即可),这里直接将 libv2ray、okhttp3、okio 等这些明显是三方库的包删掉了,如下图:
插入一句简单的代码
首先打开Manifest文件,搜索 “android.intent.action.MAIN” 找到启动页:
现在知道了启动页的Activity,就可以阅读代码,找到自己想要插入或修改代码的位置,这里演示一下直接在MainActivity的onCreate()方法的第一行,插入一句 Toast
前面说了,jadx仅仅是用作获取和阅读java源码,实际需要改动代码和重新打包时,还是要使用到apktools,现在使用apktools来再次反编译apk,得到smali代码,并根据阅读源码时找到的路径,来定位到需要修改的MainActivity.smali文件:
1、apktools 反编译apk,得到目录 test_code
java -jar apktool.jar d test.apk -o test_code
–
2、找到 test_code/smali/com/xxx/activity/MainActivity.smali
.
3、在MainActivity.smali 中插入Toast,这里需要会一些smali语言,但如果你像我一样,作为一个逆向菜鸟,完全不懂smali语言,也没关系,因为要改动的代码通常不会太多,而且作为一个程序猿,即使不会写,看懂大概意思也不难
所以我们可以先自己写demo将需要插入的代码编译成smali,看我们要插入的代码编译成smali后长什么样子,再根据具体场景把生成的smali代码copy过去,做的多了自然而然就熟悉smali了
这里就做个demo试一下,先创建一个demo工程,在Activity中写一句 Toast,然后反编译demo apk,看看生成的smali代码长什么样:
可以看到框起来的5行代码,不难分析出大概逻辑就是:
第1行:声明一个常量 v1 = ox1 (也就是 Int类型的 Toast.LENGTH_LONG)
第2行:声明一个常量 v2 = "这是插入的Toast"
第3行:invoke一个静态方法 makeText(),传入参数 v0 v1 v2
第4行:v2重新赋值 = makeText() 返回的object
第5行:invoke v2的方法,show()
–
知道smali代码怎么写之后,再回到 test_code 中的 MainActivity.smali 文件中,插入代码:
–
现在改好了代码可以重新打包了,使用apktools,重新编译并签名test_code:
java -jar apktool.jar b test_code -o test_new.apk
现在test_new.apk是未签名的,还需要签名一下,签名方法我就不赘述了,看看效果
可以看到,Toast已经成功展示出来了,代码插入都搞定了,再顺手改一下包名和翻译文案更是so easy了,还是操作刚刚的 test_code 目录
1、修改包名,直接修改Manifest即可
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="包名">
2、修改翻译,直接修改res 下对应语言的values 即可
改完还是同上,重新打包签名