解决Xposed框架拦截修改Build.MODEL手机型号失败问题

在使用Xposed框架拦截修改Build系列的静态值一直很顺利,一直到拦截修改MODEL手机机型这个静态变量的sh时候出现问题,博主发现,通过正常的途径以及采用映射都无法修改点手机机型,遂一直努力查找技术文档攻克,终于功夫不负有心人,解决了该问题。闲话少说,上代码。

博主具体参考一款插件“应用变量”来做讲解,具体的项目地址参考应用变量

package com.sollyu.android.appenv.helper;

import android.os.Build;
import android.support.annotation.RequiresApi;

import java.util.HashMap;

import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

/**
 * 作者: Sollyu
 * 时间: 16/10/20
 * 联系: sollyu@qq.com
 * 说明:
 */
public class XposedHookHelper {

    private static final String TAG = "AppEnv";

    public BuildImpl     Build     = null;
    public TelephonyImpl Telephony = null;
    public WifiImpl      Wifi      = null;
    public SettingsImpl  Settings  = null;

    private XC_LoadPackage.LoadPackageParam loadPackageParam = null;

    private static XposedHookHelper instances = null;

    @RequiresApi(api = android.os.Build.VERSION_CODES.CUPCAKE)
    private XposedHookHelper(XC_LoadPackage.LoadPackageParam loadPackageParam) {
        this.loadPackageParam = loadPackageParam;

        Build     = new BuildImpl();
        Telephony = new TelephonyImpl();
        Wifi      = new WifiImpl();
        Settings  = new SettingsImpl();
    }

    @RequiresApi(api = android.os.Build.VERSION_CODES.CUPCAKE)
    public static XposedHookHelper getInstances(XC_LoadPackage.LoadPackageParam loadPackageParam) {
        if (instances == null){
            instances = new XposedHookHelper(loadPackageParam);
        }
        return instances;
    }

    public XC_LoadPackage.LoadPackageParam getLoadPackageParam() {
        return loadPackageParam;
    }


    /**
     * android.os.Build 拦截
     */
    @SuppressWarnings("WeakerAccess")
    public class BuildImpl {
        public VersionImpl Version = new VersionImpl();

        public HashMap<String, String> hashMap = new HashMap<>();

