|
|
发表于
2026-7-19 15:54:31
|
显示全部楼层
来自 山东
第一部分:去签名校验
这个应用采用 SO 层为主的签名校验方案,Java 层仅有进程类型判断逻辑,不存在传统意义的签名比对代码,直接开整
1.1 Java 层(非签名校验)
搜索类 com.wifitutu.ka.manager.a
调用链 TuTuApp.attachBaseContext() → kaHelper.c() → Lsh/a;->c()
Lsh/a;->c() 方法完整逻辑:
- public static boolean c(String processName, String packageName) {
- if (processName.endsWith(":sync") ||
- processName.endsWith(":assistant") ||
- processName.endsWith(":persistent") ||
- processName.endsWith(":assist") ||
- processName.endsWith(":assist1")) {
- return true;
- }
- if (TextUtils.equals(processName, packageName + ".daemon")) {
- return true;
- }
- return false;
- }
复制代码 1.2 SO 层(真正的签名校验)
签名校验由爱加密 (ijiami) 加固方案在 SO 层实现在:
libijm_linker.so,libijiami_ijm.so,libkey.so,ijiami_ijm.VData
二、去签名校验
2.1 Smali 修改
文件: classes2.dex
类: Lijiami_ijm/NCall;
方法: <clinit>()V
用 try-catch 包裹 System.loadLibrary("ijiami_ijm"),捕获 UnsatisfiedLinkError,防止 SO 文件删除后因加载失败导致的应用崩溃。
2.2 文件删除
| 序号 | 文件路径 | 操作 | | 1 | lib/arm64-v8a/libijiami_ijm.so | 删除 | | 2 | lib/arm64-v8a/libijm_linker.so | 删除 | | 3 | lib/arm64-v8a/libkey.so | 删除 | | 4 | assets/ijiami_ijm.VData | 删除 |
第二部分:去广告
一、广告SDK分析
该应用集成了多个广告SDK,通过自建的广告聚合层统一管理:
| 广告SDK | 包名 | 类型 | | 百度 MobAds | com.baidu.mobads | 横幅/插屏/开屏/视频 | | 穿山甲 CSJ | com.bytedance.sdk.openadsdk | 信息流/开屏/激励视频 | | 优量汇 GDT | com.qq.e | 横幅/插屏/开屏 | | Octopus | com.octopus.ad | 下载广告 | | 荣耀 Ads | com.hihonor.adsdk | 广告归因 | | zm.adxsdk | com.zm.adxsdk | 自建广告包装层 | | zm.wfsdk | com.zm.wfsdk | 自建广告落地页 |
广告架构: 所有第三方SDK通过 com.wifi.business.potocol.sdk 聚合层统一接入,广告对象继承 AbstractAds(实现 IWifiAd 接口),通过 BaseAdLoader 统一加载。
二、去广告修改内容
共修改 6 个类(涉及 3 个 dex 文件):
| 序号 | 修改位置 | 修改方式 | 目标广告类型 | 说明 | | 1 | AbstractAds.isReady() | 返回 false | 所有聚合层广告 | 广告基类就绪判断始终返回 false,所有继承此基类的广告对象被认为"未就绪" | | 2 | BaseAdLoader.onAdLoadSuc() | 方法体清空 | 所有广告加载成功回调 | 广告加载成功后的处理逻辑被清空,广告对象不会被创建和分发 | | 3 | WWV2V.isReady() | 返回 false | 自建广告包装层 | zm.adxsdk 包装层的开屏/插屏/激励视频就绪判断始终返回 false | | 4 | LauncherActivity.T0() | 跳过广告加载,直接跳转主界面 | 开屏广告 | 启动时不再加载任何开屏广告,直接调用 d1() 跳转 MainActivity | | 5 | ActiveAppActivity.onCreate() | 立即 finish() | 加速/活跃广告页 | 打开后立即关闭 | | 6 | ReplayAdShowActivity.onCreate() | 立即 finish() | 视频回放广告页 | 打开后立即关闭 |
三、修改原理
- 去广告前:
- LauncherActivity.onCreate()
- → f1() → J0() → T0() ← 加载开屏广告
- → AbstractAds.isReady() → true → 展示广告
- → 广告展示完成 → d1() → 跳转MainActivity
- 去广告后:
- LauncherActivity.onCreate()
- → f1() → J0() → T0() ← 跳过广告加载,直接跳转
- → d1() → 跳转MainActivity
- → finish()
- 广告展示时:
- AbstractAds.isReady() → false → 广告不展示
- BaseAdLoader.onAdLoadSuc() → 空方法 → 广告不被处理
- WWV2V.isReady() → false → 自建SDK广告不展示
复制代码 第三部分:修改汇总
文件变更清单
| 文件/路径 | 操作 | 说明 | | classes2.dex | 修改 | NCall.<clinit>() 添加 try-catch | | classes8.dex | 修改 | AbstractAds.isReady(), BaseAdLoader.onAdLoadSuc() | | classes10.dex | 修改 | WWV2V.isReady() | | classes2.dex | 修改 | LauncherActivity.T0(), ActiveAppActivity.onCreate(), ReplayAdShowActivity.onCreate() | | lib/arm64-v8a/libijiami_ijm.so | 删除 | 爱加密辅助 SO | | lib/arm64-v8a/libijm_linker.so | 删除 | 爱加密核心 SO | | lib/arm64-v8a/libkey.so | 删除 | 密钥相关 SO | | assets/ijiami_ijm.VData | 删除 | 爱加密配置文件 |
修改效果
| 场景 | 修改前 | 修改后 | | 首次启动 | 有开屏广告,2-3 秒后进入主界面 | 无开屏广告,直接进入主界面 | | 使用过程 | 弹出插屏/视频广告 | 广告不弹出 | | 信息流浏览 | 列表中出现广告卡片 | 广告卡片空白或不展示 | | 签名校验 | 修改签名后闪退 | 不闪退 | | 启动速度 | 因开屏广告加载慢 | 启动更快 |
注意事项
- 必须卸载原版后再安装,签名不一致无法覆盖安装
- 仅支持 arm64-v8a 架构设备
- 信息流中的广告占位View可能仍会显示空白区域,但不影响正常使用
- 应用内部有热修复框架(Meituan Robust),但修改的代码路径不涉及热修复补丁
第四部分:具体修改步骤
环境准备
- 修改工具:MT MCP (APK 修改工具集)
- 运行环境:Termux + Android 设备
- 输出目录:/storage/emulated/0/MT2/mcp/
步骤一:打开 APK
- mt_apk_list_available_apks()
- mt_apk_open(path="WiFi万能钥匙.apk", temporary=false)
- → workspaceId: cdbsnco2
复制代码 步骤二:打开编辑会话
- mt_apk_edit_open(workspaceId="cdbsnco2")
- → editSessionId: bddff661
复制代码 步骤三:去签名校验
3.1 修改 NCall 类,添加 try-catch
- mt_apk_read_text(
- workspaceId="cdbsnco2", editSessionId="bddff661",
- locator="dex_method:Lijiami_ijm/NCall;-><clinit>()V"
- )
- mt_apk_edit_text(
- workspaceId="cdbsnco2", editSessionId="bddff661",
- locator="dex_method:Lijiami_ijm/NCall;-><clinit>()V",
- targetVersion="...",
- edits=[{
- mode: "write_target",
- writeText: ".method static constructor <clinit>()V\n .registers 1\n\n :try_start_0\n const-string v0, "ijiami_ijm"\n\n invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V\n\n :try_end_0\n .catch Ljava/lang/UnsatisfiedLinkError; {:try_start_0 .. :try_end_0} :catch_0\n\n :catch_0\n return-void\n.end method"
- }]
- )
复制代码 3.2 删除爱加密 SO 文件
- zip -d WiFi万能钥匙.apk lib/arm64-v8a/libijiami_ijm.so
- zip -d WiFi万能钥匙.apk lib/arm64-v8a/libijm_linker.so
- zip -d WiFi万能钥匙.apk lib/arm64-v8a/libkey.so
- zip -d WiFi万能钥匙.apk assets/ijiami_ijm.VData
复制代码 步骤四:去广告
4.1 修改 AbstractAds.isReady() → 返回 false
- mt_apk_read_text(
- locator="dex_method:Lcom/wifi/business/potocol/sdk/base/ad/AbstractAds;->isReady()Z"
- )
- → 原始代码: const/4 v0, 0x1 → return v0
- mt_apk_edit_text(
- edits=[{mode: "replace_match",
- matchText: " const/4 v0, 0x1\n\n return v0\n.end method",
- writeText: " const/4 v0, 0x0\n\n return v0\n.end method"}]
- )
复制代码 4.2 修改 BaseAdLoader.onAdLoadSuc() → 空方法
- mt_apk_edit_text(
- locator="dex_method:Lcom/wifi/business/potocol/sdk/base/BaseAdLoader;->onAdLoadSuc(Ljava/util/List;Ljava/lang/String;Ljava/util/List;)V",
- edits=[{mode: "write_target",
- writeText: ".method public onAdLoadSuc(Ljava/util/List;Ljava/lang/String;Ljava/util/List;)V\n .registers 4\n\n return-void\n.end method"}]
- )
复制代码 4.3 修改 WWV2V.isReady() → 返回 false
- mt_apk_edit_text(
- locator="dex_method:Lcom/zm/adxsdk/WWV2V;->isReady()Z",
- edits=[{mode: "write_target",
- writeText: ".method public isReady()Z\n .registers 2\n\n const/4 v0, 0x0\n\n return v0\n.end method"}]
- )
复制代码 4.4 修改 LauncherActivity.T0() → 跳过广告,直接跳转
- mt_apk_edit_text(
- locator="dex_method:Lcom/wifitutu/ui/launcher/LauncherActivity;->T0()V",
- edits=[{mode: "write_target",
- writeText: ".method private final T0()V\n .registers 2\n\n invoke-virtual {p0}, Lcom/wifitutu/ui/launcher/LauncherActivity;->d1()V\n invoke-virtual {p0}, Lcom/wifitutu/ui/launcher/LauncherActivity;->finish()V\n return-void\n.end method"}]
- )
复制代码 4.5 修改 ActiveAppActivity.onCreate() → 立即 finish
- mt_apk_edit_text(
- locator="dex_method:Lcom/wifitutu/ui/tools/ad/ActiveAppActivity;->onCreate(Landroid/os/Bundle;)V",
- edits=[{mode: "write_target",
- writeText: ".method public onCreate(Landroid/os/Bundle;)V\n .registers 3\n .param p1, "savedInstanceState" # Landroid/os/Bundle;\n .annotation build Lorg/jetbrains/annotations/Nullable;\n .end annotation\n .end param\n\n invoke-super {p0, p1}, Lcom/wifitutu/ui/BaseActivity;->onCreate(Landroid/os/Bundle;)V\n invoke-virtual {p0}, Lcom/wifitutu/ui/tools/ad/ActiveAppActivity;->finish()V\n return-void\n.end method"}]
- )
复制代码 4.6 修改 ReplayAdShowActivity.onCreate() → 立即 finish
- mt_apk_edit_text(
- locator="dex_method:Lcom/wifi/business/shell/replay/ReplayAdShowActivity;->onCreate(Landroid/os/Bundle;)V",
- edits=[{mode: "write_target",
- writeText: ".method public onCreate(Landroid/os/Bundle;)V\n .registers 2\n\n invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V\n invoke-virtual {p0}, Lcom/wifi/business/shell/replay/ReplayAdShowActivity;->finish()V\n return-void\n.end method"}]
- )
复制代码 步骤五:构建并签名
- mt_apk_edit_check(workspaceId="cdbsnco2", editSessionId="bddff661", runBuildChecks=true)
- mt_apk_build(workspaceId="cdbsnco2", editSessionId="bddff661", outputName="", overwrite=false)
- → 输出: /storage/emulated/0/MT2/mcp/WiFi万能钥匙_mcp_bddff661_sign.apk
- → 签名: V1 + V2 + V3
复制代码 修改文件分布
| DEX 文件 | 修改的类 | | classes2.dex | NCall, LauncherActivity, ActiveAppActivity, ReplayAdShowActivity | | classes8.dex | AbstractAds, BaseAdLoader | | classes10.dex | WWV2V |
大概就是这样,,,
我帮楼主转换一下看看 |
|