带壳App去除强制升级

2020-11-25 12:58:39 浏览数 (1)

这是一款带壳的APP,打开之后要求强制升级最新版,否则无法使用,针对此APP可以进行脱壳后定位关键代码,然后重打包进行消除强制升级弹窗。

DEXDump三种使用模式脱壳

1、使用objection加载frida_dexdump

代码语言:javascript复制
objection -g com.xxx explore
plugin load /root/.objection/plugins/dexdump/frida_dexdump
plugin dexdump dump

2、直接运行

代码语言:javascript复制
objection -g com.xxx explore
python3 main.py

会自动判断前台运行的App

3、利用pip安装后运行frida-dexdump

代码语言:javascript复制
objection -g com.xxx explore
pip3 install frida-dexdump
frida-dexdump

脱壳成功后,发现生成了4个dex文件,然后搜索带有MainActivity的dex文件

代码语言:javascript复制
grep -ril "MainActivity"

Objection快速自动化定位

正常方式首先以开发者的角度来思考是如何实现窗口弹出功能

https://www.jianshu.com/p/18e1f518c625

一 activity以窗口形式呈现

二 Android:将activity设置为弹出式的并设置为透明的

三 Dialog

1、如果是弹出的activity,可以hook所有的activities进行启动查看

代码语言:javascript复制
代码语言:javascript复制
 android hooking list activities

启动可疑的Activity,尝试能不能绕过,然后发现界面到了app信息页面,但是返回后还是要求升级的界面,说明此路不通。

代码语言:javascript复制
代码语言:javascript复制
android intent launch_activity xxx.ui.activity.About Activity

查看一个函数能不能hook,可以将它所有的类打印出来,然后过滤,如果有则可以hook

代码语言:javascript复制
代码语言:javascript复制
android hooking list classes
cat .objection/objection.log |grep -i window   

发现有android.view.Window,然后尝试hook

代码语言:javascript复制
代码语言:javascript复制
objection -g com.xxx explore --startup-command "android hooking watch class android.view.Window"

注:

也可以不需要--startup-command,进去app之后再hook也来得及

当点击“立即升级”发现会立即跳出下图内容,说明与升级框相关android.view.Window.getWindowManager()

2、尝试下dialog

代码语言:javascript复制
代码语言:javascript复制
 cat .objection/objection.log |grep -i dialog

先hook看一下android.app.AlertDialog

代码语言:javascript复制
android hooking watch class android.app.AlertDialog

发现点升级没有任何反应,故判断此API与升级框没关系

然后再尝试hook下android.app.Dialog看有没有反应

代码语言:javascript复制
代码语言:javascript复制
objection -g com.xxx explore --startup-command "android hooking watch class android.app.Dialog"

点击新版本框空白地方会出现

点击“立即升级”出现

看到存在android.app.Dialog.setCancelable (用返回键无法取消)

然后hook该方法

代码语言:javascript复制
android hooking watch class_method android.app.Dialog.setCancelab le --dump-args --dump-backtrace --dump-return

找到对应位置,发现与界面上的版本号、文件升级相关联,从而定位到了代码的关键位置。

这里是明文,所以很明显就可以判断定位的对错。如果关键字符串做了加密混淆,搜索大法也就无效了,可以使用wallbreaker内存可视化漫游,所见即所得。

Wallbreaker内存可视漫游

wallbreaker四种模式:

代码语言:javascript复制
 classdump 查看一个类的结构
classsearch 根据类名来找类
objectsearch 查看一个类的实例内容
objectdump  查看对象的属性

使用objection加载Wallbreaker搜索值得怀疑的地方

代码语言:javascript复制
代码语言:javascript复制
plugin load /root/.objection/plugins/Wallbreaker
plugin wallbreaker objectsearch xxx.ui.fragment.dialog.UpdateDialogFragment

找到之后,打印该对象的属性

代码语言:javascript复制
 plugin wallbreaker objectdump --fullname 0x276a

看到xxx.bean.VersionBean$Version _a; => [0x2266]:

然后将其打印出来

代码语言:javascript复制
代码语言:javascript复制
plugin wallbreaker objectdump --fullname 0x2266

可以看到打印出的内容,与界面所展示的一致,验证了所见即所得原理。

所见即所得的代码定位思路

定位完之后,我们继hookxxx.ui.fragment.dialog.UpdateDialogFragment

代码语言:javascript复制
代码语言:javascript复制
android hooking watch class xxx.ui.fragment.dialog.UpdateDialogFragment

打印调用栈

xxx.ui.fragment.dialog.UpdateDialogFragment.b

代码语言:javascript复制
代码语言:javascript复制
android hooking watch class_method xxx.ui.fragment.d
ialog.UpdateDialogFragment.b --dump-args --dump-backtrace --dump-return

根据打印的结果看到

xxx.ui.fragment.dialog.UpdateDialogFragment.b是从xxx.ui.activity.MainActivity.a该类过来,然后定位该类,发现也是做了个条件判断。

修改源码重打包去强制升级

接着我们进行修改代码去掉升级框并重打包,首先因为是带壳的APP,无法直接使用apktool进行反编译,不然壳也会被反编译为smali。所以我们使用apktool保留classes.dex文件进行解包,然后删除apk原有的classes.dex文件,并将脱壳后的classes.dex放入

代码语言:javascript复制
代码语言:javascript复制
apktool -s d xxx.apk
rm classes.dex

按照文件大小重命名后放入该文件夹中

搜索extends Application

查找AndroidManifest.xml内容,将android:name的内容替换为xxx.base.App将入口点改为脱壳后的入口点

然后回编译、首次使用需先生成keytool、签名

代码语言:javascript复制
代码语言:javascript复制
 apktool b xxx
 keytool  -genkey -alias abc.keystore -keyalg RSA -validity 20000 -keystore abc.keystore   # 生成keytool
 jarsigner -verbose -keystore abc.keystore -signedjar xxxsigned.apk xxx.apk abc.keystore

测试可以成功运行后,我们接着反编译,搜索之前定位的类名含MainActivity的smali文件,编辑查找UpdateDialogFragment找到之后修改判断语句

代码语言:javascript复制
代码语言:javascript复制
 apktool d xxxsigned.apk
 tree -NCfhl |grep -i MainActivity
 nano smali/cn/net/tokyo/ccg/ui/activity/MainActivity.smali

改完之后回编译、签名、运行

代码语言:javascript复制
代码语言:javascript复制
 apktool b xxxsigned/
 jarsigner -verbose -keystore abc.keystore -signedjar xxx2signed.apk xxx2.apk abc.keystore

发现已经没有了强制升级的弹窗。

0 人点赞