Files
notiMessage/docs/MARIBANK_IMPLEMENTATION.md
Mars d488a0759f docs: MariBank 实现说明与登录/注册对比
补充 MARIBANK_IMPLEMENTATION 专文及工作说明中的登录路径分析、API 对照与测试建议。
2026-07-03 17:33:39 +08:00

23 KiB
Raw Blame History

MariBank 实现说明与问题记录

日期2026-07-03
AppMariBank / SeaBank PH · ph.seabank.seabank · v3.22.0 (32200)
设备Pixel 6 · Magisk + Zygisk + LSPosed
源码xposed-module/.../hook/MariBank*.java

本文档专门说明当日对 MariBank 注册流程风控绕过 的 Xposed 实现细节,以及开发/测试中遇到的全部主要问题。通用工作汇总见 WORKLOG_2026-07-03.md


1. 目标与结果概览

1.1 目标

在已 Root 设备上完成:

打开 App → Sign up → 输入菲律宾手机号 → Next
→ POST https://api.seabank.ph/uapi/v2/register
→ 进入 OTP / 下一步

1.2 当日最终结果

阶段 结果
本地 Root 检测 / 自杀 / 弹窗 大部分绕过,可稳定进入注册页
DFP 设备指纹上报 成功code=0
riskToken 尾部字段净化 Hook 生效|09|1|00|0
注册接口 失败,服务端返回 4067012 / 4067004
注册请求明文 未抓到body native 加密)

结论:本地层 bypass 已推进到能正常发起注册请求,但 服务端风控仍拒绝;当前实现不足以完成注册。


2. App 风控架构(逆向结论)

MariBank 基于 Shopee BKE 技术栈,风控分 本地 SDK 层服务端校验层

┌─────────────────────────────────────────────────────────┐
│                     MariBank App                         │
├─────────────────────────────────────────────────────────┤
│ SafeMode SDK          │ Root/篡改检测 → Toast + 自杀      │
│ SHPSSDK (bank)        │ riskToken / DFP / requestDefense │
│ libshpssdk_bank.so    │ native/proc/maps、hook 库扫描   │
│ libsdkutils.so        │ register body native 加密         │
├─────────────────────────────────────────────────────────┤
│ OkHttp / Retrofit     │ 出站 HTTP                         │
└─────────────────────────────────────────────────────────┘
          │                              │
          ▼                              ▼
 POST /dfp/v1/data/report        POST /uapi/v2/register
 (设备指纹 + riskToken)            (加密 body + 手机号)
          │                              │
          └────────── api.seabank.ph ────┘
                         │
                    4067012 服务端拒绝

2.1 关键类与 SOv3.22.0

组件 真实符号 说明
Application com.shopee.bke.digitalbank.BkeApplication attachBaseContext 后 ClassLoader 才完整
SafeMode com.shopee.bke.lib.safemode.b 方法名混淆,多返回 boolean/int
SHPSSDK com.shopee.shpssdkbank.SHPSSDK getRiskToken / getRiskSync / requestDefense
riskToken 链 vvuuuuvvv.wwvuwuwvu(Context) classes11.dex真实 token 生成入口
SoUtils com.shopee.bke.lib.jni.utils.f 加载 libsdkutils.solog tag SoUtils
加密包装 com.shopee.bke.lib.jni.utils.d Java 层加密入口
Native 加密 com.shopee.bke.lib.jni.utils.uvwuvwuv JNIlibsdkutils.so / libbkutils.so
SHPS native wvvvuwwu.vvuwuuvuuwwvwvwuvv libshpssdk_bank.so
字符串解密 uvuwwuvwv.uvwwuuvvw.uvuwwwuwu 解密 x-sap-fixme

2.2 注册相关 API

接口 作用 当日观测
POST /dfp/v1/data/report 设备指纹 / DFP 上报 成功 code=0
POST /uapi/v2/register 手机号注册 失败 4067012

2.3 riskToken 格式(尾部字段)

token 为 pipe 分隔字符串,最后两段表示风险标记,例如:

...Base64段|Base64段|xx|09|1
                              ↑  ↑
                           风险码  Hook/Root 等标志

