Xposed Hook带特定参数的方法时遇参数冲突与类型转换错误
解决方案:正确Hook SystemProperties.get以修改设备信息
核心问题分析
- 修改
param.args[0]会强制所有get调用查询同一个key,而SystemProperties的get存在多个重载(如返回int/boolean的版本),原方法会将查询结果转为对应类型,返回字符串给期望整数的调用时必然抛出NumberFormatException。 - 同时使用
findAndHookMethod和hookAllMethods会触发钩子冲突,同一方法被多个钩子处理导致逻辑混乱。 - 之前获取参数的方式错误:
Arrays.copyOf强制转成String[]会在args包含非String类型(如int默认值)时出错,直接取args[0]转为String即可。
正确实现代码
import de.robv.android.xposed.XC_MethodReplacement; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import java.lang.reflect.Method; public class DeviceInfoHook { public static void handleLoadPackage(ClassLoader classLoader) throws Throwable { Class<?> systemPropertiesClass = Class.forName("android.os.SystemProperties", false, classLoader); // Hook所有get方法重载,避免钩子冲突 XposedBridge.hookAllMethods(systemPropertiesClass, "get", new XC_MethodReplacement() { @Override protected Object replaceHookedMethod(MethodHookParam param) throws Throwable { Method method = param.method; String key = (String) param.args[0]; Class<?> returnType = method.getReturnType(); // 根据key返回对应类型的自定义值 switch (key) { case "ro.build.id": return "JZO54K"; case "ro.build.display.id": return "JZO54K.I739KEAMF1"; case "ro.build.version.incremental": return "I739KEAMF1"; case "ro.build.version.sdk": return returnType == int.class ? 31 : "31"; case "ro.build.version.codename": return "REL"; case "ro.build.version.release": return "12"; case "ro.build.type": return "user"; case "ro.build.user": return "se.infra"; case "ro.build.host": return "S0210-08"; case "ro.build.tags": return "release-keys"; case "ro.product.model": return "SCH-I739"; case "ro.product.brand": return "samsung"; case "ro.product.name": return "kyleplusctc"; case "ro.product.device": return "kyleplusctc"; case "ro.product.board": return "MSM8625"; case "ro.product.cpu.abi": return "armeabi-v7a"; case "ro.product.cpu.abi2": return "armeabi"; case "ro.product_ship": return returnType == boolean.class ? true : "true"; case "ro.product.manufacturer": return "samsung"; case "ro.product.locale.language": return "zh"; case "ro.product.locale.region": return "CN"; case "ro.board.platform": return "msm7627a"; case "ro.build.product": return "kyleplusctc"; case "ro.build.description": return "kyleplusctc-user 4.1.2 JZO54K I739KEAMF1 release-keys"; case "ro.build.fingerprint": return "samsung/kyleplusctc/kyleplusctc:4.1.2/JZO54K/I739KEAMF1:user/release-keys"; case "ro.build.characteristics": return "china_wlan,china_cdma"; case "ro.build.PDA": return "I739KEAMF1"; case "ro.build.hidden_ver": return "I739KEAMF1"; case "ro.build.changelist": return returnType == int.class ? 1283033 : "1283033"; case "ro.opengles.version": return returnType == int.class ? 131072 : "131072"; case "ro.use_data_netmgrd": return returnType == boolean.class ? true : "true"; case "ro.bluetooth.request.master": return returnType == boolean.class ? true : "true"; case "ro.qualcomm.bluetooth.ftp": return returnType == boolean.class ? true : "true"; case "ro.qualcomm.bluetooth.sap": return returnType == boolean.class ? true : "true"; case "ro.bluetooth.remote.autoconnect": return returnType == boolean.class ? true : "true"; case "ro.config.ehrpd": return returnType == boolean.class ? true : "true"; case "ro.qualcomm.cabl": return returnType == int.class ? 1 : "1"; case "ro.fm.analogpath.supported": return returnType == boolean.class ? true : "true"; case "ro.fm.transmitter": return returnType == boolean.class ? false : "false"; case "ro.fm.mulinst.recording.support": return returnType == boolean.class ? false : "false"; case "ro.emmc.sdcard.partition": return returnType == int.class ? 18 : "18"; case "ro.screen.layout": return "normal"; case "ro.staticwallpaper.pixelformat": return "RGB_565"; case "ro.max.fling_velocity": return returnType == int.class ? 4000 : "4000"; case "ro.telephony.default_network": return returnType == int.class ? 10 : "10"; case "ro.cdma.ecmexittimer": return returnType == int.class ? 0 : "0"; case "ro.config.combined_signal": return returnType == boolean.class ? true : "true"; case "ro.kernel.qemu": return returnType == int.class ? 0 : "0"; case "ro.carrier": return "unknown"; case "ro.com.google.clientidbase": return "android-samsung"; case "ro.ril.hsxpa": return returnType == int.class ? 1 : "1"; case "ro.ril.gprsclass": return returnType == int.class ? 10 : "10"; case "ro.adb.qemud": return returnType == int.class ? 1 : "1"; case "ro.setupwizard.mode": return "OPTIONAL"; case "ro.debuggable": return returnType == int.class ? 0 : "0"; case "ro.secure": return returnType == int.class ? 1 : "1"; default: // 非自定义key,调用原方法返回默认值 return XposedHelpers.callMethod(null, method.getName(), param.args); } } }); } }
关键优化点
- 单一钩子处理所有重载:用
hookAllMethods覆盖get的所有版本,避免多个钩子冲突。 - 区分返回类型:根据当前方法的返回类型(int/boolean/String)返回对应类型的自定义值,彻底解决类型转换异常。
- 正确获取参数:直接取
param.args[0]转为String,避免强制转换数组导致的类型错误。 - 保留原有逻辑:非自定义key直接调用原方法返回,不破坏系统原有行为。
内容的提问来源于stack exchange,提问作者Kostia
相关产品推荐
相关产品推荐