        private BuildImpl() {
            XposedBridge.hookAllMethods(XposedHelpers.findClass("android.os.SystemProperties", getLoadPackageParam().classLoader), "get", new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    if (hashMap.containsKey(param.args[0].toString())) {
                        param.setResult(hashMap.get(param.args[0].toString()));
                    }
                }
            });
        }

        public void MANUFACTURER(String value) {
            XposedHelpers.setStaticObjectField(android.os.Build.class, "MANUFACTURER", value);
            hashMap.put("ro.product.manufacturer", value);
        }

        public void BRAND(String value) {
            XposedHelpers.setStaticObjectField(android.os.Build.class, "BRAND", value);
            hashMap.put("ro.product.brand", value);
        }

        public void BOOTLOADER(String value) {
            XposedHelpers.setStaticObjectField(android.os.Build.class, "BOOTLOADER", value);
            hashMap.put("ro.bootloader", value);
        }

        public void MODEL(String value) {
            XposedHelpers.setStaticObjectField(android.os.Build.class, "MODEL", value);
            hashMap.put("ro.product.model", value);
        }

        public void DEVICE(String value) {
            XposedHelpers.setStaticObjectField(android.os.Build.class, "DEVICE", value);
            hashMap.put("ro.product.device", value);
        }

        public void DISPLAY(String value) {
            XposedHelpers.setStaticObjectField(android.os.Build.class, "DISPLAY", value);
            hashMap.put("ro.build.display.id", value);
        }

        public void PRODUCT(String value) {
            XposedHelpers.setStaticObjectField(android.os.Build.class, "PRODUCT", value);
            hashMap.put("ro.product.name", value);
        }

        public void BOARD(String value) {
            XposedHelpers.setStaticObjectField(android.os.Build.class, "BOARD", value);
            hashMap.put("ro.product.board", value);
        }

        public void HARDWARE(String value) {
            XposedHelpers.setStaticObjectField(android.os.Build.class, "HARDWARE", value);
            hashMap.put("ro.hardware", value);
        }

        public void SERIAL(String value) {
            XposedHelpers.setStaticObjectField(android.os.Build.class, "SERIAL", value);
            hashMap.put("ro.serialno", value);
        }

        public void TYPE(String value) {
            XposedHelpers.setStaticObjectField(android.os.Build.class, "TYPE", value);
            hashMap.put("ro.build.type", value);
        }

        public void TAGS(String value) {
            XposedHelpers.setStaticObjectField(android.os.Build.class, "TAGS", value);
            hashMap.put("ro.build.tags", value);
        }

        public void FINGERPRINT(String value) {
            XposedHelpers.setStaticObjectField(android.os.Build.class, "FINGERPRINT", value);
            hashMap.put("ro.build.fingerprint", value);
        }

        public void USER(String value) {
            XposedHelpers.setStaticObjectField(android.os.Build.class, "USER", value);
            hashMap.put("ro.build.user", value);
        }

        public void HOST(String value) {
            XposedHelpers.setStaticObjectField(android.os.Build.class, "HOST", value);
            hashMap.put("ro.build.host", value);
        }

        public class VersionImpl {
            private VersionImpl() {
            }

            public void INCREMENTAL(String value) {
                XposedHelpers.setStaticObjectField(android.os.Build.VERSION.class, "INCREMENTAL", value);
                hashMap.put("ro.build.version.incremental", value);
            }

            public void RELEASE(String value) {
                XposedHelpers.setStaticObjectField(android.os.Build.VERSION.class, "RELEASE", value);
                hashMap.put("ro.build.version.release", value);
            }

            public void BASE_OS(String value) {
                XposedHelpers.setStaticObjectField(android.os.Build.VERSION.class, "BASE_OS", value);
                hashMap.put("ro.build.version.base_os", value);
            }

            public void SECURITY_PATCH(String value) {
                XposedHelpers.setStaticObjectField(android.os.Build.VERSION.class, "SECURITY_PATCH", value);
                hashMap.put("ro.build.version.security_patch", value);
            }

            public void SDK(String value) {
                XposedHelpers.setStaticObjectField(android.os.Build.VERSION.class, "SDK", value);
                hashMap.put("ro.build.version.sdk", value);
            }

            public void CODENAME(String value) {
                XposedHelpers.setStaticObjectField(android.os.Build.VERSION.class, "CODENAME", value);
                hashMap.put("ro.build.version.all_codenames", value);
            }

            public void SDK_INT(int value) {
                XposedHelpers.setStaticIntField(android.os.Build.VERSION.class, "SDK_INT", value);
            }
        }
    }

    @SuppressWarnings("WeakerAccess")
    public static class TelephonyImpl {
        private TelephonyImpl() {
        }

        public void getDeviceId(String value) {
            XposedBridge.hookAllMethods(android.telephony.TelephonyManager.class, "getDeviceId", new XC_ResultHook(value));
        }

        public void getDeviceSoftwareVersion(String value) {
            XposedBridge.hookAllMethods(android.telephony.TelephonyManager.class, "getDeviceSoftwareVersion", new XC_ResultHook(value));
        }

        public void getLine1Number(String value) {
            XposedBridge.hookAllMethods(android.telephony.TelephonyManager.class, "getLine1Number", new XC_ResultHook(value));
        }

        public void getMmsUAProfUrl(String value) {
            XposedBridge.hookAllMethods(android.telephony.TelephonyManager.class, "getMmsUAProfUrl", new XC_ResultHook(value));
        }

        public void getMmsUserAgent(String value) {
            XposedBridge.hookAllMethods(android.telephony.TelephonyManager.class, "getMmsUserAgent", new XC_ResultHook(value));
        }

        public void getNetworkCountryIso(String value) {
            XposedBridge.hookAllMethods(android.telephony.TelephonyManager.class, "getNetworkCountryIso", new XC_ResultHook(value));
        }

        public void getNetworkOperator(String value) {
            XposedBridge.hookAllMethods(android.telephony.TelephonyManager.class, "getNetworkOperator", new XC_ResultHook(value));
        }

        public void getNetworkOperatorName(String value) {
            XposedBridge.hookAllMethods(android.telephony.TelephonyManager.class, "getNetworkOperatorName", new XC_ResultHook(value));
        }

        public void getSimCountryIso(String value) {
            XposedBridge.hookAllMethods(android.telephony.TelephonyManager.class, "getSimCountryIso", new XC_ResultHook(value));
        }

        public void getSimOperator(String value) {
            XposedBridge.hookAllMethods(android.telephony.TelephonyManager.class, "getSimOperator", new XC_ResultHook(value));
        }

        public void getSimOperatorName(String value) {
            XposedBridge.hookAllMethods(android.telephony.TelephonyManager.class, "getSimOperatorName", new XC_ResultHook(value));
        }

        public void getSimSerialNumber(String value) {
            XposedBridge.hookAllMethods(android.telephony.TelephonyManager.class, "getSimSerialNumber", new XC_ResultHook(value));
        }

        public void getSubscriberId(String value) {
            XposedBridge.hookAllMethods(android.telephony.TelephonyManager.class, "getSubscriberId", new XC_ResultHook(value));
        }

        public void getCallState(int value) {
            XposedBridge.hookAllMethods(android.telephony.TelephonyManager.class, "getCallState", new XC_ResultHook(value));
        }

        public void getDataNetworkType(int value) {
            XposedBridge.hookAllMethods(android.telephony.TelephonyManager.class, "getDataNetworkType", new XC_ResultHook(value));
        }

        public void getDataState(int value) {
            XposedBridge.hookAllMethods(android.telephony.TelephonyManager.class, "getDataState", new XC_ResultHook(value));
        }

        public void getNetworkType(int value) {
            XposedBridge.hookAllMethods(android.telephony.TelephonyManager.class, "getNetworkType", new XC_ResultHook(value));
        }

        public void getPhoneCount(int value) {
            XposedBridge.hookAllMethods(android.telephony.TelephonyManager.class, "getPhoneCount", new XC_ResultHook(value));
        }

        public void getPhoneType(int value) {
            XposedBridge.hookAllMethods(android.telephony.TelephonyManager.class, "getPhoneType", new XC_ResultHook(value));
        }

        public void getSimState(int value) {
            XposedBridge.hookAllMethods(android.telephony.TelephonyManager.class, "getSimState", new XC_ResultHook(value));
        }
    }

    @SuppressWarnings("WeakerAccess")
    public static class WifiImpl {
        public InfoImpl Info = new InfoImpl();

        private WifiImpl() {
        }

        public void enableNetwork(boolean returnStatus) {
            XposedBridge.hookAllMethods(android.net.wifi.WifiManager.class, "enableNetwork", new XC_ResultHook(returnStatus));
        }

        public void disableNetwork(boolean returnStatus) {
            XposedBridge.hookAllMethods(android.net.wifi.WifiManager.class, "disableNetwork", new XC_ResultHook(returnStatus));
        }

        public void getWifiState(int returnStatus) {
            XposedBridge.hookAllMethods(android.net.wifi.WifiManager.class, "getWifiState", new XC_ResultHook(returnStatus));
        }

        public static class InfoImpl {
            private InfoImpl() {
            }

            public void getSSID(String value) {
                XposedBridge.hookAllMethods(android.net.wifi.WifiInfo.class, "getSSID", new XC_ResultHook(value));
            }

            public void getBSSID(String value) {
                XposedBridge.hookAllMethods(android.net.wifi.WifiInfo.class, "getBSSID", new XC_ResultHook(value));
            }

            public void getMacAddress(String value) {
                XposedBridge.hookAllMethods(android.net.wifi.WifiInfo.class, "getMacAddress", new XC_ResultHook(value));
            }

            public void getIpAddress(int value) {
                XposedBridge.hookAllMethods(android.net.wifi.WifiInfo.class, "getIpAddress", new XC_ResultHook(value));
            }

            public void getFrequency(int value) {
                XposedBridge.hookAllMethods(android.net.wifi.WifiInfo.class, "getFrequency", new XC_ResultHook(value));
            }

            public void getLinkSpeed(int value) {
                XposedBridge.hookAllMethods(android.net.wifi.WifiInfo.class, "getLinkSpeed", new XC_ResultHook(value));
            }
        }
    }

    @RequiresApi(api = android.os.Build.VERSION_CODES.CUPCAKE)
    @SuppressWarnings("WeakerAccess")
    public static class SettingsImpl {
        public SystemImpl System = new SystemImpl();

        private SettingsImpl() {
        }

        @SuppressWarnings("WeakerAccess")
        public static class SystemImpl {
            private HashMap<String, String> hashMap = new HashMap<>();

            @RequiresApi(api = android.os.Build.VERSION_CODES.CUPCAKE)
            private SystemImpl() {
                XposedBridge.hookAllMethods(android.provider.Settings.System.class, "getString", new XC_MethodHook() {
                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        if (param.args.length > 1 && param.args[1] != null && hashMap.containsKey(param.args[1].toString())) {
                            param.setResult(hashMap.get(param.args[1].toString()));
                        }
                    }
                });

                XposedBridge.hookAllMethods(android.provider.Settings.Secure.class, "getString", new XC_MethodHook() {
                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        if (param.args.length > 1 && param.args[1] != null && hashMap.containsKey(param.args[1].toString())) {
                            param.setResult(hashMap.get(param.args[1].toString()));
                        }
                    }
                });
            }

            public void getString(String keyName, String value) {
                hashMap.put(keyName, value);
            }
        }
    }

    private static class XC_ResultHook extends XC_MethodHook {
        private Object resultObject = null;

        XC_ResultHook(Object resultObject) {
            this.resultObject = resultObject;
        }

        @Override
        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
            if (resultObject != null)
                param.setResult(resultObject);
        }
    }
}

 以上代码是项目“应用变量”的XposedHookHelper.java文件

