安卓逆向--使用jadx-ai-mcp辅助分析某校园pro校园跑"

admin 2026-10-22 13:37:21 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

安卓逆向 -- 使用jadx-ai-mcp辅助分析某校园pro校园跑

Tonyha7
Tonyha7

逆向有你

2026年10月19日 10:04
河南

去阅读

介绍

笔者的学校又开始了新一轮的校园跑 这次换了一个校园跑的app

本着科技强国的思想 自然少不了对这个app的一顿研究

逆向

我们把数据发给ai 并且把我们的目标也加上

经过半个小时的分析 ai给出了如下代码

 复制代码 隐藏代码
publicclassFaceBypassHook {
    publicstaticvoidHook(ClassLoader classLoader) {
        Class<?> delegateClass = XposedHelpers.findClassIfExists(
                \"com.huachenjie.base.aliyun.detect_face.DetectFaceDelegate\",
                classLoader);

        if (delegateClass != null) {
            XposedBridge.hookAllMethods(delegateClass, \"r\", newXC_MethodHook() {
                @Override
                protectedvoidbeforeHookedMethod(MethodHookParam param)throws Throwable {
                    param.args[0] = true;
                    XposedBridge.log(\"Hooked DetectFaceDelegate.r -> 强制修改返回结果为 true\");
                }
            });

        /* (可选) 拦截上传对比方法,直接不执行网络请求并调用 r(true)
        XposedBridge.hookAllMethods(delegateClass, \"o\", new XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                XposedBridge.log(\"Hooked DetectFaceDelegate.o -> 拦截 compareFace 阻断上传\");
                // 反射调用 r(true) 制造成功假象
                XposedHelpers.callMethod(param.thisObject, \"r\", true);
                return null;
            }
        });
         */

            XposedBridge.hookAllMethods(delegateClass, \"p\", newXC_MethodReplacement() {
                @Override
                protected Object replaceHookedMethod(MethodHookParam param)throws Throwable {
                    XposedBridge.log(\"Hooked DetectFaceDelegate.p -> 拦截 detectLivingFace 阻断活体检验\");
                    // 反射调用 r(true) 制造成功假象
                    XposedHelpers.callMethod(param.thisObject, \"r\", true);
                    returnnull;
                }
            });
        }
    }
}

很搞笑的一点是 这个app的人脸检测是本地判断的

而且只判断了是否存在活体

经过测试 就算直接上传一个只有1x1像素的jpg图片也可以通过校验

 复制代码 隐藏代码
publicclassAntiDetectHook {
    publicstaticvoidHook(ClassLoader classLoader) {
        try {
            // 1. 绕过虚拟定位检测
            // 屏蔽 Android 6.0+ 的 isFromMockProvider API
            XposedHelpers.findAndHookMethod(Location.class, \"isFromMockProvider\", XC_MethodReplacement.returnConstant(false));

            // 屏蔽 Android 12+ 的 isMock API
            if (Build.VERSION.SDK_INT >= 31) {
                XposedHelpers.findAndHookMethod(Location.class, \"isMock\", XC_MethodReplacement.returnConstant(false));
            }

            // 拦截获取开发者选项中“允许模拟位置”的设置读取
            XposedHelpers.findAndHookMethod(Settings.Secure.class, \"getInt\", android.content.ContentResolver.class, String.class, int.class, newXC_MethodHook() {
                @Override
                protectedvoidbeforeHookedMethod(MethodHookParam param)throws Throwable {
                    Stringsetting= (String) param.args[1];
                    if (Settings.Secure.ALLOW_MOCK_LOCATION.equals(setting)) {
                        param.setResult(0); // 强制返回 0(未开启)
                    }
                }
            });

            // 过滤系统级原始定位上报的网络基站位置,强制只收受虚拟的 GPS
            try {
                XposedHelpers.findAndHookMethod(\"android.location.LocationManager\", classLoader, \"requestLocationUpdates\", String.class, long.class, float.class, \"android.location.LocationListener\", newXC_MethodHook() {
                    @Override
                    protectedvoidbeforeHookedMethod(MethodHookParam param)throws Throwable {
                        Stringprovider= (String) param.args[0];
                        if (\"network\".equals(provider)) {
                            // 遇到获取网络定位,直接将其篡改为无效,强迫系统/APP仅用我们注入的 GPS 数据
                            param.args[0] = \"passive\";
                        }
                    }
                });

                XposedHelpers.findAndHookMethod(\"android.location.LocationManager\", classLoader, \"getLastKnownLocation\", String.class, newXC_MethodHook() {
                    @Override
                    protectedvoidafterHookedMethod(MethodHookParam param)throws Throwable {
                        // 抑制“上一次所在位置”的提取。由于这个值常常是你未修改坐标前的真实宿舍点位,跳跃到操场会被算出几十公里而越界
                        param.setResult(null);
                    }
                });
            } catch (Throwable ignore) {}

            try {                // 新增:拦截高德地图定位的配置设置,强制限制它只使用设备传感器(纯 GPS),切断 Wi-Fi 和基站网络定位,防止“真假坐标互跳”
                Class<?> aMapLocationClientOptionClass = XposedHelpers.findClassIfExists(\"com.amap.api.location.AMapLocationClientOption\", classLoader);
                if (aMapLocationClientOptionClass != null) {
                    Class<?> aMapLocationModeEnum = XposedHelpers.findClassIfExists(\"com.amap.api.location.AMapLocationClientOption$AMapLocationMode\", classLoader);
                    if (aMapLocationModeEnum != null) {
                        try {
                            finalObjectdeviceSensorsMode= Enum.valueOf((Class<Enum>) aMapLocationModeEnum, \"Device_Sensors\");
                            XposedBridge.hookAllMethods(aMapLocationClientOptionClass, \"setLocationMode\", newXC_MethodHook() {
                                @Override
                                protectedvoidbeforeHookedMethod(MethodHookParam param)throws Throwable {
                                    if (deviceSensorsMode != null) {
                                        param.args[0] = deviceSensorsMode; // 强制指定成纯 GPS 模式
                                    }
                                }
                            });
                        } catch (Throwable t) {}
                    }
                }
                // 深度拦截高德地图 (AMap) SDK 以及自有封装业务对定位的真实坐标校验,从而绕过“已离开有效跑步范围/公里数0”的警告
                Class<?> aMapLocationClass = XposedHelpers.findClassIfExists(\"com.amap.api.location.AMapLocation\", classLoader);
                if (aMapLocationClass != null) {
                    XposedBridge.hookAllMethods(aMapLocationClass, \"isMock\", XC_MethodReplacement.returnConstant(false));
                    XposedBridge.hookAllMethods(aMapLocationClass, \"getTrustedLevel\", XC_MethodReplacement.returnConstant(1));
                    XposedBridge.hookAllMethods(aMapLocationClass, \"getErrorCode\", XC_MethodReplacement.returnConstant(0));
                    // [新增] 屏蔽卫星颗数和定位质量监测
                    XposedBridge.hookAllMethods(aMapLocationClass, \"getSatellites\", XC_MethodReplacement.returnConstant(12)); // 强行拉高卫星数,过检测 (>2颗)
                    XposedBridge.hookAllMethods(aMapLocationClass, \"getLocationType\", XC_MethodReplacement.returnConstant(1)); // 1 代表原生 GPS 定位返回结果
                    XposedBridge.hookAllMethods(aMapLocationClass, \"getAccuracy\", XC_MethodReplacement.returnConstant(5.0f)); // 精度拉高到 5米 绝佳状态
                    XposedBridge.hookAllMethods(aMapLocationClass, \"getSpeed\", newXC_MethodHook() {
                        @Override
                        protectedvoidafterHookedMethod(MethodHookParam param)throws Throwable {
                            floatspeed= (float) param.getResult();
                            if (speed <= 0.5f) {
                                param.setResult(2.5f); // 补2.5的底层配速防止被当作静止
                            }
                        }
                    });                }

                Class<?> hcjAddressInfo = XposedHelpers.findClassIfExists(\"huachenjie.sdk.map.lib_base.HCJAddressInfo\", classLoader);
                if (hcjAddressInfo != null) {
                    XposedBridge.hookAllMethods(hcjAddressInfo, \"isMock\", XC_MethodReplacement.returnConstant(false));
                    XposedBridge.hookAllMethods(hcjAddressInfo, \"getSatellites\", XC_MethodReplacement.returnConstant(12));
                    XposedBridge.hookAllMethods(hcjAddressInfo, \"getGpsStatus\", XC_MethodReplacement.returnConstant(1));
                    XposedBridge.hookAllMethods(hcjAddressInfo, \"getAccuracy\", XC_MethodReplacement.returnConstant(5.0f));
                    XposedBridge.hookAllMethods(hcjAddressInfo, \"getSpeed\", newXC_MethodHook() {
                        @Override
                        protectedvoidafterHookedMethod(MethodHookParam param)throws Throwable {
                            floatspeed= (float) param.getResult();
                            if (speed <= 0.5f) {
                                param.setResult(2.5f);
                            }
                        }
                    });
                }

                // 拦截应用层自身纪录点的对象
                Class<?> runLatLng = XposedHelpers.findClassIfExists(\"com.huachenjie.common.bean.RunLatLng\", classLoader);
                if (runLatLng != null) {
                    XposedBridge.hookAllMethods(runLatLng, \"getSatellites\", XC_MethodReplacement.returnConstant(12));
                    XposedBridge.hookAllMethods(runLatLng, \"isValid\", XC_MethodReplacement.returnConstant(true));
                    XposedBridge.hookAllMethods(runLatLng, \"getAccuracy\", XC_MethodReplacement.returnConstant(5.0f));
                }

                // 核心控制层:接管 DataComponent 新版拉取位置信息的方法 P0 (原为O0)
                Class<?> dataComponent = XposedHelpers.findClassIfExists(\"com.huachenjie.running.service.DataComponent\", classLoader);
                if (dataComponent != null) {
                    XposedBridge.hookAllMethods(dataComponent, \"P0\", newXC_MethodHook() {
                        @Override
                        protectedvoidafterHookedMethod(MethodHookParam param)throws Throwable {
                            ObjecthcjInfo= param.getResult();
                            if (hcjInfo != null) {
                                XposedHelpers.callMethod(hcjInfo, \"setSatellites\", 12);
                                XposedHelpers.callMethod(hcjInfo, \"setMock\", false);
                                XposedHelpers.callMethod(hcjInfo, \"setFromMockProvider\", false);
                                XposedHelpers.callMethod(hcjInfo, \"setAccuracy\", 5.0f);
                                XposedHelpers.callMethod(hcjInfo, \"setGpsStatus\", 1); // 设置 GPS 状态

                                floatspeed= (float) XposedHelpers.callMethod(hcjInfo, \"getSpeed\");
                                if (speed <= 0.5f) {
                                    XposedHelpers.callMethod(hcjInfo, \"setSpeed\", 2.5f);
                                }
                            }
                        }
                    });
                }

                // 【强制屏蔽地理围栏逻辑检测】如果上层仍然通过缓存的目标点(TargetPoints)判断你在围栏外,这里进行拦截
                Class<?> targetPointsClass = XposedHelpers.findClassIfExists(\"com.huachenjie.common.bean.TargetPoints\", classLoader);
                if (targetPointsClass != null) {
                    XposedBridge.hookAllMethods(targetPointsClass, \"isInFence\", XC_MethodReplacement.returnConstant(true));
                    XposedBridge.hookAllMethods(targetPointsClass, \"getIsInFence\", XC_MethodReplacement.returnConstant(true));
                    XposedBridge.hookAllMethods(targetPointsClass, \"isSensitiveFenceAdded\", XC_MethodReplacement.returnConstant(false));
                    XposedBridge.hookAllMethods(targetPointsClass, \"getIsSensitiveFenceAdded\", XC_MethodReplacement.returnConstant(false));
                }

                // 阻止 AutoPauseView 弹窗本身显示“越界”和 WIfi 报警,掩耳盗铃
                Class<?> autoPauseView = XposedHelpers.findClassIfExists(\"com.huachenjie.running.widget.AutoPauseView\", classLoader);
                if (autoPauseView != null) {
                    XposedBridge.hookAllMethods(autoPauseView, \"setLastedDuration\", newXC_MethodHook() {
                        @Override
                        protectedvoidbeforeHookedMethod(MethodHookParam param)throws Throwable {
                            intreason= (int) param.args[1];
                            // 去除 1 (越野报警) 和 2 (WiFi预警) 等相关的标志
                            param.args[1] = reason & ~3;
                        }
                    });
                }
            } catch (Throwable ignore) {}

            // [新增] Android原生地层级检测:卫星获取接口拦截,处理 GnssStatus/GpsStatus 检测不到卫星导致为0的问题
            try {
                Class<?> gnssStatusClass = XposedHelpers.findClassIfExists(\"android.location.GnssStatus\", classLoader);
                if (gnssStatusClass != null) {
                    XposedBridge.hookAllMethods(gnssStatusClass, \"getSatelliteCount\", XC_MethodReplacement.returnConstant(12));
                }
            } catch (Throwable ignore) {}

            // 拦截底层系统本身 Location 附加数据的卫星情况
            XposedHelpers.findAndHookMethod(Location.class, \"getExtras\", newXC_MethodHook() {
                @Override
                protectedvoidafterHookedMethod(MethodHookParam param)throws Throwable {
                    android.os.Bundleextras= (android.os.Bundle) param.getResult();
                    if (extras == null) {
                       extras = newandroid.os.Bundle();
                    }
                    extras.putInt(\"satellites\", 12);
                    param.setResult(extras);
                }
            });

            // 2. 绕过基本的 Root 检测(隐藏常见的su执行文件)
            XposedHelpers.findAndHookMethod(File.class, \"exists\", newXC_MethodHook() {
                @Override
                protectedvoidbeforeHookedMethod(MethodHookParam param)throws Throwable {
                    Filefile= (File) param.thisObject;
                    Stringpath= file.getAbsolutePath();
                    if (path != null && (path.endsWith(\"/su\") || path.contains(\"magisk\") || path.contains(\"xposed\"))) {
                        param.setResult(false); //笔者: 这玩意真的有用吗(不是)
                    }
                }
            });

            XposedBridge.log(\"★[XXXX校园] 防检测机制(Root/虚拟定位)Hook 成功\");
        } catch (Throwable t) {
            XposedBridge.log(\"★[XXXX校园] 防检测机制 Hook 异常: \" + t.getMessage());
        }
    }
}

我们乘胜追击 让步频模拟等功能也一并实现

 复制代码 隐藏代码
publicclassSensorMockHook {
    privatestaticintmockStepCount=0;
    privatestaticTimerstepTimer=null;

    publicstaticvoidHook(ClassLoader classLoader) {
        try {
            // 拦截注册传感器监听器,捕获App对步数和加速度传感器的监听
            XposedHelpers.findAndHookMethod(SensorManager.class, \"registerListener\",
                    SensorEventListener.class, Sensor.class, int.class, newXC_MethodHook() {
                        @Override
                        protectedvoidafterHookedMethod(MethodHookParam param)throws Throwable {
                            SensorEventListenerlistener= (SensorEventListener) param.args[0];
                            Sensorsensor= (Sensor) param.args[1];

                            if (sensor == null || listener == null) return;

                            inttype= sensor.getType();
                            // 针对计步器和计步检测器进行模拟
                            if (type == Sensor.TYPE_STEP_COUNTER || type == Sensor.TYPE_STEP_DETECTOR) {
                                XposedBridge.log(\"★[XXXX校园] 拦截到步数传感器注册开始模拟步频\");
                                startStepSimulation(listener, sensor);
                            }
                        }
                    });

            XposedHelpers.findAndHookMethod(SensorManager.class, \"unregisterListener\",
                    SensorEventListener.class, Sensor.class, newXC_MethodHook() {
                        @Override
                        protectedvoidafterHookedMethod(MethodHookParam param)throws Throwable {
                            stopStepSimulation();
                        }
                    });
            XposedBridge.log(\"★[XXXX校园] 步频模拟机制 Hook 成功\");
        } catch (Throwable t) {
            XposedBridge.log(\"★[XXXX校园] 传感器步频模拟 Hook 异常: \" + t.getMessage());
        }
    }

    privatestaticvoidstartStepSimulation(final SensorEventListener listener, final Sensor sensor) {
        if (stepTimer != null) return;
        stepTimer = newTimer();
        // 模拟正常跑步步频:约每秒 2.5 步 (也就是 150 步/分钟)
        stepTimer.scheduleAtFixedRate(newTimerTask() {
            @Override
            publicvoidrun() {
                mockStepCount += 2;
                sendFakeSensorEvent(listener, sensor, mockStepCount);
            }
        }, 0, 800);
    }

    privatestaticvoidstopStepSimulation() {
        if (stepTimer != null) {
            stepTimer.cancel();
            stepTimer = null;
        }
    }

    // 构造伪造的 SensorEvent 并通知 App
    privatestaticvoidsendFakeSensorEvent(SensorEventListener listener, Sensor sensor, int steps) {
        try {
            // 通过反射实例化系统保护的 SensorEvent
            SensorEventevent= (SensorEvent) SensorEvent.class.getDeclaredConstructors()[0].newInstance(1);
            event.sensor = sensor;
            event.accuracy = SensorManager.SENSOR_STATUS_ACCURACY_HIGH;
            event.timestamp = System.nanoTime();
            event.values[0] = steps;

            listener.onSensorChanged(event);
        } catch (Throwable e) {
            // 忽略报错
        }
    }
}

后续还实现了一些小功能 比如让app获取不到WiFi等功能 这里就不展开了

最后 我们找一个带摇杆/模拟路线的虚拟定位软件就可以愉快地开跑了

总结

AI真是太好用了

遇到问题/解决不了的问题 可以直接带着LSPosed的模块日志和问题现象去问ai 重复几次即可解决

·今 日 推 荐·

---
    安卓逆向--使用jadx-ai-mcp辅助分析某校园pro校园跑" 网络安全文章

    安卓逆向--使用jadx-ai-mcp辅助分析某校园pro校园跑"

    本文介绍使用jadx-ai-mcp辅助分析某校园跑APP的安卓逆向实战。作者针对易盾加固的APP,通过配置jadx-ai-mcp插件与服务器,创建Xposed模块Hook应用加载的ClassLoader,拦截并分析真实上传的跑步数据,包括位置、步频、人脸验证等信息,为后续逆向修改做准备。文章提供了具体配置步骤和代码示例,具有较强的可操作性。
    【实战复盘】Hackthebox-ProlabsMythicalCHAIN双域渗透全链:从ESC4到跨林信任再到SQL提权" 网络安全文章

    【实战复盘】Hackthebox-ProlabsMythicalCHAIN双域渗透全链:从ESC4到跨林信任再到SQL提权"

    本文复盘HacktheboxProlabsMythicalCHAIN双域渗透全链实战,从已控DC01的beacon出发,经rsync匿名读取获取KeePass库并破解弱口令,利用ESC4将证书模板转化为ESC1,并绕过KB5014754强映射限制(SANURISID),获取域管权限;随后导出跨林信任密钥,利用信任账户进入EU域,最终通过MSSQLTRUSTWORTHY与SeImpersonate提权至SYSTEM。文章提供完整命令形态与防御视角,强调授权环境与脱敏原则,实操与教学价值高。
    你刷的每条广告,可能都是一次零点击黑客攻击" 网络安全文章

    你刷的每条广告,可能都是一次零点击黑客攻击"

    CitizenLab披露名为AdFection的零点击攻击,以色列公司Discover-Tech伪装成正规广告商,通过在线广告供应链分发Candiru等雇佣间谍软件,用户无需点击即可被感染,影响半岛电视台、美国国防部等敏感机构。文章建议及时打补丁、部署移动威胁防护、监控异常流量、限制广告追踪并加强供应商尽调,强调监管需介入修补系统性风险。
    评论:0   参与:  0