当日 Hook 将尾部 09|1 改为 00|0(认为表示 Root + Hook 命中。logcat 可见净化日志,但 register 仍被拒,说明服务端还校验 token 其他段或独立 DFP 载荷。

2.4 登录 vs 注册(当日未测登录,以下为逆向 + 推断)

当日实测路径为 Sign up → 注册Log in 登录尚未在设备上验证。以下基于 APK 字符串扫描与 Hook 架构整理。

2.4.1 现有 Hook 是否覆盖登录

是。 当前 Xposed 按 整包 ph.seabank.seabank 加载,不区分注册/登录:

能力 登录是否同样生效
SafeMode / Root 自杀、弹窗拦截
SHPSSDK / riskToken、deviceToken 出站净化 所有 OkHttp 请求
DFP POST /dfp/v1/data/report App 启动即上报
/proc 过滤、boot 属性伪装

无需为登录单独写 Hook;能稳定进入 App登录页同样受益。

2.4.2 API 路径不同

登录 不走 /uapi/v2/register,而是独立 auth 链路v3.22.0 base APK DEX 扫描):

场景 典型路径
注册(已实测) POST /uapi/v2/register
登录预检 /v2/auth/precheck/v1/pin/auth/precheck
OTP 登录 /v2/app/login/otp/get/v2/app/login/otp/verify
PIN 登录 /v1/pin/auth
受限环境 /v2/restricted/auth/v2/restricted/auth/precheck
通用 OTP /v1/otp/send/v1/otp/verify
设备指纹(共用) POST /dfp/v1/data/report

ViewModel 层面:RegisterViewModelLoginViewModel / PinCodeViewModel / OneTimePasswordViewModel 分离;PhoneNumViewModel 可能与注册共用(输入手机号 UI 类似)。

