天津地铁app环境检测

查看 60|回复 10
作者:KillLog   
该帖子仅供学习
用root设备进入app会提示下图


IMG_20250216_101729.png (12.04 KB, 下载次数: 0)
下载附件
2025-2-16 10:22 上传

这个软件的提示词过于简单了,没有进行加密什么的
直接在dex里搜关键词即可


a.png (23.6 KB, 下载次数: 0)
下载附件
2025-2-16 10:21 上传

我们进入判断具体分析一下


b.png (58.78 KB, 下载次数: 0)
下载附件
2025-2-16 10:23 上传

一共三个函数
每个函数判断不同
第一个函数是通过判断是获取的手机信息(System/build.prop文件)
一般root后的设备其他root特征便是ro.system.build.tags=text-keys
第二个函数是通过判断文件是否存在
其中判断的文件都有:
/system/app/Superuser.apk,/sbin/su,/system/bin/su,/system/xbin/su,/data/local/xbin/su,/data/local/bin/su,/system/sd/xbin/su,/system/bin/failsafe/su,/data/local/su,/su/bin/su这些文件
如果设备进行Root,会存在
第三个函数则是通过执行shell命令
检查设备上是否存在 su可执行文件,判断是否是Root设备
那么知道这些了我们很好去隐藏,但是也可以进行hook处理
我们先hook第一个函数的检测他是获取的Build.TAGS
通过查看android.os.Build类TAGS字段是通过
[color=]public static final
String
TAGS = getString(
[color=]"ro.build.tags"
);
那么去只要去hookgetString即可正常的TAGS是release-keys
所以我们可以这样hook(mumu模拟器和我自己的root设备都是release-keys无法进行测试,请各位佬自行测试)
[Java] 纯文本查看 复制代码XposedHelpers.findAndHookMethod(Build.class, "getString", String.class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                String str=(String) param.args[0];
                XposedBridge.log("输出str:"+str);
                if (str.equals("ro.build.tags")){
                    XposedBridge.log("输出key:"+param.getResult());
                    param.setResult("release-keys");
                }
            }
        });第二个函数,我们可以去hookFile构造类当传入的路径是上面那些文件路径,则替换成一个不存在的文件路径即可或者是hook exists函数,那么怎么判断当前传入的路径我们可以查看File类代码,通过构造参数看出


d.png (30.46 KB, 下载次数: 0)
下载附件
2025-2-16 11:46 上传

这个类的path字段储存的路径所以我们可以直接获取exists函数当前实例的path然后判断是否是想hook的实例,然后返回一个false,不存在文件[Java] 纯文本查看 复制代码XposedHelpers.findAndHookMethod(File.class, "exists", new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                String path=(String) XposedHelpers.getObjectField(param.thisObject,"path");
                if (path.equals("/system/app/Superuser.apk")||path.equals("/sbin/su")||path.equals("/system/bin/su")||path.equals("/system/xbin/su")||path.equals("/data/local/xbin/su")||path.equals("/data/local/bin/su")||path.equals("/system/sd/xbin/su")||path.equals("/system/bin/failsafe/su")||path.equals("/data/local/su")||path.equals("/su/bin/su")) {
                param.setResult(false);
                }
            }
        });下面看第三个函数我们要怎么hook呢直接hook Runtime类的exec函数
[Java] 纯文本查看 复制代码XposedHelpers.findAndHookMethod(Runtime.class, "exec", String[].class, new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                super.beforeHookedMethod(param);
                String[] str=(String[]) param.args[0];
                if (Arrays.asList(str).contains("su")){
                    param.args[0]=new String[]{"echo", "-n"};
                }
            }
        });替换他的执行命令,新的指令返回的InputStream是空的然后我们在打开软件发现root提示已经没有了

函数, 下载次数

穿越蓝天   

isDeviceRooted直接返回false更简洁
Mysky6   

没那么复杂,直接hook 第一个函数isDeviceRooted的返回值就行
Java.perform(function () {
    var RootUtil = Java.use('com.bwton.tjmetro.util.RootUtil'); // 替换为实际的类名
    RootUtil.isDeviceRooted.implementation = function () {
        console.log('Hooked isDeviceRooted');
        return false; // 修改返回值为 falseRootUtil
    };
});
oknew3567   

感谢分享
Some   

感谢分享
fujita731   

通用,好想法。
三滑稽甲苯   

北京地铁亿通行能搞吗?
编程天下   

直接 shamiko 可以过检测吗
reficulx   

大佬,请教一下你的hook代码,是通过什么hook的,怎样hook的?
武之舞   

这个软件做得跟屎一样,满屏幕的广告,幸亏最近天津地铁跟支付宝合作了,过去坐地铁只能用这个支付
您需要登录后才可以回帖 登录 | 立即注册

返回顶部