安卓代码加固
安卓代码加固(9):防录屏
来电页、落地页、全屏广告使用 FLAG_SECURE。截屏与录屏得到黑屏,无需额外权限。
代码放入加密 dex 之后,屏幕上的来电页、落地页和全屏广告仍能被截屏或录屏。工程用系统窗口标志 FLAG_SECURE 处理这一层:截屏失败或得到黑图,录屏画面为全黑,多任务缩略图也会被抹掉。
这不是 DEX 加固,是窗口级隐私保护。不需要 Manifest 权限,也不影响点击。
通过 SDK 指令调用
接入文档约定 invoke(13, activity)。实现位于加密 dex 的 applyScreenProtection:
hidden-landing-page/src/main/java/com/example/minidex/hidden/HiddenLandingPageController.kt
fun applyScreenProtection(activity: Activity, enable: Boolean) {
if (enable) {
activity.window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
} else {
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
}
}
关键点是:未 init 也会加标志。HiddenSdk.fallback 在 native 尚未 ready 时会自行操作 window,避免密钥错误后来电页反而能被截屏。
hidden-sdk/src/main/java/com/example/minidex/sdk/HiddenSdk.kt
13 -> {
val activity = a as? Activity
if (activity != null) {
val enable = when (b) {
is Boolean -> b
else -> true
}
if (enable) {
activity.window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
} else {
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
}
}
null
}
Demo 宿主在来电路由页和落地页的 onCreate 里调用 HiddenSdk.invoke(13, this)(或 HostBridge.protect)。
保护全屏广告
:ads 不走 HiddenSdk,自己按 Activity 类名判断:
ads/src/main/java/com/example/minidex/ads/internal/AdScreenProtection.kt
fun isAdRelatedActivity(className: String): Boolean {
return className.contains("com.google.android.gms.ads") ||
className.contains("AdActivity") ||
className.contains("AdLandingActivity") ||
className.contains("com.google.android.libraries.ads")
}
fun applyScreenProtection(activity: Activity, enable: Boolean = true) {
if (enable) {
activity.window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
} else {
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
}
}
init(application) 注册生命周期回调,在 created、started、resumed 时重复施加。AdMob 全屏页由 SDK 自行启动,宿主清单里没有类名,只能按包名匹配。
可用 AdConfig.enableScreenProtection 关掉。落地页 AdLandingActivity 也会再调用一次 AdSdk.applyScreenProtection(this)。
FLAG_SECURE 阻止的是系统截屏、录屏和 Recents 缩略图。它不能阻止 HDMI、定制 ROM 或已 root 设备上的帧缓冲抓取。对照两套入口
| 场景 | 入口 | 未初始化 |
|---|---|---|
| 来电 / 落地页 | HiddenSdk.invoke(13, activity) | fallback 仍加标志 |
| 全屏广告 | AdScreenProtection 生命周期 | 与 HiddenSdk 无关 |
两套实现都是同一条系统 API,故意不抽成公共模块,避免广告模块 compile 依赖 hidden-sdk。