某班课app卡开屏完整逆向以及小发现

某班课app卡开屏完整逆向以及小发现
某班课app卡开屏完整逆向以及小发现

*班课开屏卡半天进不去导致签到没签上,好好好正好最近在推进jshookmcp的安卓逆向能力那么:

*班课 App 逆向分析:一个教育App能塞多少屎


一、基本信息

项目 值 包名 com.**.teach 版本 5.4.51 APK 大小 151 MB targetSdk 33 (Android 13) 加壳 梆梆安全 SecNeo (com.secneo.apkwrapper) Application com.**.teach.MTApp 启动页 MainActivityMainMenuActivity 冷启动耗时 3042ms 主线程最大阻塞 751ms(单次消息延迟)

二、加壳分析

APK 使用梆梆安全加壳,壳代码位于 com.**.apkwrapper 包下:

壳特征

  • Native 解壳库libDexHelper.so(ARM) / libDexHelper-x86.so
  • AppComponentFactory 劫持:通过 AP.smali 拦截所有组件实例化
  • 解壳时机H.load()instantiateClassLoader 阶段触发,从 APK 中提取加密 DEX
  • 加密 payload 位置:APK 内 assets 目录中(壳在 loadLib 方法中从 APK 的 lib/ 目录提取 SO)

反调试措施

// H.smali - Iii1Iii1IIIi1() 方法
// 读取 /proc/self/status 检查 TracerPid
new BufferedReader(new FileReader("/proc/self/status"))
// 匹配 "TracerPid:" 行,非零则表示被调试

// 另一个反调试
new FileInputStream("/system/bin/app_process")
// 检查 app_process 完整性
SystemClock.sleep(2000) // 延时反调试

启动日志也印证了反调试:

Not starting debugger since process cannot load the jdwp agent.

解壳耗时

从 logcat 时间线分析,梆梆解壳独占约 376ms

T+0ms     Init 进程
T+90ms    ART SDK 初始化完成
T+466ms   libDexHelper.so JNI_OnLoad success  ← 解壳在这 376ms 内完成

三、SDK 清单:一个教育 App 集成了多少第三方

广告 SDK(5 个,开屏+信息流+激励视频)

SDK 用途 证据 倍孜 BeiZis 开屏广告 BeiZis: request SplashAd adUnitId:119600 云帆 YFAds 广告投放 YFAds: initWua end 快手 Kwai Ad 短视频广告 Manifest 中 com.kwad.sdk,6 个 Activity 壳 华为 Ads 华为广告联盟 com.huawei.openalliance.ad 穿山甲/字节 字节跳动广告 jad_click.json, jad_shake.json(穿山甲 Lottie 素材)

推送 SDK(4 个,全家桶)

SDK 证据 极光推送 JPush cn.jpush.android.service,Manifest 中完整声明 华为 Push Kit com.huawei.hms.support.api.push.TransActivity 魅族 Push cn.jpush.android.service.PluginMeizuPlatformsReceiver vivo Push cn.jpush.android.service.PluginVivoMessageReceiver

其他 SDK

SDK 用途 大小 声网 Agora 音视频通话 17MB + 6.5MB×3 + 更多 百度语音 语音识别 1.2MB Bugly 崩溃上报 191KB 友盟 Umeng 数据统计 Manifest UMENG_APPKEY=55b0603be0f55a4dc0000a0f 支付宝 支付 com.alipay.sdk.app 腾讯 QQ/微信 社交分享 com.tencent.connect, WXEntryActivity AGConnect 华为服务 AGConnectInitializeProvider Chromium WebView 内置浏览器 HTTP 缓存 197MB (你要下片吗)

四、原生库(SO)分析:83MB 的恐怖体积

arm64-v8a 目录就塞了 83MB 的 SO 库:

SO 文件 大小 所属 SDK libagora-rtc-sdk.so 17 MB 声网 RTC libagora-rtm-sdk-jni.so 6.5 MB 声网 RTM libAgoraMediaPlayer.so 6.5 MB 声网播放器 libagora-player-ffmpeg.so 5.7 MB 声网 FFmpeg libagora_fpa_sdk.so 2.9 MB 声网 FPA libagora-ffmpeg.so 1.5 MB 声网 FFmpeg libBaiduSpeechSDK.so 1.2 MB 百度语音 libDexHelper.so 1.2 MB 梆梆加壳 libDexHelper-x86.so 1.2 MB 梆梆加壳(x86) libRSSupport.so 2.1 MB RenderScript libagora-core.so 487 KB 声网核心 libagora_fdkaac.so 495 KB 声网 AAC libagora-soundtouch.so 179 KB 声网音效 libagora_fpa_service.so 911 KB 声网 FPA libBugly_Native.so 191 KB Bugly 崩溃 libPglbizssdk_ml.so 1.1 MB 未知 SDK libads-ac.so 9.9 KB 广告 SDK libads-c.so 11 KB 广告 SDK

