zhang010416/systemhelper-blocker
zhang010416/systemhelper-blocker has 58 GitHub stars and 6 forks. Star changes are not measured yet. Last checked 2026-11-13 02:06 UTC. Last push 2026-11-06.
让预装的联通 DM 上报组件彻底哑掉:不采集 / 不定位 / 不落库 / 不出网(LSPosed + KernelSU 双层拦截)
측정된 스타 증가
- in 24h
- 기록 수집 중
- in 7 days
- 기록 수집 중
- in 15 days
- 기록 수집 중
- in 1 month
- 기록 수집 중
서로 겹치는 기간의 순증가량이며 일별 합계가 아닙니다. 측정값이 없으면 비워 둡니다. 스타는 관심도를 나타내며 품질을 보장하지 않습니다.
README.md
OriginalSystemHelper Blocker
让预装的联通 DM 上报组件彻底哑掉:不采集、不定位、不落库、不出网。
背景
部分运营商定制机预装了一个叫 com.mobiletools.systemhelper 的组件(priv-app 权限),
它会把设备的 IMEI / ICCID / IMSI / 基站信息 / 经纬度 / 已装应用使用时长 / 流量明细
加密后定时上报到运营商的 DM(Device Management)服务器。
问题在于:它在 OPPO 定制机上几乎不受用户控制。 设置里那个"运营商服务改进计划"开关只有 vivo 机型的分支才会读取,OPPO 分支只判断系统开机向导是否完成—— 也就是说,开机向导过完,它就开始上报了。
本项目用三层手段把这条链路掐断,全部离线、无网络权限、不采集任何数据。
它拦的是什么
| 项 | 值 |
|---|---|
| 包名 | com.mobiletools.systemhelper |
| 版本(逆向目标) | 3.0.1-20250822(versionCode 31) |
| 安装位置 | /product/priv-app/SystemHelper-oppo-20250822/ |
| 上报地址 | http://dm.wo.com.cn:18080/register(存 SharedPreferences,可被远程改) |
| 传输加密 | MD5(json) 作 AES-128 key;AES/ECB/PKCS5 加密 body;RSA-1024 加密 AES key 作为 URL 的 sign |
上报分六类(RegType):F 首次开机、B 开机、S 定时(24h+随机偏移)、T SIM 变更、
A 应用使用情况、R 信号+位置补报。
三层架构
┌─ DNS ─────── dm.wo.com.cn 解析到 127.0.0.1(设备既有的 DNS 过滤,可选)
├─ 内核层 ──── KernelSU 模块 sh_blocker:按 uid 阻断全部 IPv4/IPv6 出站,连 native 层一起拦
└─ 应用层 ──── LSPosed 模块:L1~L4 拦截 HTTP 出口 / 采集 / 定位 / 落库
三层互相独立:只装内核层就已经断网,应用层则把采集动作本身也停掉(不产生数据、不写库)。 两层通过共享目录联动,内核模块的「操作」按钮能一次性体检两层的状态。
| 层 | 组件 | 拦什么 | 能单独用吗 |
|---|---|---|---|
| 内核 | KernelSU 模块 sh_blocker |
uid 10100 的全部出站(含 JNI 发出的) | ✅ 可以 |
| 应用 | LSPosed 模块 com.example.syshelperblocker |
L1 出口 / L2 总闸与门控 / L3 定位 / L4 落库 | ✅ 可以(落库和采集都停) |
目录结构
.
├── SystemHelperXposed/ # LSPosed 模块(libxposed API 102,Gradle 工程)
│ ├── app/src/main/
│ │ ├── java/.../MainHook.java # 全部 hook 逻辑
│ │ ├── resources/META-INF/xposed/
│ │ │ ├── java_init.list # 入口类
│ │ │ ├── module.prop # minApiVersion / targetApiVersion / staticScope
│ │ │ └── scope.list # 作用域:com.mobiletools.systemhelper
│ │ └── AndroidManifest.xml # 只有 label / description
│ └── HANDOVER.md # 逆向记录:类映射、调用链、踩坑
├── kernel-module/ # KernelSU 模块源码
│ ├── module.prop
│ ├── service.sh # 探测 uid → iptables/ip6tables REJECT → 60s 自愈
│ ├── action.sh # 「操作」按钮:一键体检
│ ├── post-fs-data.sh / uninstall.sh / skip_mount
└── build_module_zip.py # 打包成可刷入的 zip
体检
装好之后随时跑一次联合体检(等于 KernelSU 管理器里该模块的「操作」按钮):
adb shell su -c "sh /data/adb/modules/sh_blocker/action.sh"
[1] 目标进程
包名 : com.mobiletools.systemhelper
uid : 10100
pid : 17148
[2] 内核层规则(iptables / ip6tables)
IPv4 : OK
IPv6 : OK
[3] 内核拦截计数(数字涨 = 有请求撞墙)
IPv4 : 0 包 / 0 字节
IPv6 : 0 包 / 0 字节
[4] 当前 TCP 连接(应为空)
(空) 没有任何外连
[5] 模块自愈记录(最近 4 条)
[2026-11-05 18:26:15] target com.mobiletools.systemhelper uid=10100
[2026-11-05 18:26:15] iptables: OUTPUT reject uid=10100
[6] Xposed 模块(LSPosed)
最后心跳 : 2026-11-05 18:44:05 (9s 前)
hook 摘要: L1=1 L2e=1 L2g=4 L3=1 L4=2
拦截统计 : 出网 0 次 / 0 字节 | 总闸 1 次 | 写库拦截 0 次
心跳判定 : ✅ 活跃(10 分钟内)
[结论]
✅ 正常:规则在位,当前零外连
怎么读:
| 现象 | 含义 |
|---|---|
| 规则在、命中数 0、连接表空 | ✅ 最理想:应用层就拦住了,一个包都没发出去 |
| 命中数在涨 | ⚠️ 有路径绕过了应用层,被内核兜住(正常兜底,可查 events.log) |
| 规则不见了 | ❌ 被 netd 清了,60 秒守护会自己补回来 |
status.json 心跳超 10 分钟 |
❌ Xposed 层没工作(进程没跑 / 模块没启用) |
配置
应用层开关放在共享目录,改完重启目标进程即可,不用重刷模块:
adb shell su -c "cat /storage/emulated/0/Android/media/com.mobiletools.systemhelper/SHBlocker/config.conf"
BLOCK_EGRESS=1 # L1 出口
BLOCK_COLLECT=1 # L2 总闸 + 门控
BLOCK_LOCATION=1 # L3 定位
BLOCK_DB=1 # L4 写库
WIPE_DB=1 # 启动时清空历史积压库
同目录下还有两个运行时文件:status.json(模块写的心跳+统计,内核侧读)、events.log(事件流)。
工作原理
调用链
触发(广播 / Alarm / JobService / Binder / Activity)
→ e1.b.a(Context, regType) 【L2 总闸,唯一调度入口】
→ f1.o.d(Context, regType) 采集分发
├─ f1.a DeviceInfoReaderBase(13 家厂商适配,反射私有 API 取 5G/VoLTE)
├─ e1.d 信号采集(TelephonyCallback PreciseDataConnectionState)
└─ e1.g / e1.c / e1.f / e1.e 上报线程
→ g1.f.b(String url, byte[] body, byte[] key) 【L1,全 App 唯一 HTTP 出口】
信号链:GetSignalInfoReceiver.onReceive → b()/c() 门控 → d(回调) 启百度定位 → 写 SigInfo → 落库
落库:g1.m.c(String) → signalhelper.db / g1.e.b(String) → systemhelper.db(补报)
hook 点
| 层 | 目标(3.0.1-20250822 的混淆名) | 动作 |
|---|---|---|
| L1 | g1.f.b(String, byte[], byte[]) : boolean |
直接返回 true(伪装上报成功) |
| L2 总闸 | e1.b.a(Context, String) : e1.b |
返回空对象,不采集 |
| L2 门控 | f1.a.c(Context) / g1.l.a(Context) / GetSignalInfoReceiver.b,c(Context) |
返回 false |
| L3 | GetSignalInfoReceiver.d(回调) : void |
不执行,定位不启动 |
| L4 | g1.m.c(String) / g1.e.b(String) : void |
不执行 + 启动时清库 |
L1 必须返回 true 而不是 false —— 返回 false 会让上层走"落库补报"分支并反复重试,
返回 true 才算真正伪装成功。
为什么还需要内核层
百度定位 SDK 的网络收发在 JNI 里:全 APK 里 java.net.HttpURLConnection 只有 1 个引用(就是 g1.f),
java.net.Socket 更是零引用,也没有 okhttp / apache-http。
Java 层没有可 hook 的点,只能靠按 uid 的内核阻断兜底——这也是为什么要做双份实现而不是一个 Xposed 模块了事。
技术栈
- 应用层用官方现代 API
libxposed/api(API 102), 不再依赖已停止维护的de.robv.android.xposed:api:82; - hook 采用拦截器链模型(
hook(m).intercept(chain -> ...)),不调chain.proceed()即短路。
构建
Xposed 模块(需要 JDK 17 + Android SDK 34):
cd SystemHelperXposed
echo "sdk.dir=/path/to/android-sdk" > local.properties # 指向本机 Android SDK
./gradlew assembleDebug
# 产物:app/build/outputs/apk/debug/app-debug.apk
工程自带 Gradle 8.7 wrapper,
distributionUrl指向腾讯云镜像(国内直接可用)。 海外或镜像失效时,把gradle/wrapper/gradle-wrapper.properties里那行改回https\://services.gradle.org/distributions/gradle-8.7-bin.zip即可。
KernelSU 模块:
python build_module_zip.py # 读取 module.prop 的 version,输出 sh_blocker_<version>.zip
兼容性
| 项 | 实测 | 说明 |
|---|---|---|
| 设备 | OPPO PLP110 / Android 16 | |
| 目标 App | 3.0.1-20250822 | 类名取自该版本 |
| Xposed 框架 | LSPosed 2.2.1(API 102) | 需要支持 libxposed 的版本 |
| root 方案 | KernelSU | Magisk 下把 ksud module install 换掉即可 |
| 模块 minSdk | 29 | onPackageReady 回调要求 Android 10+ |
已知限制:
g1.f / e1.b / f1.a / g1.l / g1.m / g1.e都是3.0.1-20250822的混淆名,OTA 升级后大概率失效, 需要重新定位。想抗变更可以接 DexKit 按字符串常量搜索。- 内核层是按 uid 全量阻断,不做协议识别——目标应用一旦换 uid(重装/换版本)需要重启让
service.sh重新探测。 - 只覆盖这一个包,不针对任何其他应用。
验证方法
不想等到定时上报(默认 24 小时)才验证,可以直接触发目标 App 自带的测试入口:
adb shell su -c "am start -n com.mobiletools.systemhelper/.Activity.TestActivity"
它内部会调用 e1.b.a(),日志里看到下面这行就说明链路当场断了:
[SHBlocker] L2 entry short-circuit regType= (total 1)
模块日志在 LSPosed 日志里:
adb shell su -c "grep -a SHBlocker /data/adb/lspd/log/modules_*.log | tail -30"
免责声明
- 本项目用于自有设备上的隐私控制:阻止预装组件在用户不知情的情况下采集并外发设备信息。
- 只对
com.mobiletools.systemhelper生效,不修改任何系统文件,不联网,不上传任何数据。 - 使用需要 root,后果自负;不同 ROM / 版本可能有差异,请先备份。
- 请勿用于规避运营商合约、伪造设备信息或任何违法用途。
许可证
관련 프로젝트 살펴보기
trimstray/the-book-of-secret-knowledge
영감을 주는 목록, 매뉴얼, 치트시트, 블로그, 팁, 원라이너, CLI/웹 도구 등을 모은 컬렉션.
258,122 스타Hack-with-Github/Awesome-Hacking
해커, 펜테스터, 보안 연구자를 위한 다양한 Awesome 목록 모음.
125,360 스타swisskyrepo/PayloadsAllTheThings
웹 애플리케이션 보안과 모의 침투 테스트/CTF에 유용한 페이로드 및 우회 방법 목록.
82,623 스타caddyserver/caddy
빠르고 확장 가능한 멀티플랫폼 HTTP/1-2-3 웹 서버이며, 자동 HTTPS를 지원합니다
79,020 스타