其中关键代码为:

使用了HashMap存放Build中的静态变量,然后通过判断HashMap中的键值是否存在,存在则去修改返回结果

XposedBridge.hookAllMethods(XposedHelpers.findClass("android.os.SystemProperties", getLoadPackageParam().classLoader), "get", new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    if (hashMap.containsKey(param.args[0].toString())) {
                        param.setResult(hashMap.get(param.args[0].toString()));
                    }
                }
            });

把MODEL值存放进HashMap

 public void MODEL(String value) {
            XposedHelpers.setStaticObjectField(android.os.Build.class, "MODEL", value);
            hashMap.put("ro.product.model", value);
        }

解析上面两句代码,我们可以得出:

”应用变量“首先通过setStaticObjectField()方法设置了自定义值,然后又通过setResult()方法修改了get方法的返回值,以此达到了修改Build.MODEL的目的。

看到这里是不是恍然大悟了呢?所以赶快去试试吧。

最后非常感谢项目”应用变量“的作者kingsollyu,如果使用该文章请标明出处!

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 如果你想通过 Xposed 框架对 ActivityThread.class 中的 currentActivityThread 方法对应的 ArtMethod 对象的 hotness_count_ 字段进行 hook,您需要在 Xposed 框架中编写一个模块,并通过 XposedBridge API 进行 hook。您需要在 Xposed 模块中通过 XposedHelpers.findAndHookMethod() 方法获取 currentActivityThread 方法,然后使用 XposedBridge.hookMethod() 方法对其进行 hook。在 hook 方法中,您可以通过反射获取 hotness_count_ 字段的值,并对其进行修改。 注意:在修改系统层代码(如 Android framework)的 hotness_count_ 字段时,请谨慎操作,以免造成系统不稳定。 ### 回答2: 想要通过Xposed框架hook安卓ActivityThread.class中的currentActivityThread方法对应的ArtMethod对象中的hotness_count_字段值,需要先了解一些相关知识。 Xposed框架是一款用于修改安卓系统的框架,它通过hook技术来实现对安卓应用的改造和扩展。在使用Xposed框架时,首先需要安装Xposed框架并激活,然后编写相应的模块来实现hook。 要hook ActivityThread.class中的currentActivityThread方法,可以通过Xposed的findAndHookMethod方法来实现。首先,我们在模块的初始化方法中使用该方法对currentActivityThread方法进行hook。在hook的回调函数中,我们可以获取到当前执行的ArtMethod对象。 要获取ArtMethod对象中的hotness_count_字段值,可以使用Java的反射机制来实现。首先,通过反射获取到ArtMethod类的声明,然后再通过反射获取到hotness_count_字段,并获取该字段的值。 具体代码如下: ```java import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedHelpers; public class MyXposedModule { public void initZygote() { XposedHelpers.findAndHookMethod("android.app.ActivityThread", null, "currentActivityThread", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { // 获取当前执行的ArtMethod对象 Object currentActivityThread = param.getResult(); // 获取ArtMethod类 Class<?> artMethodClass = XposedHelpers.findClass("java.lang.reflect.ArtMethod", currentActivityThread.getClass().getClassLoader()); // 获取hotness_count_字段 Object hotnessCount = XposedHelpers.getObjectField(currentActivityThread, "hotness_count_"); // 打印hotness_count_字段值 if (hotnessCount != null) { int hotnessCountValue = (int) hotnessCount; Log.d("MyXposedModule", "hotness_count_: " + hotnessCountValue); } } }); } } ``` 以上代码实现了对currentActivityThread方法的hook,获取到ArtMethod对象后再获取其中的hotness_count_字段并进行打印。 需要注意的是,Xposed框架的使用可能需要root权限,并且不同版本的安卓系统以及应用可能会有一些差异,可能需要根据实际情况进行相应的修改。 ### 回答3: 要想通过Xposed框架hook安卓ActivityThread.class中的currentActivityThread()方法对应的ArtMethod对象中的hotness_count_字段值,需要按照以下步骤进行: 首先,使用Xposed框架创建一个模块,在模块的init方法中进行hook操作。可以使用findAndHookMethod函数来hook currentActivityThread()方法。代码如下所示: ```java public class MyXposedModule implements IXposedHookLoadPackage { @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable { if (!lpparam.packageName.equals("com.android.systemui")) { return; } // 当加载的包是 com.android.systemui 时进行hook操作 XposedHelpers.findAndHookMethod("android.app.ActivityThread", lpparam.classLoader, "currentActivityThread", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { // 获取 currentActivityThread 方法的返回值(即 ActivityThread 对象) Object activityThreadObj = param.getResult(); // 获取 ActivityThread 类中的 mHotcness_count 字段 Field hotnessField = activityThreadObj.getClass().getDeclaredField("mHotness_count"); hotnessField.setAccessible(true); // 修改 mHotness_count 的值为你想要的值 hotnessField.setInt(activityThreadObj, 100); } }); } } ``` 上述代码中,我们通过hook currentActivityThread()方法获取了ActivityThread对象,并通过反射获取到该对象的mHotness_count字段,并将其值修改为100。 接下来,使用Android Studio或其他工具进行编译和打包,得到一个Xposed模块的apk文件。 最后,将生成的apk文件安装到Android设备上,并使用Xposed框架将该模块激活即可。当目标应用启动时,Xposed框架会自动调用我们编写的hook代码,从而成功修改ArtMethod对象中的hotness_count_字段值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值