错误展示由 GlobalAuthErrorImpl通用鉴权错误处理 负责(matchScene 多场景4067 封锁弹窗 不限于注册接口

2.4.3 登录可能的结果(推断)

情况 登录表现(推断)
设备指纹已被服务端拉黑 可能在 /v2/auth/precheck/v2/app/login/otp/get 即返回 4067012,与注册类似
仅「新开户」风控更严 若设备未全局封禁,已有账户 + 正确 PIN/OTP 的登录 有机会 通过 precheck
本地 bypass 足够、服务端仍拒 DFP code=0 但 auth 接口 4067 — 与注册相同,改 riskToken 尾部 不够

2.4.4 注册 vs 登录对比

维度 注册 (Sign up) 登录 (Log in)
前提 新菲律宾手机号 已有 MariBank 账户 + PIN 或 OTP
关键 API /uapi/v2/register /v2/auth/precheck/login/otp/*/pin/auth
风控强度 新户反欺诈通常 更严 老户相对松,设备黑名单仍生效
当日实测 4067012 未测
Hook 专用日志 代码中对 /register 有较详细 body 日志 其它 URL 仅有通用 HTTP / 4067 日志

2.4.5 若改测登录

  1. Log in(非 Sign up输入 已开户 手机号
  2. logcatpowershell -File scripts\logcat-maribank.ps1 -Follow
  3. 重点观察:/v2/auth/precheck/v2/app/login/otp/get/v1/pin/auth/dfp/v1/data/report 的响应码
  4. 若仍为 4067012 → 倾向 设备/环境级封锁,换登录路径无法绕过
  5. 若 precheck 通过、仅 OTP/PIN 失败 → 多为 账户凭证 问题,非 Root bypass 范畴

多次注册失败可能已加重设备风控,登录测试前建议 冷却 2448h 或使用未试过的环境。


3. Xposed 实现架构

3.1 入口与加载顺序

MainHook.javaph.seabank.seabank 加载两个 Hook 类:

MariBankShpsNativeHook.install(lpparam);      // 第一阶段early
MariBankRootBypassHook.install(lpparam);      // 第一阶段 + 调度 deferred

两阶段加载是当日最关键的工程决策之一:

阶段 时机 安装内容
Early loadPackage 立即 /proc 读过滤、系统属性伪装、Process.killProcess 拦截
Deferred BkeApplication.attachBaseContext 之后 SafeMode、SHPSSDK、OkHttp 出站净化、riskToken Hook

原因:过早 Hook SHPSSDK / SoUtils.loadSoLibrary 会导致 **libsdkutils.so 加载死循环 → 白屏**(见 §5.2)。

3.2 文件职责

文件 职责
MariBankShpsNativeHook.java Native 层检测绕过:/proc/self/maps 过滤、boot 属性伪装、Build 字段、requestDefense
MariBankRootBypassHook.java Java 层SafeMode、SHPSSDK risk、OkHttp 出站净化、弹窗/自杀拦截、4067 日志
MariBankRiskTokenUtil.java riskToken / deviceToken 尾部净化工具类

4. 实现细节(按模块)

4.1 反自杀与反「假闪退」(MariBankRootBypassHook

问题背景SafeMode 检测到 Root 后会 Toast + Process.killProcess + Activity.finishAffinity,表现为闪退。

实现

  1. Hook Process.killProcess(self)System.exit → 直接拦截
  2. Hook Activity.finish / finishAffinity / finishAndRemoveTask / moveTaskToBack
  • 8 秒宽限期内(SOFT_CRASH_GUARD_MS)阻止 BKE 相关 Activity 被风控栈关闭
  • 通过栈追踪识别 safemode / shpssdk / errorcodehandler 等调用来源
  • 保留用户按返回键isUserBackNavigation()
  1. 拦截 Root 相关 Toast 文案(rooted or jailbrokenmagisk/xposed/frida 等)

logcat 典型输出

notiMessageHook/MariBankRoot: blocked killProcess(self)
notiMessageHook/MariBankRoot: blocked finishAffinity on com.shopee.bke...

4.2 SafeMode 检测绕过

目标类(方法名混淆,无法按名 Hook

  • com.shopee.bke.lib.safemode.b
  • com.shopee.bke.lib.safemode.catchs.a
  • com.shopee.bke.lib.safemode.util.c
  • com.shopee.bke.biz.base.risk.a

策略Hook 所有 非 static、参数 ≤2、返回 boolean/int 的实例方法,统一返回 false / 0

弹窗Hook SafeModeRecoverActivity 相关 Dialog / AlertDialog.show阻止 Root 提示框。

4.3 SHPSSDK 风控Java 层)

boolean 检测类

  • com.shopee.shpssdkbank.SPSAssessRisk
  • com.shopee.shpssdk.SPSAssessRisk

Token 相关 HookhookShpsToken

方法 处理
getRiskSync / getRiskAsync 返回 空 risk 列表,避免 RISK_ROOT=1RISK_HOOK=4 写入
getRiskToken / getRiskTokenAsync 返回值经 MariBankRiskTokenUtil.sanitizeRiskToken
vvuuuuvvv.wwvuwuwvu(Context) 真实 token 生成链,最早出口净化
getSecData 字符串返回值净化

RISK 常量(逆向)RISK_ROOT=1RISK_HOOK=4 等会编码进 token 尾部。

4.4 Native 层检测绕过(MariBankShpsNativeHook

**/proc 过滤**

  • Hook FileInputStream / BufferedReader / RandomAccessFile
  • /proc/self/maps/proc/version/proc/self/status 等读结果 过滤敏感行
  • 隐藏 markerxposedlsposedmagiskfridazygiskmiraclegarden

Boot / 环境伪装

  • SystemProperties.get 伪装 ro.boot.verifiedbootstatero.boot.vbmeta.device_state
  • Build 字段、/proc/self/attr/current → 伪造 SELinux 上下文

SHPS native 桥

  • requestDefense → 解密/处理 x-sap-fixme 请求头
  • hookShpsNativeCore → native 桥接类 boolean 返回 false

刻意不 Hook

// MariBankShpsNativeHook.hookShpssInstall()
// 勿 Hook ShpssInstall / vuvuwwwuw会干扰 SoUtils.loadSoLibrary导致 libsdkutils.so 死循环白屏。

4.5 网络出站净化OkHttp 链)

不能 Hook RealInterceptorChain.proceedSO 硬编码检测),改为在更外层拦截:

