1. 起因
昨天晚上闲来无事,下载了一个神秘小软件。
没成想打开之后,上来就管我要无障碍权限,不是你一个黄色app管我要无障碍权限干嘛:

就给我一种 belike 他一个公安厅长要狙击枪干嘛:

不过 叽里咕噜的跟我的鸿蒙Next系统说去吧:

卓易通平等地肘击所有软件
不过这倒引起了我的兴趣,这得打开电脑仔细研究研究它到底要干嘛了:
2. 拆壳
先解压看一下:

发现了以下内容:
AndroidManifest.xml 436944684(解压后) 2037250(压缩后) // 437MB填充的虚假manifest文件
classes.dex 9872 // 只有 9.8KB,壳
assets/ftazbxftcg 7445924 // 随机名,加密的真 dex
assets/yfvllwqkjellgk 617158 // 又一个随机名
xdyepzjvh/... // 根目录一堆随机字母目录
直接上jadx反编译看看:

发现了两个问题:
- 这个manifest清单文件是一个zip炸弹,解压后膨胀到了437MB,故意塞的垃圾填充,专炸按声明大小读内存的分析工具;
- 反编译完成了,但产物少得可怜,整个 APK 就这 3 个类,说明真代码不在 dex 里
典型加固壳布局。但问题是壳 loader 必须在主 dex 里明文写着怎么解密、密钥是什么 ,要不然手机自己都解不开。所以先去读壳:
3.读壳
直接拆壳:

就三个类,都在 io\handy\tracker\client\b**p\y**o\ 下。打开主类,直接搜索decrypt|QuickAudioConfig:

壳自称叫DexProtect,核心加密逻辑是循环 XOR,密钥 32 字节 hex 硬编码。解出来是个 zip,装着真 dex,运行时 PathClassLoader 动态加载。他的真实入口组件是io.handy.tracker.client.QuickAudioConfig。
那么这下就可以开拆了,用大肥鱼写一个XOR 解密脚本,传入密钥,可以解出来真正的dex包:

拿到了17.9MB的真代码,直接对其反编译:

拿到了11787 个类。包结构大致分为三种:
io\handy\tracker\client\(业务类,类名装得像正常代码,比如DownloadHandler,全是障眼法命名);
aabab\b\c\y\...\baba\(超长混淆包,核心逻辑);
myobfuscated\(三方库混淆)。
4.定位信息
显然核心逻辑全部是混淆过的。不管,直接定位无障碍所在的位置:

定位打开一看所有字符串都加密了,不管他,先放在这。
xml文件有 437MB,常规解析库全挂。这个壳在标准 AXML 里做了四个手脚,分别是:
- 头部 size 字段写 437MB。解决方法:只按 chunk 实际大小遍历,不管文件头。
- 混入了混入伪造 chunk。解决方法:不认识的类不管直接跳过。
- namespace chunk 类型被改成 0x017E/0x017F/0x0105。解决方法:只处理字符串池和 start-element。
- 元素头被塞 8 字节(属性区从+36开始,标准是+20);而且每个元素末尾混有指向陷阱字符串的垃圾属性。解决方法:属性区固定 +36,按 dataType 白名单遇假即断。
继续大肥鱼写解析器,直接开拆:


这下明白了:他申请了43 条权限,全是 RAT 全家桶:READ_SMS(读短信);READ_CONTACTS(读联系人)、CAMERA(相机)、RECORD_AUDIO(录音)、
MANAGE_EXTERNAL_STORAGE(管理外部存储)、REQUEST_DELETE_PACKAGES(申请删除软件权限)、FOREGROUND_SERVICE_MEDIA_PROJECTION(录屏)、
RECEIVE_BOOT_COMPLETED(开机自启)、REQUEST_IGNORE_BATTERY_OPTIMIZATIONS(电池优化白名单)……
外加6 个 activity-alias。
那么这下都拿到了,开始还原:
5.还原加密字符串
混淆器就两个类(v90/w90),又是重复密钥 XOR。直接写批量替换脚本即可。大肥鱼,启动!

1523个唯一字符串中,最能定性的是:

哦吼?这下明白了。