声网 SDK 一家就占了 ~33MB,一个教育 App 的音视频功能在启动时就要加载这些,浮木骨灰盒都打包进去了是吧。


五、启动流程分析

完整时间线(冷启动)

T+0ms     18:38:04.465  Init 进程
T+28ms    18:38:04.493  SecNeo 反调试检查,阻断 JDWP 调试器
T+90ms    18:38:04.555  ART SDK 版本检测 (API 33)
T+466ms   18:38:04.931  梆梆 libDexHelper JNI_OnLoad 完成 ← 解壳 ~376ms
T+542ms   18:38:05.007  MultiDex 安装
T+553ms   18:38:05.018  AGConnect 华为服务初始化
T+581ms   18:38:05.046  InitProvider 初始化(更多 SDK)
T+800ms   18:38:05.268  PerfMonitor 主线程延迟 548ms
T+800ms   18:38:05.268  PerfMonitor 主线程延迟 751ms ← 严重卡顿
T+800ms   18:38:05.269  PerfMonitor 主线程延迟 742ms
T+802ms   18:38:05.271  PerfMonitor 主线程延迟 741ms
          ...后续 SDK 继续在主线程初始化...
T+3042ms                 am start -W 返回 WaitTime

主线程阻塞证据

系统 PerfMonitor 捕获到连续 4 次严重的主线程消息延迟:

PerfMonitor: latency=548ms  (BIND_APPLICATION, wall=533ms)
PerfMonitor: latency=751ms  (EXECUTE_TRANSACTION, wall=204ms)
PerfMonitor: latency=742ms
PerfMonitor: latency=741ms

单次消息最高延迟 751ms,连续 4 次累计阻塞超过 2.7 秒。这直接导致冷启动 3 秒。

那么开屏流程是这样的:

MainActivity 启动

请求开屏广告

等待广告加载
↓ ↓
广告加载成功 广告加载失败/超时
↓ ↓
展示广告 N秒 等到超时才跳转
↓ ↓
跳转到 MainMenuActivity

如果你用去广告工具把广告请求 host 拦截了,BeiZis SDK 的 request SplashAd 就会一直等广告服务器响应,那么很抱歉同学你签不上到了。


六、广告 SDK 开屏行为分析

BeiZis 开屏广告请求

18:15:54.707  BeiZis: request SplashAd adUnitId:119600
18:15:54.825  BeiZis: spaceBean is null and return fail
18:15:54.825  BeiZis: startUpdateConfig
18:15:54.825  BeiZis: heartbeatTime:60000