Hook 点 作用
OkHttpClient.newCall 替换 Request 为净化版
RealCall.execute / enqueue 同上
Request.Builder.build / post(body) body 写入时净化
RequestBody.writeTo 写出字节时净化
Gson.toJson / fromJson JSON 中 riskToken 字段
JSONObject.put("riskToken", ...) 直接改字段
Response.request().url() 记录 URL关联 4067 响应

净化逻辑MariBankRiskTokenUtil

  • 正则匹配 pipe-token 尾部 \d+\|\d+ → 改为 00|0
  • JSON 字段 "riskToken" / "deviceToken" 同步处理

register body 日志

register request body unreadable (encrypted or one-shot)

说明 register 的 body 在 Java 层已是 加密或一次性 RequestBody,无法直接读明文。

4.6 错误码与弹窗监控

服务端错误码logcat 实测):

code 含义
4067004 安全封锁(与 4067012 同类)
4067012 账户安全临时封锁

客户端弹窗文案(服务端下发,非本地 Root 弹窗):

For your account's security, this service has been temporarily blocked...
(+632) 8424 8050

Hook 对含 temporarily blocked / 8424 8050 的 Toast 会 记录栈logBriefStack),便于区分本地 vs 服务端弹窗。


5. 遇到的问题(完整清单)

5.1 服务端注册拒绝 — 4067012核心未解问题

现象

  • 能进入 Sign up 页
  • 请求发出后弹服务端封锁弹窗
  • 多个号码(917885426691334777999171243667 等)均失败

logcat

POST /uapi/v2/register
→ {"code":4067012,"msg":"For your account's security, this service has been temporarily blocked..."}

分析

  1. 不是本地 Root 弹窗——本地 bypass 后已能到达注册页并成功打 DFP
  2. DFP 成功仅说明 上报链路通,不代表服务端认可设备
  3. riskToken 尾部改掉 不够——token 主体可能含加密指纹,或服务端维护设备/号码黑名单
  4. 多次失败可能 加重封锁(建议冷却 2448h

待验证

  • 未 Root 干净机 + 菲律宾 IP + 新号码 → 区分设备封禁 vs 号码封禁
  • Hook native 加密前明文,看清 register body 到底带了什么

5.2 过早 Hook 导致白屏libsdkutils 死循环)

现象App 启动白屏logcat 反复出现 SoUtils / loadSoLibrary("sdkutils")

原因

  • loadPackage 时 split APK 的 ClassLoader 尚未绑定
  • 过早 Hook ShpssInstallvuvuwwwuw 或完整 SHPSSDK 链 → 干扰 SO 加载顺序

解决

  • Early 阶段 只装 /proc 过滤 + 反自杀
  • BkeApplication.attachBaseContext 回调后再 installDeferredHooks
  • 永不 Hook ShpssInstall / vuvuwwwuw

5.3 不能 Hook RealInterceptorChain.proceed

现象Hook 后触发 native 硬编码检测,行为异常或加重风控。

逆向依据libshpssdk_bank.so 字符串含 RealInterceptorChain.proceed

解决:改 Hook OkHttpClient.newCallRealCall.executeRequestBody.writeTo 等外层点。


5.4 register 请求体无法读取

现象logcat 始终为:

register request body unreadable (encrypted or one-shot)

原因

  • Body 经 NativeEncryptUtilsWrapper → native uvwuvwuv 加密
  • 可能是 one-shot RequestBody,写入后不可重读

影响:无法在 Java 层确认手机号 JSON 明文内容,也无法在 Xposed 层直接改 register 字段(除 riskToken 出站净化外)。

后续方向Frida/native Hook libsdkutils.soutils.d 包装方法。


5.5 wvvvuwwu.vuwuuwvw native 未找到

现象logcat 出现 native 方法实现找不到的警告。

可能原因

  • LSPosed 与 Frida/Clash 等环境叠加干扰
  • 混淆类在不同 split / 版本下位移
  • Hook 时机与 ClassLoader 边界问题

影响:部分 SHPS native 桥接 Hook 可能未完全生效;但 DFP 已成功,说明主链路部分工作。


5.6 Frida 动态分析失败

环境Frida 17.15.3 + /data/local/tmp/frida-server