他基本上不管国内国外的软件,通吃:
模板槽位 |
目标包名 |
应用 |
|---|
手机密码 |
— |
设备锁屏 PIN/图案(无障碍从系统锁屏偷 + 假锁屏收) |
钓鱼密码 |
— |
通用 [TITLE] 假覆盖页收到的任意密码 |
Alipay |
com.eg.android.AlipayGphone |
支付宝 |
Wechat |
com.tencent.mm |
微信 |
云 |
com.unionpay |
云闪付 |
建 |
com.chinamworld.main |
建设银行 |
邮 |
com.yitong.mbank.psbc |
邮储银行 |
农 |
com.android.bankabc |
农业银行 |
中 |
com.chinamworld.bocmbci |
中国银行 |
工 |
com.icbc |
工商银行 |
招 |
cmb.pb |
招商银行 |
gp |
com.google.android.apps.nbu.paisa.user |
Google Pay(印度版) |
pe |
com.phonepe.app |
PhonePe(印度) |
an |
com.emeint.android.myservices |
Ana Vodafone(埃及沃达丰手机营业厅) |
mb |
pt.sibs.android.mbway |
MB Way(葡萄牙 SIBS 支付) |
bc |
pt.bctt.appbctt |
Banco CTT(葡萄牙邮政银行) |
Trust / Imtoken / Tokenpocket |
trustapp / imToken / TokenPocket |
三大加密钱包 |
甚至不光如此,还针对加密钱包单独走了一条线。
模板里 Trust/imToken/TokenPocket 之外,还有一批不进这个汇总表的盯梢对象(币安、Gate.io 的资金密码/谷歌验证码输入框 ID、co.mona.android 的提币地址框),配合配置里那个 usdtadress 字段,针对换提币地址还有剪贴板劫持攻击。
以及锁屏图案上报模板 "图案:%s"、com.android.packageinstaller:id/confirm_button
(自动点安装确认)、华为/小米/OPPO/vivo/荣耀各系统管家的控件 ID(自动导航电池白名单)、
vivo 锁屏 PIN 键盘 VivoPinkey,可以说针对几个国产厂商都有针对性的设计。
针对另外一个类,使用另一个密钥解密,就是webview的资产:

.bt文件的密钥写在壳的get_asetskey类里面,内容分为:
- 假锁屏类:密码直接回传服务器:

假系统更新类:按受害者手机品牌动态选用

(ps:这软件居然针对鸿蒙专门做了一个页面,但是问题是纯血鸿蒙打不开这玩意啊)
所以这下入口流程就是:
检测无障碍服务是否在运行,如果不在,弹出话术对话框。只有授权才继续;
权限到手后 WebView 加载伪装网页,且开着
setAllowUniversalAccessFromFileURLs(true)(允许网页读取所有本地文件);
- addJavascriptInterface(…, “Android”)`(允许网页执行任意java代码)
manifest 里的activity-alias,可以直接远程换图标/改名/从桌面消失;
启动完后台服务直接结束主软件,纯幽灵;
WebSocket 客户端链接后台服务器,各功能模块用 JSON 收发指令,流量用AES 参数加密。

大概就这么个流程吧。
6. 糖衣炮弹,糖呢?
既然他是伪装色情app,那在用户真的授予无障碍之后,总要给用户点甜头吧。那看看甜头是啥:
WebView 首页 URL 存在一个字段(Base64+AES,算65535轮)。解密后是一个网站,而且还有一个参数。当配置为0的时候正常显示网页,配置为1的时候连网页都不显示,加载完后台服务直接退出主程序,直接隐身掉。
7.如何预防,以及真的授权后如何解救:
这就是老生常谈的话,一般的正常的,靠广告盈利的小软件,都不需要任何额外的权限(最多可能要个存储文件下载更新),
要通讯录、相册甚至无障碍的软件立刻卸载,咱不缺这一个,只要没主动授权他啥都拿不到
如果在钓鱼页输过任何密码,立刻改掉,真的因为这个被骗不值当
当然,如果真的点了无障碍权限,立刻长按十秒钟电源按钮强制重启,一般国产系统会在重启后自动关闭所有应用的无障碍权限,如果还没关就立刻断网拔卡,晚了就是给骗子创造机会。
8.致谢
感谢GLM 5.3flash提供的逆向技术支持,真的感慨ai逆向比人快多了,人还在老老实实vscode全局搜索,ai直接用powershell(先跟ps搏斗几次)搜索,解码,完事了。
感谢大肥鱼DeepSeek V4 flash提供的脚本支持。
最后再重复一遍,本文仅供技术探讨,所有操作均在沙箱中完成,莫要真的涉险去尝试!