倍孜 SDK 在启动时请求开屏广告位 119600,同时:

  • 获取设备 OAID(IdProviderImpl: getOAID
  • 通过 AdManager 管理广告标识(AdManager: code sm Oaid:5d2a1f53331d09f6
  • 云帆广告 SDK 同步初始化(YFAds: initWua end

断网测试结果

使用 iptables DROP 掉 app 全部出站 TCP 流量后:

  • 冷启动时间:3042ms(与正常网络一致)
  • 结论:广告网络请求不是启动卡顿的主因,3 秒主要来自壳解密 + SO 加载 + 主线程 SDK 初始化

七、其他恶心发现

7.1 MIUI 反射调用被拦截

Accessing hidden method Landroid/view/Window;->setExtraFlags(II)V (blocked, reflection, denied)
Accessing hidden field Landroid/view/MiuiWindowManager$LayoutParams;->EXTRA_FLAG_NAVIGATION_BAR_DARK_MODE:I

App 试图通过反射调用 MIUI 系统隐藏 API 修改导航栏颜色,被 Android 13 的 hidden API 限制拦截。

7.2 HTTP 缓存 197MB

chromium: HTTP Cache size is: 206722859  (197 MB)

WebView 的 HTTP 缓存膨胀到 197MB,在启动时需要初始化,我问问簧片app启动缓存都没这么大你是要下片吗。

7.3 Bugly 广播接收器权限配置错误

BroadcastQueue: Permission Denial: broadcasting Intent { act=android.net.conn.CONNECTIVITY_CHANGE }
requires com.tencent.bugly.BuglyBroadcastReceiver.permission

Bugly 的网络变化广播接收器权限配置有误,每次网络变化都会触发权限拒绝警告。

7.4 极光推送连接失败

JIGUANG-JCore: [TcpRequestManager-main] [key-step]send error -tcp connect was invalid

极光推送在启动时 TCP 连接失败,每次启动都会重试,又不降级又不容灾赤白饭吗。

7.5 开屏请求摄像头服务

CameraManagerGlobal: Connecting to camera service
CameraExtStub: init android.hardware.camera2.impl.CameraExtImplXiaoMi

开屏阶段就连接摄像头服务,你是l聊app吗。

7.6 Manifest 泄露的密钥

<meta-data android:name="UMENG_APPKEY" android:value="55b**"/>
<meta-data android:name="MEIZU_APPKEY" android:value="MZ-**"/>
<meta-data android:name="MEIZU_APPID" android:value="MZ-**"/>

友盟 AppKey 和魅族推送密钥直接明文写在 Manifest 中啊对对对就喜欢露出。


八、assets 目录可疑文件

文件 说明 ijiami_1011.VData 爱加密相关数据(疑似壳中壳或安全检测) libscorpion_bin.so Scorpion 二进制(调试检测) SCORPION.VERSION Scorpion 版本信息 aicontrol.bsg AI 控制相关 baidu_speech_grammar.bsg 百度语音语法 info.y 未知用途 na.czl 未知用途 mimoVerCode 版本验证码 ssl_red_ai/aj/ak.properties SSL 相关配置

九、总结

问题汇总

严重程度 问题 评价 :red_circle: 严重 梆梆加壳导致冷启动增加 ~400ms 拉完了 :red_circle: 严重 主线程 SDK 初始化阻塞 750ms+ 卡开屏 :red_circle: 严重 5 个广告 SDK + 4 个推送 SDK 同时初始化 启动慢、耗电、耗流量 :orange_circle: 中等 83MB+ SO 库全量加载 内存占用高、启动慢 :orange_circle: 中等 声网 33MB SDK 常驻加载 想偷听 :yellow_circle: 一般 WebView 缓存膨胀到 197MB 在下片 :yellow_circle: 一般 开屏连接摄像头服务 想l聊 :yellow_circle: 一般 反射调用系统隐藏 API 兼容性问题 :blue_circle: 信息 Manifest 明文密钥 喜欢露出

数据对比

指标 云班课 行业正常水平 APK 大小 151 MB 30-50 MB 冷启动时间 3.0 秒 < 1.0 秒 广告 SDK 数量 5 个 0-1 个(教育类) 推送 SDK 数量 4 个 1 个 原生库体积 83 MB 10-20 MB 主线程最大阻塞 751 ms < 16 ms 第三方 SDK 总数 15+ 5-8 个

十、运行时密钥提取

提取方法

梆梆安全加壳导致静态分析无法获取真实代码和密钥。Frida 被反调试(TracerPid 检测)拦截,frida-dexdump 失败。最终通过某神秘方法(后续上架jshookmcp)拿到密钥。

提取到的密钥

# SDK 密钥类型 值 来源 1 OPPO 推送 AppKey 97ff** 运行时内存 2 OPPO 推送 AppSecret 8ac9** 运行时内存 3 魅族推送 AppKey MZ-** Manifest + 内存验证 4 魅族推送 AppID MZ-** Manifest 5 华为推送 AppID B737** 运行时内存 6 高德地图 API Key d6f0** 运行时内存 7 倍孜广告 开屏广告位 ID 206720670 运行时内存 8 倍孜广告 SDK Host https://sdk.beizi.biz 运行时内存 9 友盟 AppKey 55b0** Manifest 10 环信 IM 加密 AppKey rzlD** SharedPreferences

十一、赠礼

一个教育App把安全预算花在反逆向加壳上,开屏必须看广告不看不给进主界面,很好奇家里还有人吗。

4 个帖子 - 4 位参与者

阅读完整话题

来源: LinuxDo 最新话题查看原文