【去除广告】《安卓逆向这档事》四、恭喜你获得广告&弹窗静默卡

资源

这是《安卓逆向这档事》四、恭喜你获得广告&弹窗静默卡的课后作业

Android逆向学习(四)app修改smali函数跳过弹窗广告,等待广告,更新提醒 - 吾爱破解 - 52pojie.cn

这里使用frida编写脚本进行解题

弹窗1

进入app第一个弹窗

image-20250504170811188

使用jadx反编译,直接搜索文本

image-20250504171111949

np.֏

image-20250504171137784

直接将代码丢给deepseak,给出hook脚本

/*
去除弹窗
* */
Java.perform(function () {
    const TARGET_CLASS = "np.\u058F"; // 目标类名 np.֏.ށ
    var targetClass = Java.use(TARGET_CLASS);
    var methods = targetClass.class.getDeclaredMethods();
    methods.forEach(function (method) {
        var methodName = method.getName();
        var params = method.getParameterTypes();
        var paramTypes = [];
        // 手动转换 Java 参数类型数组为 JS 字符串数组
        for (var j = 0; j < params.length; j++) {
            paramTypes.push(params[j].getName());
        }
        try {
            if (paramTypes.length > 0) {
                // 修复:使用 apply 传递参数类型数组
                targetClass[methodName].overload.apply(targetClass, paramTypes).implementation = function () {
                    console.log("[+] 拦截方法调用:", TARGET_CLASS + "." + methodName);
                    // 直接返回,不执行原逻辑
                };
            } else {
                // 无参数方法
                targetClass[methodName].implementation = function () {
                    console.log("[+] 拦截方法调用:", TARGET_CLASS + "." + methodName);
                    // 直接返回,不执行原逻辑
                };
            }
        } catch (e) {
            console.log("[!] Hook 失败:", e.message);
        }
    });
});

三秒广告

点击第三关

image-20250504171546475

会弹出来一个三秒的广告

image-20250504171627223

使用算法助手工具,定位这个三秒广告在那个activite

image-20250504172217236 image-20250504172402191

所在的activite为AdActivity

image-20250504172540048

image-20250504172624204

hook loadAd函数,调用时立即跳转

Java.perform(function () {
    // 直接触发跳转,绕过等待
    var AdActivity = Java.use("com.zj.wuaipojie.ui.AdActivity");
    AdActivity.loadAd.implementation = function () {
        this.jump(); // 立即跳转
        console.log("------跳过一次3s广告-------")
    };
});

弹窗2和3

image-20250504172940929 image-20250504172958270

可以使用弹窗定位

image-20250504173607608

image-20250504173710048

image-20250504173750343 image-20250504173832287

二号弹窗

image-20250511144143976

image-20250511144241348

image-20250511144326696

在com.zj.wuaipojie.ui.ChallengeThird中,1号弹窗和2号弹窗

/*
* 第1、2广告弹窗
* */
Java.perform(function () {
     // 定位弹窗类
    var CommonDialog = Java.use("com.zj.wuaipojie.util.CommonDialog");

    // 方案1:拦截弹窗的 show() 方法(直接阻止显示)
    CommonDialog.show.implementation = function () {
        console.log("[+] 拦截 CommonDialog 弹窗显示");
        // 不执行原方法,直接跳过
    };
});


#############################################################
都可以实现去除两个弹窗
Java.perform(function () {
     // 定位弹窗类
    var CommonDialog = Java.use("androidx.appcompat.app.AlertDialog");

    // 方案1:拦截弹窗的 show() 方法(直接阻止显示)
    CommonDialog.show.implementation = function () {
        console.log("[+] 拦截 CommonDialog 弹窗显示");
        // 不执行原方法,直接跳过
    };
});

为什么可以一次去除两个弹窗

Java.perform(function () {
    var AlertDialog = Java.use("androidx.appcompat.app.AlertDialog");
    var CommonDialog = Java.use("com.zj.wuaipojie.util.CommonDialog");

    // Hook AlertDialog.show()
    AlertDialog.show.implementation = function () {
        console.log("[*] AlertDialog.show() 调用栈: " + 
            Java.use("android.util.Log").getStackTraceString(
                Java.use("java.lang.Throwable").$new()
            )
        );
        return this.show();
    };

    // Hook CommonDialog.show()
    CommonDialog.show.implementation = function () {
        console.log("[*] CommonDialog.show() 调用栈: " + 
            Java.use("android.util.Log").getStackTraceString(
                Java.use("java.lang.Throwable").$new()
            )
        );
        return this.show();
    };
});

image-20250511183137542

从调用栈分析可知,两个弹窗的 show() 方法最终都调用了 Dialog.show()(父类方法),但只有第二个弹窗明确使用了 CommonDialog,而第一个弹窗的 show() 调用栈显示来自 AlertDialog$Builder.show()
根本原因CommonDialog 未重写 show() 方法,导致 CommonDialogAlertDialog 均使用父类 Dialogshow() 方法。当 Hook CommonDialog.show() 时,实际 Hook 的是 Dialog.show(),因此拦截了所有 Dialog 子类(包括 AlertDialogCommonDialog)。

横幅广告

image-20250504174349505

使用开发助手获取这个图片的控件id

image-20250504174611867

控件的展示是使用android.view.ViewGroup下的addView方法,但是有重载

# Hook 视图添加到布局
# Hook ViewGroup.addView() 方法
android hooking watch class_method android.view.ViewGroup.addView --dump-args --dump-backtrace

image-20250504175841603

去除这个横幅图片

/*
* 去除横幅
* */
Java.perform(function () {
    // 目标视图的十六进制资源ID(0x7f0801ca的十进制为2131231178)
    var TARGET_VIEW_ID = 0x7f0801ca;

    // Hook ViewGroup.addView(View, int, LayoutParams) 方法
    var ViewGroup = Java.use('android.view.ViewGroup');
    ViewGroup.addView.overload('android.view.View', 'int', 'android.view.ViewGroup$LayoutParams').implementation = function (view, index, params) {
        try {
            // 获取被添加视图的ID
            var viewId = view.getId();

            // 如果是目标视图,拦截添加操作
            if (viewId === TARGET_VIEW_ID) {
                console.log("[+] 拦截 third_ad_image (ID: 0x"+viewId.toString(16)+") 的添加操作");
                return; // 直接返回,不调用原方法
            }

            // 其他视图正常添加
            this.addView(view, index, params);
        } catch (e) {
            console.log('[-] Hook Error:', e);
        }
    };

    console.log('[+] Hook ViewGroup.addView() 注入成功');
});

至此去除弹窗与横幅图片

frida -U -l deletetupian.js com.zj.wuaipojif
image-20250511173522747
posted @ 2025-05-11 19:47  JKding233  阅读(184)  评论(0)    收藏  举报