这个叫做GO视频播放器的app,开屏广告,进入app后等一会也也有全屏广告

57549-6b053lsxthq.png

大概看了下,虽然没有加固,但是代码进行了大幅度的混淆。
各种关键词、文本都在代码里搜索不到,全是没有意义的函数和变量。

96110-7hpycn7f2vc.png

然后是想从抓包入手,结果发现打开了抓包软件,APP就不显示广告和会员入口。
通过参数可以看到的确判断了VPN并且进行了上报

92837-e5w9l03l3tq.png

关键的来了,当开启抓包(VPN)时,开屏不仅没有了广告,而且进入app后购买会员等标识也消失了
可以推断在启动页launcherActivity中先判断了VPN再决定要不要显示广告。
但是Hook不需要去找VPN等函数,我试过了,跳了很多层依然没找到关键入口
所以就盲打,直接Hook launcherActivity OnCreate(),让launcherActivity 启动时直接跳转到主界面

结果真的直接跳过了开屏广告。但是还有一个问题,就是主界面右上角的会员标识等还在

29671-ji81uy5itqh.png

根据前面开启抓包就没有会员标识可以确认主界面的会员标识数据也是启动页launcherActivity 传递过去的。所以我们可以试着在启动主界面后,立即结束启动页,阻止数据传递。然后就真的完全去除了广告和会员限制

19242-oorwnjluak.png

尽管APP有反编译、反抓包等手段,但是百密一疏。我都没想到竟然这么简单的破解完了。
最后成品和代码都放到github上了(传送门)

@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
    if (!TARGET_PACKAGE_NAME.equals(lpparam.packageName)) {
        return; // 如果包名不匹配,直接返回,不执行后续逻辑
    }

    XposedBridge.log(TAG + ": Hook目标: " + lpparam.packageName);

    // 直接hook开屏oncreate
    String launcherActivityClassName = "com.lvxingetch.goplayer.launcher.LauncherActivity";
    String onCreateMethodName = "onCreate";
    Class<?>[] bundleParamType = {Bundle.class}; // onCreate(Bundle savedInstanceState)

    Class<?> launcherActivityClass = XposedHelpers.findClassIfExists(launcherActivityClassName, lpparam.classLoader); // 使用 findClassIfExists 更安全
    if (launcherActivityClass != null) {
        XposedBridge.log(TAG + ": Found class " + launcherActivityClassName);

        // Hook onCreate(Bundle savedInstanceState) 方法,在方法执行完毕后 (after) 立即跳转
        XposedHelpers.findAndHookMethod(launcherActivityClass, onCreateMethodName, bundleParamType[0],
                new XC_MethodHook() {
                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        Log.d(TAG, "[Xposed] Hooked LauncherActivity.onCreate()已成功");

                        // 获取当前 LauncherActivity 实例
                        android.app.Activity launcherActivityInstance = (android.app.Activity) param.thisObject;

                        try {
                            // 创建跳转到 MainActivity 的 Intent
                            Class<?> mainActivityClass = XposedHelpers.findClass("com.lvxingetch.goplayer.MainActivity", lpparam.classLoader);
                            Intent intent = new Intent(launcherActivityInstance, mainActivityClass);

                            // 启动 MainActivity
                            launcherActivityInstance.startActivity(intent);
                            Log.d(TAG, "[Xposed] 启动 MainActivity 成功.");

                            // 直接结束LauncherActivity,不然它会接收数据使得在MainActivity右上角显示开会员等标识
                            launcherActivityInstance.finish();
                            Log.d(TAG, "[Xposed] 关闭LauncherActivity");

                        } catch (Exception e) {
                            Log.e(TAG, "[Xposed] Error: " + e.getMessage(), e);
                        }
                    }
                });
    } else {
        XposedBridge.log(TAG + ": Class " + launcherActivityClassName + " 在com.lvxingetch.goplayer中没找到");
    }