问题 详情
attach 找不到 Java 60s 内 Java.available == false
进程名 需用 MariBank 而非 ph.seabank.seabank
spawn native dlopen 可 hookJava 层 Java is not defined
CLI 退出 spawn 无保活脚本会立刻 detach
与 LSPosed 冲突 建议测 Frida 时 关闭 LSPosed 对 MariBank 作用域

结果:未抓到 /register 明文 body当日分析 主要依赖 LSPosed logcat

脚本位置:reverse/frida/trace_maribank_register.jsrun_frida_trace.py



5.7 本地 Root 检测 vs 服务端封锁(易混淆)

类型 文案特征 来源 当日状态
本地 Root rooted or jailbrokenmagisk/xposed/frida SafeMode / SHPSSDK 已拦截 Toast可继续使用
服务端封锁 temporarily blocked8424 8050 API 4067012 响应 未绕过

6. 实测 logcat 参考

6.1 成功片段DFP + token 净化)

notiMessageHook/MariBankRoot: sanitized riskToken tail 09|1 -> 00|0
notiMessageHook/MariBankRoot: HTTP .../dfp/v1/data/report ... code=0

6.2 失败片段(注册)

notiMessageHook/MariBankRoot: register request body unreadable (encrypted or one-shot)
notiMessageHook/MariBankRoot: HTTP .../uapi/v2/register ... code=4067012
notiMessageHook/MariBankRoot: security block Toast: For your account's security...

6.3 推荐过滤命令

powershell -File scripts\logcat-maribank.ps1 -Follow

# 或
adb logcat -s notiMessageHook/MariBankRoot:V notiMessageHook/MariBankNative:V

7. 部署与验证

7.1 构建安装

powershell -ExecutionPolicy Bypass -File scripts\build-debug.ps1
powershell -ExecutionPolicy Bypass -File scripts\install-debug.ps1

7.2 LSPosed 作用域

必须勾选:

  • ph.seabank.seabankMariBank
  • com.miraclegarden.smsmessage(主 App
  • Xposed 模块自身

修改 Hook 后:强制停止 MariBank 再冷启动。

7.3 测试路径

注册(当日已测)

Sign up → 输入 10 位菲律宾号码(如 9XXXXXXXXX→ Next
观察 logcat 中 /dfp 与 /register 响应

登录(当日未测,供对照)

Log in → 输入已开户手机号 → 继续
观察 /v2/auth/precheck、/login/otp/* 或 /pin/auth 响应
详见 §2.4

8. 已知限制

  1. 仅改 riskToken 尾部不足以通过服务端 register 校验
  2. register body 加密Java Hook 无法读明文、难改字段
  3. RealInterceptorChain 等 SO 检测点不可 Hook
  4. ShpssInstall 不可 Hook限制 SO 加载链上的干预手段
  5. Frida 在当前 App 上 Java 桥不稳定
  6. 多次失败 可能导致号码/设备进入服务端黑名单
  7. 登录流程未实测;若设备已被 4067012 封锁,登录很可能同样失败(见 §2.4

9. 后续工作建议

优先级 方向 说明
P0 对照实验 干净机 + PH IP + 新号,确认封禁维度;有老户时可对比登录 precheck
P1 Native 明文 Hook utils.d / libsdkutils.so 加密前抓包
P2 riskToken 全链 不仅尾部,需理解 pipe 各段含义及 DFP 载荷
P3 Frida 环境 无 LSPosed 冲突、或 Zygisk 隐藏 Frida 后再 attach
P4 停试冷却 已失败号码/设备 2448h 内勿反复请求
官方渠道 (+632) 8424 8050

10. 相关文件索引

路径 说明
xposed-module/.../MariBankRootBypassHook.java Java 层主 Hook~1700 行)
xposed-module/.../MariBankShpsNativeHook.java Native/proc 层 Hook
xposed-module/.../MariBankRiskTokenUtil.java Token 净化
xposed-module/.../MainHook.java 包名路由
reverse/frida/jni_targets.md JNI / Frida 目标
reverse/frida/trace_maribank_register.js Frida trace 脚本
scripts/logcat-maribank.ps1 logcat 过滤
scripts/start-mari-trace.ps1 Frida + logcat 联启
docs/WORKLOG_2026-07-03.md 当日全项目工作汇总

文档版本2026-07-03 · 对应 commit 分支 ysc