Developing Your Own Custom ROM Software with Xposed Framework

Author ForumAccount: Flying Ugly Duck

In the previous article “Teaching My Brother Android Reverse Engineering 14 – Writing Basic Custom ROM Code 02”, I introduced you to the process of customizing ROMs, set up the basic code for customization, and for storing customization parameters, we used SharedPreferences. I created a one-click new device button on the interface. When you click the one-click new device button, it will randomly generate IMEI data and store it in an XML file. Then the Xposed code hooks into the getDeviceId function and sets the return value to the value read from the XML file, thus completing the modification of the IMEI. Regarding the interface, I also wrote a rough version in the last lesson, and you can write your own interface based on the functions you want to implement. In the previous two lessons, we configured the Xposed development environment and wrote the first demo for customizing ROMs. In this lesson, I will introduce you to the overall customization of ROMs, as well as how to find and write customization points. You either learn or you don’t learn! There is no middle ground between learning and not learning. If you don’t study, just give up; if you choose to study, you must study seriously! –Advantages and Disadvantages of Xposed Custom ROMAdvantagesEasy to use, low time cost required.DisadvantagesIt can be easily detected, and you can only operate at the Java layer. Functions at the native layer, kernel layer, and some C library functions cannot be modified. For example, libc functions like open, fopen, access, rename, Unix’s popen function, and some C and kernel layer structures that obtain device information cannot be modified through Xposed. So what are the solutions if you want to make a good custom ROM? 1. Use Xposed in conjunction with tools that can hook into SO layer functions like Inlinehook, Frida, etc. 2. Targeted modifications, reverse engineer protocol data, and use Xposed to simulate data packets. 3. Customize the Android system and make global modifications.1. Introduction to Customization Points1. Hardware Information: Unique identifiers for the phone such as IMEI, Android version, serial number, phone brand, phone model, manufacturer, Bluetooth name, Bluetooth MAC address, system version, version name, development code name, source control version number, compilation type, CPU architecture, radio firmware version, device version number, motherboard name, bootloader version number, device parameters, device address, product name, ROM name, hardware name, fingerprint, developer ROM compilation user, and the time the device’s ROM was generated…..2. SIM Card Information 3. Bluetooth Information 4. User Agent Information 5. Battery Level 5. Boot Time 6. Phone Memory Information 7. Screen Size 8. Sensors 9. Location Base Station Information 10. Wi-Fi Information 11. File Information 12. Environmental Detection 13. Device Information Authenticity Detection……Seeing so much information, you should have questions. How do we find these points mentioned above?2. Finding Customization Points1. Search for Xposed custom ROM code on search engines like Baidu or Google; there are also some open-source Xposed custom ROM codes on GitHub that you can refer to. 2. Reverse engineer some apps to see how they obtain device information and how they detect environmental information, so as to improve the customization code accordingly. 3. Study and analyze the Android source code to find all points that can obtain device information. You should know that large companies start their security research from studying the Android source code.3. Writing Customization Code1. Since the amount of customization code is quite large, we will first write an abstract class that inherits from XC_MethodHook, and later hook classes can inherit from this class.MethodHook.java

public abstract class MethodHook extends XC_MethodHook {        protected String mpackageName;        protected ClassLoader mclassLoader;        protected DeviceInfoModel deviceInfoModel;        public MethodHook(XC_LoadPackage.LoadPackageParam paramLoadPackageParam, DeviceInfoModel deviceInfoModel)        {            this.mpackageName = paramLoadPackageParam.packageName;            this.mclassLoader = paramLoadPackageParam.classLoader;            this.deviceInfoModel = deviceInfoModel;        }    @Override    protected void afterHookedMethod(MethodHookParam param) throws Throwable {        super.afterHookedMethod(param);    }    public void hookMethodByClassMethodName(String paramString, String paramString2)    {        try        {            for (Method localMethod : XposedHelpers.findClass(paramString, this.mclassLoader).getDeclaredMethods())                if ((localMethod.getName().equals(paramString2)) && (!Modifier.isAbstract(localMethod.getModifiers())))                {                    localMethod.setAccessible(true);                    XposedBridge.hookMethod(localMethod, this);                }        }        catch (Throwable localThrowable)        {            Log.e("xposed-MethodHook", "hookMethodByClassMethodName Exception " + paramString);        }    }    public void hookMethodByClassMethodName(String paramString1, String paramString2, Object[] paramArrayOfObject)    {        try        {            Object[] arrayOfObject = new Object[1 + paramArrayOfObject.length];            for (int i = 0; i < arrayOfObject.length; i++)            {                if (i == -1 + arrayOfObject.length)                {                    arrayOfObject[(-1 + arrayOfObject.length)] = this;                    XposedHelpers.findAndHookMethod(paramString1, this.mclassLoader, paramString2, arrayOfObject);                    return;                }                arrayOfObject[i] = paramArrayOfObject[i];            }        }        catch (Throwable localThrowable)        {            Log.e("xposed-MethodHook", "addHookMethodWithParms Exception " + paramString1);        }    }     public void hookMethodByClassMethodName(String paramString, Object[] paramArrayOfObject)    {        try        {            Object[] arrayOfObject = new Object[1 + paramArrayOfObject.length];            for (int i = 0; i < arrayOfObject.length; i++)            {                if (i == -1 + arrayOfObject.length)                {                    arrayOfObject[(-1 + arrayOfObject.length)] = this;                    XposedHelpers.findAndHookConstructor(paramString, this.mclassLoader, arrayOfObject);                    return;                }                arrayOfObject[i] = paramArrayOfObject[i];            }        }        catch (Throwable localThrowable)        {           Log.e("xposed-MethodHook", "addHookConWithParms Exception " + paramString);        }    }     public void addHook(String paramString)    {        try        {            for (Constructor localConstructor : XposedHelpers.findClass(paramString, this.mclassLoader).getDeclaredConstructors())                if (Modifier.isPublic(localConstructor.getModifiers()))                    XposedBridge.hookMethod(localConstructor, this);        }        catch (Throwable localThrowable)        {            Log.e("Xhook", "addHook exception", localThrowable);        }    }    public static Field setAccessible(Object arg4, String arg5) {        Field[] v4 = arg4.getClass().getDeclaredFields();        int v0 = v4.length;        int v1;        for(v1 = 0; v1 < v0; ++v1) {            Field v2 = v4[v1];            v2.setAccessible(true);            if(v2.getType().toString().endsWith(arg5)) {                return v2;            }        }        return null;    }}

2.BuildHook.javaThis contains modifications to some hardware information of the phone and modifications to Android system properties, but the downside is that many large companies detect the SystemProperties’ get method by calling the underlying native_get method, which requires other methods for modification.

public class BuildHook extends MethodHook{    public BuildHook(XC_LoadPackage.LoadPackageParam paramLoadPackageParam, DeviceInfoModel deviceInfoModel, final Context context) {        super(paramLoadPackageParam, deviceInfoModel);        hookMethodByClassMethodName("android.os.SystemProperties", "set");        hookMethodByClassMethodName("android.os.SystemProperties", "get");        //hookMethodByClassMethodName("android.os.SystemProperties", "getString");        hookMethodByClassMethodName(Settings.System.class.getName(), "putStringForUser");        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) {            hookMethodByClassMethodName(Settings.Secure.class.getName(), "putStringForUser");        }        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {            hookMethodByClassMethodName(Settings.Global.class.getName(), "putStringForUser");        }        hookMethodByClassMethodName(Settings.System.class.getName(), "getStringForUser");        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) {            hookMethodByClassMethodName(Settings.Secure.class.getName(), "getStringForUser");        }        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {            hookMethodByClassMethodName(Settings.Global.class.getName(), "getStringForUser");        }        hookMethodByClassMethodName("android.provider.Settings$NameValueCache", "getStringForUser");    }     @SuppressLint("SuspiciousIndentation")    private void setBuilds() {        XposedHelpers.setStaticObjectField(Build.class, "BOOTLOADER", "unknown");        if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildBrand()))            XposedHelpers.setStaticObjectField(Build.class, "BRAND", this.deviceInfoModel.getBuildBrand());        if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildBoard()))            XposedHelpers.setStaticObjectField(Build.class, "BOARD", this.deviceInfoModel.getBuildBoard());        if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildModel()))            XposedHelpers.setStaticObjectField(Build.class, "MODEL", this.deviceInfoModel.getBuildModel());        if (!TextUtils.isEmpty(this.deviceInfoModel.getDisplayId()))            XposedHelpers.setStaticObjectField(Build.class, "DISPLAY", this.deviceInfoModel.getDisplayId());        if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildProduct()))            XposedHelpers.setStaticObjectField(Build.class, "PRODUCT", this.deviceInfoModel.getBuildProduct());        if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildManufacturer()))            XposedHelpers.setStaticObjectField(Build.class, "MANUFACTURER", this.deviceInfoModel.getBuildManufacturer());        if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildDevice()))            XposedHelpers.setStaticObjectField(Build.class, "DEVICE", this.deviceInfoModel.getBuildDevice());        if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildRelease()))            XposedHelpers.setStaticObjectField(Build.VERSION.class, "RELEASE", this.deviceInfoModel.getBuildRelease());        if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildSdk()))            XposedHelpers.setStaticObjectField(Build.VERSION.class, "SDK", this.deviceInfoModel.getBuildSdk());        if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildFingerprint()))            XposedHelpers.setStaticObjectField(Build.class, "FINGERPRINT", this.deviceInfoModel.getBuildFingerprint());        if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildHardware()))            XposedHelpers.setStaticObjectField(Build.class, "HARDWARE", this.deviceInfoModel.getBuildHardware());        if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildCodename()))            XposedHelpers.setStaticObjectField(Build.VERSION.class, "CODENAME", this.deviceInfoModel.getBuildCodename());        if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildIncremental()))            XposedHelpers.setStaticObjectField(Build.VERSION.class, "INCREMENTAL", this.deviceInfoModel.getBuildIncremental());        if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildHost()))            XposedHelpers.setStaticObjectField(Build.class, "HOST", this.deviceInfoModel.getBuildHost());        if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildId()))            XposedHelpers.setStaticObjectField(Build.class, "ID", this.deviceInfoModel.getBuildId());        if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildType()))            XposedHelpers.setStaticObjectField(Build.class, "TYPE", this.deviceInfoModel.getBuildType());        if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildUser()))            XposedHelpers.setStaticObjectField(Build.class, "USER", this.deviceInfoModel.getBuildUser());        if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildSerialno()))            XposedHelpers.setStaticObjectField(Build.class, "SERIAL", this.deviceInfoModel.getBuildSerialno());        if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildTags()))            XposedHelpers.setStaticObjectField(Build.class, "TAGS", this.deviceInfoModel.getBuildTags());        if (this.deviceInfoModel.getBuildUtc() > 0L)            XposedHelpers.setStaticObjectField(Build.class, "TIME", Long.valueOf(this.deviceInfoModel.getBuildUtc()));         if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildAbi())){            XposedHelpers.setStaticObjectField(Build.class, "CPU_ABI", this.deviceInfoModel.getBuildAbi());        }         if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildAbi2())){            XposedHelpers.setStaticObjectField(Build.class, "CPU_ABI2", this.deviceInfoModel.getBuildAbi2());        }        if (!TextUtils.isEmpty(this.deviceInfoModel.getBuildSdk())){            if(Integer.parseInt(this.deviceInfoModel.getBuildSdk())<26){                XposedHelpers.setStaticIntField(Build.VERSION.class, "SDK_INT", Integer.parseInt(this.deviceInfoModel.getBuildSdk()));            }        }        if (!TextUtils.isEmpty(this.deviceInfoModel.getSecurity_patch())){            XposedHelpers.setStaticObjectField(Build.VERSION.class, "SECURITY_PATCH", this.deviceInfoModel.getSecurity_patch());        }    }     public static Object IIl1lIIlll(DeviceInfoModel arg4, String arg5) {        if("ro.product.model".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildModel())) {                return arg4.getBuildModel();             }        }         if("ro.boot.serialno".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getSerialno())) {                Log.i("TestYY", "ro.boot.serialno");                return arg4.getSerialno();            }        }          else if("ro.build.id".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildId())) {                return arg4.getBuildId();            }        }        else if("ro.build.display.id".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getDisplayId())) {                return arg4.getDisplayId();            }        }        else if("ro.build.type".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildType())) {                return arg4.getBuildType();            }        }        else if("ro.build.user".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildUser())) {                return arg4.getBuildUser();            }        }        else if("ro.build.host".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildHost())) {                return arg4.getBuildHost();            }        }        else if("ro.build.tags".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildTags())) {                return arg4.getBuildTags();            }        }        else if("ro.product.brand".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildBrand())) {                return arg4.getBuildBrand();            }        }        else if("ro.product.device".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildDevice())) {                return arg4.getBuildDevice();            }        }        else if("ro.product.board".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildBoard())) {                return arg4.getBuildBoard();            }        }        else if("ro.product.name".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildName())) {                return arg4.getBuildName();            }        }        else if("ro.product.manufacturer".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildManufacturer())) {                return arg4.getBuildManufacturer();            }        }        else if("ro.hardware".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildHardware())) {                return arg4.getBuildHardware();            }        }        else if("c".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildSerialno())) {                return arg4.getBuildSerialno();            }        }        else if("ro.build.version.incremental".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildIncremental())) {                return arg4.getBuildIncremental();            }        }        else if("ro.build.version.release".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildRelease())) {                return arg4.getBuildRelease();            }        }        else if("ro.build.version.sdk".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildSdk())) {                return arg4.getBuildSdk();            }        }        else if("ro.build.version.codename".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildCodename())) {                return arg4.getBuildCodename();            }        }        else if("ro.build.fingerprint".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildFingerprint())) {                return arg4.getBuildFingerprint();            }        }        else if("ro.build.date.utc".equals(arg5) && arg4.getBuildUtc() > 0) {                return Long.valueOf(arg4.getBuildUtc());            }        }        else if("gsm.operator.numeric".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getSimOperator())) {                return arg4.getSimOperator();            }        }        else if(!TextUtils.isEmpty(((CharSequence)arg5)) && (arg5.contains("recovery_id"))) {            return arg4.getRecoveryId();        }         else if(("gsm.operator.numeric".equals(arg5)) || ("gsm.sim.operator.numeric".equals(arg5)) || ("gsm.apn.sim.operator.numeric".equals(arg5))) {            if(TextUtils.isEmpty(arg4.getSimOperator())) {                return arg4.getSimOperator();            }        }          else if("gsm.operator.iso-country".equals(arg5) || "gsm.sim.operator.iso-country".equals(arg5)) {            if(TextUtils.isEmpty(arg4.getSimCountryIso())) {                return arg4.getSimCountryIso();            }         }         else if("gsm.operator.alpha".equals(arg5) || "gsm.operator.orig.alpha".equals(arg5)) {            if(TextUtils.isEmpty(arg4.getSimOperatorName())) {                return arg4.getSimOperatorName();            }        }           else if("ro.build.brand".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildBrand())) {                return arg4.getBuildBrand();            }        }        else if("ro.build.board".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildBoard())) {                return arg4.getBuildBoard();            }        }        else if("net.hostname".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getNetHostname())) {                return arg4.getNetHostname();            }        }        else if("dalvik.vm.heapsize".equals(arg5)) {            return arg4.getVmHeapSize();        }         else if("ro.build.selinux".equals(arg5)) {            return "1";        }         else if("ro.board.platform".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBoardPlat())) {                return arg4.getBoardPlat();            }        }        else if("ro.product.cpu.abi".equals(arg5)) {            if(!TextUtils.isEmpty(arg4.getBuildAbi())) {                return arg4.getBuildAbi();            }        }        else if("ro.product.cpu.abi2".equals(arg5)) {            if(TextUtils.isEmpty(arg4.getBuildAbi2())) {                arg4.setBuildAbi2("armeabi");            }             return arg4.getBuildAbi2();        }        else {            if(!arg5.contains("gsm.version.baseband") && !arg5.contains("ro.baseband") && !arg5.contains("ro.boot.baseband")) {                return null;            }             if(TextUtils.isEmpty(arg4.getBuildRadioVersion())) {                return null;            }             return arg4.getBuildRadioVersion();        }         return null;    }      @Override    protected void afterHookedMethod(final XC_MethodHook.MethodHookParam xc_MethodHook$MethodHookParam) throws Throwable {        int v3 = 3;        Object v0_1;        String name = xc_MethodHook$MethodHookParam.method.getName();        String v1 = xc_MethodHook$MethodHookParam.method.getDeclaringClass().getName();         if ("get".startsWith(name)) {            v0_1 = this.IIl1lIIlll(this.deviceInfoModel, (String) xc_MethodHook$MethodHookParam.args[0]);             if (v0_1 != null) {                xc_MethodHook$MethodHookParam.setResult(v0_1);            }             if ("android.provider.Settings$NameValueCache".equals(v1)) {                this.setAccessible(xc_MethodHook$MethodHookParam.thisObject, "mValues");                v0_1 = XposedHelpers.getObjectField(xc_MethodHook$MethodHookParam.thisObject, "mValues");                 if ("android_id".equals(xc_MethodHook$MethodHookParam.args[0])) {                    ((HashMap) v0_1).put("android_id", this.deviceInfoModel.getAndroidId());                    xc_MethodHook$MethodHookParam.setResult(this.deviceInfoModel.getAndroidId());                }                 if ("accessibility_enabled".equals(xc_MethodHook$MethodHookParam.args[0])) {                    ((HashMap) v0_1).put("accessibility_enabled", "0");                    name = "0";                    xc_MethodHook$MethodHookParam.setResult(name);                 }                 if ("enabled_accessibility_services".equals(xc_MethodHook$MethodHookParam.args[0])) {                    super.afterHookedMethod(xc_MethodHook$MethodHookParam);                    ((HashMap) v0_1).put("enabled_accessibility_services", null);                    xc_MethodHook$MethodHookParam.setResult(null);                }            }              if ("android_id".equals(xc_MethodHook$MethodHookParam.args[0])) {                xc_MethodHook$MethodHookParam.setResult((Object) this.deviceInfoModel.getAndroidId());            }            if ("adb_enabled".equals(xc_MethodHook$MethodHookParam.args[0])) {                xc_MethodHook$MethodHookParam.setResult((Object) 0);            }            if ("data_roaming".equals(xc_MethodHook$MethodHookParam.args[0])) {                xc_MethodHook$MethodHookParam.setResult((Object) 0);            }            /* if ("wifi_on".equals(xc_MethodHook$MethodHookParam.args[0])) {                if (this.DeviceInfoModel.getType() != 1) {                    v3 = 0;                }                RLog.m("Test---get--othier2:wifi_on");                xc_MethodHook$MethodHookParam.setResult(v3);            }*/             if ("bluetooth_address".equals(xc_MethodHook$MethodHookParam.args[0])) {                if (TextUtils.isEmpty(this.deviceInfoModel.getBtAddress())) {                    super.afterHookedMethod(xc_MethodHook$MethodHookParam);                    xc_MethodHook$MethodHookParam.setResult(this.deviceInfoModel.getBtAddress());                }            }              if ("bluetooth_name".equals(xc_MethodHook$MethodHookParam.args[0])) {                if (TextUtils.isEmpty(this.deviceInfoModel.getBtName())) {                    super.afterHookedMethod(xc_MethodHook$MethodHookParam);                    xc_MethodHook$MethodHookParam.setResult(this.deviceInfoModel.getBtName());                }            }             if ("accessibility_enabled".equals(xc_MethodHook$MethodHookParam.args[0])) {                xc_MethodHook$MethodHookParam.setResult(0);            }             if ("enabled_accessibility_services".equals(xc_MethodHook$MethodHookParam.args[0])) {                xc_MethodHook$MethodHookParam.setResult(null);                super.afterHookedMethod(xc_MethodHook$MethodHookParam);            }             if (xc_MethodHook$MethodHookParam.args[0].toString().contains("accessibility")) {                xc_MethodHook$MethodHookParam.setResult(null);            }        }         else {            if("getStringForUser".equals(name)) {                if ("android.provider.Settings$NameValueCache".equals(v1)) {                    //RLog.m("Test---get--othier:enter android.provider.Settings$NameValueCache222");                    this.setAccessible(xc_MethodHook$MethodHookParam.thisObject, "mValues");                    v0_1 = XposedHelpers.getObjectField(xc_MethodHook$MethodHookParam.thisObject, "mValues");                     if ("android_id".equals(xc_MethodHook$MethodHookParam.args[1])) {                        ((HashMap) v0_1).put("android_id", this.deviceInfoModel.getAndroidId());                        xc_MethodHook$MethodHookParam.setResult(this.deviceInfoModel.getAndroidId());                    }                     if ("accessibility_enabled".equals(xc_MethodHook$MethodHookParam.args[1])) {                        ((HashMap) v0_1).put("accessibility_enabled", "0");                        name = "0";                        xc_MethodHook$MethodHookParam.setResult(name);                    }                    if ("enabled_accessibility_services".equals(xc_MethodHook$MethodHookParam.args[1])) {                        ((HashMap) v0_1).put("enabled_accessibility_services", null);                        xc_MethodHook$MethodHookParam.setResult(null);                    }                    super.afterHookedMethod(xc_MethodHook$MethodHookParam);                }                 if ("android_id".equals(xc_MethodHook$MethodHookParam.args[1])) {                    xc_MethodHook$MethodHookParam.setResult((Object)this.deviceInfoModel.getAndroidId());                }                if ("adb_enabled".equals(xc_MethodHook$MethodHookParam.args[1])) {                    xc_MethodHook$MethodHookParam.setResult((Object) 0);                }                if ("data_roaming".equals(xc_MethodHook$MethodHookParam.args[1])) {                    xc_MethodHook$MethodHookParam.setResult((Object) 0);                }                 if ("bluetooth_address".equals(xc_MethodHook$MethodHookParam.args[1])) {                    if (TextUtils.isEmpty(this.deviceInfoModel.getBtAddress())) {                        super.afterHookedMethod(xc_MethodHook$MethodHookParam);                        xc_MethodHook$MethodHookParam.setResult(this.deviceInfoModel.getBtAddress());                    }                }                  if ("bluetooth_name".equals(xc_MethodHook$MethodHookParam.args[1])) {                    if (TextUtils.isEmpty(this.deviceInfoModel.getBtName())) {                        super.afterHookedMethod(xc_MethodHook$MethodHookParam);                        xc_MethodHook$MethodHookParam.setResult(this.deviceInfoModel.getBtName());                    }                }                 if ("accessibility_enabled".equals(xc_MethodHook$MethodHookParam.args[1])) {                    xc_MethodHook$MethodHookParam.setResult(0);                }                 if ("enabled_accessibility_services".equals(xc_MethodHook$MethodHookParam.args[1])) {                    xc_MethodHook$MethodHookParam.setResult(null);                    super.afterHookedMethod(xc_MethodHook$MethodHookParam);                }                 if (xc_MethodHook$MethodHookParam.args[1].toString().contains("accessibility")) {                    xc_MethodHook$MethodHookParam.setResult(null);                }            }             if("set".equals(name)) {                Log.i("SysPropertyHook", "SystemProperties set : " + xc_MethodHook$MethodHookParam.args[0] + " , " + xc_MethodHook$MethodHookParam.args[1]);            }             if(!"getInt".equals(name)) {            }             if("ro.build.version.sdk".equals(xc_MethodHook$MethodHookParam.args[0])) {                xc_MethodHook$MethodHookParam.setResult(this.deviceInfoModel.getBuildSdk());            }        }    }     @Override   protected void beforeHookedMethod(XC_MethodHook.MethodHookParam paramMethodHookParam) throws Throwable {        super.beforeHookedMethod(paramMethodHookParam);        String str1 = paramMethodHookParam.method.getName();        Class localClass = paramMethodHookParam.method.getDeclaringClass();        if ("putStringForUser".equals(str1)) {            Class[] arrayOfClass = new Class[3];            arrayOfClass[0] = ContentResolver.class;            arrayOfClass[1] = String.class;            arrayOfClass[2] = Integer.TYPE;            Method localMethod = localClass.getDeclaredMethod("getStringForUser", arrayOfClass);            Object[] arrayOfObject = new Object[3];            arrayOfObject[0] = paramMethodHookParam.args[0];            arrayOfObject[1] = paramMethodHookParam.args[1];            arrayOfObject[2] = paramMethodHookParam.args[3];            String str2 = (String) localMethod.invoke(localClass, arrayOfObject);            String str3 = localClass.getSimpleName() + "," + paramMethodHookParam.args[1] + "," + paramMethodHookParam.args[2] + "," + str2;            Log.i("SysPropertyHook"," Settings putStringForUser : "+str3);        }else if("get".equals(str1)){            setBuilds();        }    }    }

3.RobuildHook.javaThis will obtain some system property values through the Build class’s getString method.

public class RobuildHook extends MethodHook {    public RobuildHook(XC_LoadPackage.LoadPackageParam paramLoadPackageParam, DeviceInfoModel deviceInfoModel) {        super(paramLoadPackageParam, deviceInfoModel);        hookMethodByClassMethodName("android.os.Build", "getString");        hookMethodByClassMethodName("android.os.Build", "getRadioVersion");    }    @Override    protected void afterHookedMethod(XC_MethodHook.MethodHookParam paramMethodHookParam) throws Throwable {        final String name = paramMethodHookParam.method.getName();        if ("getRadioVersion".equals(name)) {            if (!TextUtils.isEmpty((CharSequence)this.deviceInfoModel.getBuildRadioVersion())) {                paramMethodHookParam.setResult((Object)this.deviceInfoModel.getBuildRadioVersion());            }        }        else if ("getString".equals(name)) {             final String s = (String)paramMethodHookParam.args[0];            if ("net.hostname".equals(s)) {                paramMethodHookParam.setResult("android-" + this.deviceInfoModel.getBuildHost());            }             if ("ro.product.model".equals(s)) {                if (!TextUtils.isEmpty((CharSequence)this.deviceInfoModel.getBuildModel())) {                    //FileUtil.writeContent2FileForceUtf8(FilePathCommon.phoneTagPath,createfile.getRgPhoneNo());//标记是否hook成功                    paramMethodHookParam.setResult((Object)this.deviceInfoModel.getBuildModel());                }            }            else if ("ro.build.id".equals(s)) {                if (!TextUtils.isEmpty((CharSequence)this.deviceInfoModel.getBuildId())) {                    paramMethodHookParam.setResult((Object)this.deviceInfoModel.getBuildId());                }            }            else if ("ro.build.display.id".equals(s)) {                if (!TextUtils.isEmpty((CharSequence)this.deviceInfoModel.getDisplayId())) {                    paramMethodHookParam.setResult((Object)this.deviceInfoModel.getDisplayId());                }            }            else if ("ro.build.type".equals(s)) {                if (!TextUtils.isEmpty((CharSequence)this.deviceInfoModel.getBuildType())) {                    paramMethodHookParam.setResult((Object)this.deviceInfoModel.getBuildType());                }            }            else if ("ro.build.user".equals(s)) {                if (!TextUtils.isEmpty((CharSequence)this.deviceInfoModel.getBuildUser())) {                    paramMethodHookParam.setResult((Object)this.deviceInfoModel.getBuildUser());                }            }            else if ("ro.build.host".equals(s)) {                if (!TextUtils.isEmpty((CharSequence)this.deviceInfoModel.getBuildHost())) {                    paramMethodHookParam.setResult((Object)this.deviceInfoModel.getBuildHost());                }            }            else if ("ro.build.tags".equals(s)) {                if (!TextUtils.isEmpty((CharSequence)this.deviceInfoModel.getBuildTags())) {                    paramMethodHookParam.setResult((Object)this.deviceInfoModel.getBuildTags());                }            }            else if ("ro.product.brand".equals(s)) {                if (!TextUtils.isEmpty((CharSequence)this.deviceInfoModel.getBuildTags())) {                    paramMethodHookParam.setResult((Object)this.deviceInfoModel.getBuildBrand());                }            }            else if ("ro.product.device".equals(s)) {                if (!TextUtils.isEmpty((CharSequence)this.deviceInfoModel.getBuildDevice())) {                    paramMethodHookParam.setResult((Object)this.deviceInfoModel.getBuildDevice());                }            }            else if ("ro.product.board".equals(s)) {                if (!TextUtils.isEmpty((CharSequence)this.deviceInfoModel.getBuildBoard())) {                    paramMethodHookParam.setResult((Object)this.deviceInfoModel.getBuildBoard());                }            }            else if ("ro.product.name".equals(s)) {                if (!TextUtils.isEmpty((CharSequence)this.deviceInfoModel.getBuildName())) {                    paramMethodHookParam.setResult((Object)this.deviceInfoModel.getBuildName());                }            }            else if ("ro.product.manufacturer".equals(s)) {                if (!TextUtils.isEmpty((CharSequence)this.deviceInfoModel.getBuildManufacturer())) {                    paramMethodHookParam.setResult((Object)this.deviceInfoModel.getBuildManufacturer());                }            }            else if ("ro.hardware".equals(s)) {                if (!TextUtils.isEmpty((CharSequence)this.deviceInfoModel.getBuildHardware())) {                    paramMethodHookParam.setResult((Object)this.deviceInfoModel.getBuildHardware());                }            }            else if ("ro.serialno".equals(s)) {                if (!TextUtils.isEmpty((CharSequence)this.deviceInfoModel.getBuildSerialno())) {                    paramMethodHookParam.setResult((Object)this.deviceInfoModel.getBuildSerialno());                }            }            else if ("ro.build.version.incremental".equals(s)) {                if (!TextUtils.isEmpty((CharSequence)this.deviceInfoModel.getBuildIncremental())) {                    paramMethodHookParam.setResult((Object)this.deviceInfoModel.getBuildIncremental());                }            }            else if ("ro.build.version.release".equals(s)) {                if (!TextUtils.isEmpty((CharSequence)this.deviceInfoModel.getBuildRelease())) {                    paramMethodHookParam.setResult((Object)this.deviceInfoModel.getBuildRelease());                }            }            else if ("ro.build.version.sdk".equals(s)) {                if (!TextUtils.isEmpty((CharSequence)this.deviceInfoModel.getBuildSdk())) {                    paramMethodHookParam.setResult((Object)this.deviceInfoModel.getBuildSdk());                }            }            else if ("ro.build.version.codename".equals(s)) {                if (!TextUtils.isEmpty((CharSequence)this.deviceInfoModel.getBuildCodename())) {                    paramMethodHookParam.setResult((Object)this.deviceInfoModel.getBuildCodename());                }            }            else if ("ro.build.fingerprint".equals(s)) {                if (!TextUtils.isEmpty((CharSequence)this.deviceInfoModel.getBuildFingerprint())) {                    paramMethodHookParam.setResult((Object)this.deviceInfoModel.getBuildFingerprint());                }            }            else if ("ro.build.date.utc".equals(s) && this.deviceInfoModel.getBuildUtc() > 0L) {                paramMethodHookParam.setResult((Object)this.deviceInfoModel.getBuildUtc());            }        }        super.afterHookedMethod(paramMethodHookParam);    }     @Override    protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {        super.beforeHookedMethod(param);    }}

4.ScreenHook.javaModifications to screen information data.

public class ScreenHook extends MethodHook{     public ScreenHook(XC_LoadPackage.LoadPackageParam xc_LoadPackage$LoadPackageParam, DeviceInfoModel deviceInfoModel) {        super(xc_LoadPackage$LoadPackageParam, deviceInfoModel);        this.hookMethodByClassMethodName(Display.class.getName(), "getMetrics", new Object[] { DisplayMetrics.class.getName() });        this.hookMethodByClassMethodName(Display.class.getName(), "getWidth", new Object[0]);        this.hookMethodByClassMethodName(Display.class.getName(), "getHeight", new Object[0]);        this.hookMethodByClassMethodName(Resources.class.getName(), "getDisplayMetrics", new Object[0]);    }            }     @Override    protected void afterHookedMethod(XC_MethodHook.MethodHookParam xc_MethodHook$MethodHookParam) {        final String name = xc_MethodHook$MethodHookParam.method.getName();        if ("getWidth".equals(name)) {            if (this.deviceInfoModel.getWidth() > 0) {                xc_MethodHook$MethodHookParam.setResult((Object)this.deviceInfoModel.getWidth());             }        }        else if ("getHeight".equals(name)) {            if (this.deviceInfoModel.getHeight() > 0) {                xc_MethodHook$MethodHookParam.setResult((Object)this.deviceInfoModel.getHeight());            }        }        else if ("getDisplayMetrics".equals(name)) {            if (this.deviceInfoModel.getWidth() > 0 && this.deviceInfoModel.getHeight() > 0) {                final DisplayMetrics result = (DisplayMetrics)xc_MethodHook$MethodHookParam.getResult();                result.heightPixels = this.deviceInfoModel.getHeight();                result.widthPixels = this.deviceInfoModel.getWidth();                result.densityDpi = this.deviceInfoModel.getDensityDpi();                xc_MethodHook$MethodHookParam.setResult((Object)result);            }        }        else if ("getMetrics".equals(name)) {            final Object o = xc_MethodHook$MethodHookParam.args[0];            if (this.deviceInfoModel.getWidth() > 0 && this.deviceInfoModel.getHeight() > 0) {                ((DisplayMetrics)o).widthPixels = this.deviceInfoModel.getWidth();                ((DisplayMetrics)o).heightPixels = this.deviceInfoModel.getHeight();                ((DisplayMetrics)o).densityDpi = this.deviceInfoModel.getDensityDpi();            }        }          if(Filec.readToString("/sdcard/.hm_diamond/zhuce").length()>3){            //if(true){            final String name = xc_MethodHook$MethodHookParam.method.getName();            if ("getWidth".equals(name)) {                if (this.deviceInfoModel.getWidth() > 0) {                    xc_MethodHook$MethodHookParam.setResult((Object)this.deviceInfoModel.getWidth());                }            }            else if ("getHeight".equals(name)) {                if (this.deviceInfoModel.getHeight() > 0) {                    xc_MethodHook$MethodHookParam.setResult((Object)this.deviceInfoModel.getHeight());                }            }            else if ("getDisplayMetrics".equals(name)) {                if (this.deviceInfoModel.getWidth() > 0 && this.deviceInfoModel.getHeight() > 0) {                    final DisplayMetrics result = (DisplayMetrics)xc_MethodHook$MethodHookParam.getResult();                    result.heightPixels = this.deviceInfoModel.getHeight();                    result.widthPixels = this.deviceInfoModel.getWidth();                    result.densityDpi = this.deviceInfoModel.getDensityDpi();                    xc_MethodHook$MethodHookParam.setResult((Object)result);                 }            }            else if ("getMetrics".equals(name)) {                final Object o = xc_MethodHook$MethodHookParam.args[0];                if (this.deviceInfoModel.getWidth() > 0 && this.deviceInfoModel.getHeight() > 0) {                    ((DisplayMetrics)o).widthPixels = this.deviceInfoModel.getWidth();                    ((DisplayMetrics)o).heightPixels = this.deviceInfoModel.getHeight();                    ((DisplayMetrics)o).densityDpi = this.deviceInfoModel.getDensityDpi();                }            }        }     }}

5.PhoneSubInfoHook.javaThis modifies some information related to the SIM card.

public class PhoneSubInfoHook extends MethodHook{    private static  XC_LoadPackage.LoadPackageParam lpp;    public PhoneSubInfoHook(XC_LoadPackage.LoadPackageParam paramLoadPackageParam, DeviceInfoModel deviceInfoModel)    {        super(paramLoadPackageParam, deviceInfoModel);        lpp = paramLoadPackageParam;        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getDeviceId", new Object[0]);        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getSimSerialNumber", new Object[0]);        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getSubscriberId", new Object[0]);        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getLine1Number", new Object[0]);        hookMethodByClassMethodName(TelephonyManager.class.getName(), "hasIccCard", new Object[0]);        hookMethodByClassMethodName(TelephonyManager.class.getName(), "isSmsCapable", new Object[0]);        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getDataState", new Object[0]);        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getIsimImpi", new Object[0]);        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getIsimDomain", new Object[0]);        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getIsimImpu", new Object[0]);        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getLine1AlphaTag", new Object[0]);        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getMsisdn", new Object[0]);        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getVoiceMailAlphaTag");        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getMmsUserAgent");        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getMmsUAProfUrl");        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getDeviceSoftwareVersion");        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getProccmdline");        hookMethodByClassMethodName("com.android.internal.telephony.PhoneSubInfo", "getDeviceId");        hookMethodByClassMethodName("com.android.internal.telephony.PhoneSubInfo", "getImei");        hookMethodByClassMethodName("com.android.internal.telephony.PhoneSubInfo", "getDeviceSvn");        hookMethodByClassMethodName("com.android.internal.telephony.PhoneSubInfo", "getIccSerialNumber");        hookMethodByClassMethodName("com.android.internal.telephony.PhoneSubInfo", "getLine1Number");        hookMethodByClassMethodName("com.android.internal.telephony.PhoneSubInfo", "getSubscriberId");        hookMethodByClassMethodName("com.android.internal.telephony.PhoneSubInfo", "getLine1AlphaTag");        hookMethodByClassMethodName("android.telephony.MSimTelephonyManager", "getDeviceId");        hookMethodByClassMethodName("android.telephony.MSimTelephonyManager", "getSubscriberId");        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getCallState", new Object[0]);        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getNetworkType", new Object[0]);*/        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getPhoneType", new Object[0]);        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getNetworkClass", new Object[] { Integer.TYPE.getName() });        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getSimCountryIso", new Object[0]);        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getSimOperator", new Object[0]);        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getSimOperatorName", new Object[0]);        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getNetworkCountryIso", new Object[0]);        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getNetworkOperator", new Object[0]);        hookMethodByClassMethodName(TelephonyManager.class.getName(), "getNetworkOperatorName", new Object[0]);    }     @Override    protected void afterHookedMethod(XC_MethodHook.MethodHookParam paramMethodHookParam) throws Throwable {        String str1 = paramMethodHook$MethodHookParam.method.getName();        String str2 = paramMethodHook$MethodHookParam.method.getDeclaringClass().getName();        System.out.println("getString-->str0" + str1);        if("asInterface".equals(str1)) {            paramMethodHook$MethodHookParam.setResult(null);        }         if ("hasIccCard".equals(str1)){            paramMethodHook$MethodHookParam.setResult(Boolean.valueOf(true));        }        if ("isSmsCapable".equals(str1))        {            paramMethodHook$MethodHookParam.setResult(Boolean.valueOf(true));        }        if ("getDataState".equals(str1))        {            paramMethodHook$MethodHookParam.setResult(Integer.valueOf(2));        }        if ("getCallState".equals(str1))        {            paramMethodHook$MethodHookParam.setResult(Integer.valueOf(0));        }         if (("getLine1AlphaTag".equals(str1)) || ("getMsisdn".equals(str1)))        {            paramMethodHook$MethodHookParam.setResult(this.deviceInfoModel.getLine1Number());        }        if ("getLine1Number".equals(str1))        {            paramMethodHook$MethodHookParam.setResult(this.deviceInfoModel.getLine1Number());        }        if ("getState".equals(str1))        {            paramMethodHook$MethodHookParam.setResult(Integer.valueOf(0));        }        if ("getDataActivity".equals(str1))        {            paramMethodHook$MethodHookParam.setResult(Integer.valueOf(0));        }        if (("getVoiceMailAlphaTag".equals(str1)) || ("getVoiceMailNumber".equals(str1)))        {            paramMethodHook$MethodHookParam.setResult(this.deviceInfoModel.getLine1Number());        }         if ("getDeviceSoftwareVersion".equals(str1))        {            paramMethodHook$MethodHookParam.setResult("00");        }        if ("getProccmdline".equals(str1))        {            String str =  Filec.readToString(PathFileUtil.ownPath + "proccmdline");            paramMethodHook$MethodHookParam.setResult(str);        }         if ("getImei".equals(str1))        {            paramMethodHook$MethodHookParam.setResult(this.deviceInfoModel.getDeviceId());        }        if ("getDeviceId".equals(str1))        {            paramMethodHook$MethodHookParam.setResult(this.deviceInfoModel.getDeviceId());        }        if ("getIccSerialNumber".equals(str1))        {            paramMethodHook$MethodHookParam.setResult(this.deviceInfoModel.getSimSerialNumber());        }        super.afterHookedMethod(paramMethodHook$MethodHookParam);    }}

6.CellIdentityGsmHook.javaBase station and location information modification; note that the authenticity of base station information and nearby base station simulation is required.

public class CellIdentityGsmHook extends MethodHook{    public CellIdentityGsmHook(XC_LoadPackage.LoadPackageParam paramLoadPackageParam, DeviceInfoModel deviceInfoModel)    {        super(paramLoadPackageParam, deviceInfoModel);        hookMethodByClassMethodName("android.telephony.CellIdentityCdma", "getSystemId"); //mnc        hookMethodByClassMethodName("android.telephony.CellIdentityCdma", "getNetworkId"); //lac        hookMethodByClassMethodName("android.telephony.CellIdentityCdma", "getLongitude");  //getLongitude        hookMethodByClassMethodName("android.telephony.CellIdentityCdma", "getLatitude");  //getLatitude        hookMethodByClassMethodName("android.telephony.CellIdentityCdma", "getBaseStationId"); //ci        hookMethodByClassMethodName("android.telephony.CellIdentityGsm", "getLac");        hookMethodByClassMethodName("android.telephony.CellIdentityGsm", "getCid");        hookMethodByClassMethodName("android.telephony.CellIdentityGsm", "getMcc");        hookMethodByClassMethodName("android.telephony.CellIdentityGsm", "getMnc");        hookMethodByClassMethodName("android.telephony.CellIdentityLte", "getTac");        hookMethodByClassMethodName("android.telephony.CellIdentityLte", "getCi");        hookMethodByClassMethodName("android.telephony.CellIdentityLte", "getMcc");        hookMethodByClassMethodName("android.telephony.CellIdentityLte", "getMnc");        hookMethodByClassMethodName("android.telephony.CellIdentityWcdma", "getLac");        hookMethodByClassMethodName("android.telephony.CellIdentityWcdma", "getCid");        hookMethodByClassMethodName("android.telephony.CellIdentityWcdma", "getMcc");        hookMethodByClassMethodName("android.telephony.CellIdentityWcdma", "getMnc");    }     protected void afterHookedMethod(XC_MethodHook.MethodHookParam paramMethodHookParam) {        paramMethodHookParam.method.getDeclaringClass().getName();        String str = paramMethodHookParam.method.getName();        if ("getSystemId".equals(str))        {            paramMethodHook$MethodHookParam.setResult(this.deviceInfoModel.getMnc());        }        if ("getNetworkId".equals(str))        {            paramMethodHook$MethodHookParam.setResult(Integer.valueOf(this.deviceInfoModel.getLac()));            return;        }        if ("getLongitude".equals(str))        {            paramMethodHook$MethodHookParam.setResult(Double.valueOf(this.deviceInfoModel.getLongitude()));            return;        }        if ("getLatitude".equals(str))        {            paramMethodHook$MethodHookParam.setResult(Double.valueOf(this.deviceInfoModel.getLatitude()));            return;        }        if ("getBaseStationId".equals(str))        {            paramMethodHook$MethodHookParam.setResult(Integer.valueOf(this.deviceInfoModel.getCi()));            return;        }        if (("getLac".equals(str)) || ("getTac".equals(str)))        {            paramMethodHook$MethodHookParam.setResult(Integer.valueOf(this.deviceInfoModel.getLac()));            return;        }        if (("getCid".equals(str)) || ("getCi".equals(str)))        {            paramMethodHook$MethodHookParam.setResult(Integer.valueOf(this.deviceInfoModel.getCi()));            return;        }        if ("getMcc".equals(str)) {            paramMethodHook$MethodHookParam.setResult(Integer.valueOf(460));            return;        }        if (!"getMnc".equals(str));            paramMethodHook$MethodHookParam.setResult(this.deviceInfoModel.getMnc());    }}

7.StorageHook.javaThis modifies some data related to device memory, including anti-detection codes for Xposed, and there are also memory checks at the native layer, plus some C layer structures that will check the phone storage information.

public StorageHook(XC_LoadPackage.LoadPackageParam paramLoadPackageParam, DeviceInfoModel deviceInfoModel) {        super(paramLoadPackageParam, deviceInfoModel);        Object[] arrayOfObject1 = new Object[1];        arrayOfObject1[0] = ActivityManager.MemoryInfo.class.getName();         if(true){            hookMethodByClassMethodName("android.app.ActivityManager", "getMemoryInfo", arrayOfObject1);  //Memory            hookMethodByClassMethodName("android.content.pm.ApplicationInfo", "getApplicationInfo", new Object[0]);            hookMethodByClassMethodName("com.android.internal.os.PowerProfile", "getAveragePower");            hookMethodByClassMethodName("com.google.android.gles_jni.GLImpl", "glGetString");            hookMethodByClassMethodName("android.net.TrafficStats", "getMobileRxBytes");            hookMethodByClassMethodName("android.net.TrafficStats", "getMobileTxBytes");            hookMethodByClassMethodName("android.net.TrafficStats", "getTotalTxBytes");            hookMethodByClassMethodName("android.net.TrafficStats", "getTotalRxBytes");            String str = Intent.class.getName();            Object[] arrayOfObject2 = new Object[2];            arrayOfObject2[0] = String.class;            arrayOfObject2[1] = Integer.TYPE;            hookMethodByClassMethodName(str, "getIntExtra", arrayOfObject2);            hookMethodByClassMethodName(Window.class.getName(), "getAttributes", new Object[0]);            this.hookMethodByClassMethodName(WebView.class.getName(), "loadUrl");            this.hookMethodByClassMethodName(URLConnection.class.getName(), "getInputStream");            this.hookMethodByClassMethodName(HttpURLConnection.class.getName(), "getResponseCode");        }          XposedHelpers.findAndHookMethod("android.os.Debug", paramLoadPackageParam.classLoader, "isDebuggerConnected", XC_MethodReplacement.returnConstant(false));        hookMethodByClassMethodName(Thread.class.getName(), "getStackTrace", new Object[0]);        hookMethodByClassMethodName(Throwable.class.getName(), "getStackTrace", new Object[0]);        this.hookMethodByClassMethodName(Modifier.class.getName(), "isNative");        hookMethodByClassMethodName(File.class.getName(), "lastModified", new Object[0]);        hookMethodByClassMethodName("com.google.android.gms.ads.identifier.AdvertisingIdClient.Info", "getId");        hookMethodByClassMethodName(SystemClock.class.getName(), "elapsedRealtime", new Object[0]);        hookMethodByClassMethodName("java.lang.System", "getProperty");    }      @Override    protected void afterHookedMethod(XC_MethodHook.MethodHookParam xc_MethodHook$MethodHookParam) {        int i = 0;        int v0_2 = 0;        super.afterHookedMethod(xc_MethodHook$MethodHookParam);        final String name = xc_MethodHook$MethodHookParam.method.getName();        if ("getMemoryInfo".equals(name)) {            final ActivityManager.MemoryInfo activityManager$MemoryInfo = (ActivityManager.MemoryInfo)xc_MethodHook$MethodHookParam.args[0];            if (this.deviceInfoModel.getMemTotal() > 0L && this.deviceInfoModel.getMemAvailable() > 0L) {                XposedHelpers.setLongField((Object)activityManager$MemoryInfo, "totalMem", this.deviceInfoModel.getMemTotal());                XposedHelpers.setLongField((Object)activityManager$MemoryInfo, "availMem", this.deviceInfoModel.getMemAvailable());            }        }         else {            if ("glGetString".equals(name)) {              final int intValue = (int)xc_MethodHook$MethodHookParam.args[0];                 String[] v1_1 = IIl1lIIlll[new Random().nextInt(IIl1lIIlll.length)].split("|");                if(intValue == 7937) {                    xc_MethodHook$MethodHookParam.setResult(v1_1[0]);                }                if(intValue != 7936) {                    return;                }            }            else {                if ("getIntExtra".equals(name)) {                    final Intent intent = (Intent)xc_MethodHook$MethodHookParam.thisObject;                    if (!TextUtils.isEmpty((CharSequence)intent.getAction()) && "android.intent.action.BATTERY_CHANGED".equals(intent.getAction()) && "level".equals(xc_MethodHook$MethodHookParam.args[0])) {                        xc_MethodHook$MethodHookParam.setResult((Object)this.deviceInfoModel.getBatteryLevel());                    }                }                     else if ("getProperty".equals(name)) {                    final String s = (String)xc_MethodHook$MethodHookParam.args[0];                               if (s.equals("user.name")) {                        xc_MethodHook$MethodHookParam.setResult((Object)"");                    }                    if (s.equals("java.class.path")) {                        xc_MethodHook$MethodHookParam.setResult((Object)((String)xc_MethodHook$MethodHookParam.getResult()).replaceAll("XposedBridge.jar", ""));                    }                }                else {                    if ("getAttributes".equals(name)) {                        final WindowManager.LayoutParams result2 = (WindowManager.LayoutParams)xc_MethodHook$MethodHookParam.getResult();                        result2.screenBrightness = (float)(0.01 + 0.01 * Math.random());                         //result2.screenBrightness = (float)0.07;                        xc_MethodHook$MethodHookParam.setResult((Object)result2);                        return;                    }                    if ("elapsedRealtime".equals(name)) {                         xc_MethodHook$MethodHookParam.setResult((Object)(1990000L + (System.currentTimeMillis() - this.deviceInfoModel.getBuildUtc())));                        return;                    }                                      if ("isNative".equals(name)) {                        xc_MethodHook$MethodHookParam.setResult(false);                        return;                    }                      if ("getStackTrace".equals(name) && xc_MethodHook$MethodHookParam.getResult() instanceof StackTraceElement[]) {                        final StackTraceElement[] array = (StackTraceElement[])xc_MethodHook$MethodHookParam.getResult();                        final LinkedHashMap<Integer, StackTraceElement> linkedHashMap = new LinkedHashMap<Integer, StackTraceElement>();                        final int length = array.length;                        int j = 0;                        int n = 0;                        int n2 = 0;                        while (j < length) {                            final StackTraceElement stackTraceElement = array[j];                            int n3;                            if (!stackTraceElement.getClassName().startsWith("org.apache.pog")&&!stackTraceElement.getMethodName().equals("afterHookedMethod") && !stackTraceElement.getMethodName().equals("beforeHookedMethod")) {                                linkedHashMap.put(n2, stackTraceElement);                                n3 = n2 + 1;                            }                            else {                                n3 = n2;                            }                            if (n != 0 && "getStackTrace".equals(stackTraceElement.getMethodName())) {                                --n3;                                linkedHashMap.remove(n3);                            }                            if ("getStackTrace".equals(stackTraceElement.getMethodName())) {                                n = 1;                            }                            ++j;                            n2 = n3;                        }                        final StackTraceElement[] result3 = new StackTraceElement[n2];                        for (int k = 0; k < n2; ++k) {                            result3[k] = linkedHashMap.get(k);                        }                        xc_MethodHook$MethodHookParam.setResult((Object)result3);                    }                }            }        }    }

8.WifiHook.javaModification of mobile Wi-Fi information, including name, address, speed, whether Wi-Fi is enabled, etc.

hookMethodByClassMethodName(NetworkInfo.class.getName(), "getDetailedState", new Object[0]);hookMethodByClassMethodName(NetworkInfo.class.getName(), "getExtraInfo", new Object[0]);hookMethodByClassMethodName(NetworkInfo.class.getName(), "getTypeName", new Object[0]);hookMethodByClassMethodName(NetworkInfo.class.getName(), "getType", new Object[0]);hookMethodByClassMethodName(NetworkInfo.class.getName(), "isRoaming", new Object[0]);hookMethodByClassMethodName(NetworkInfo.class.getName(), "isConnected", new Object[0]);hookMethodByClassMethodName(NetworkInfo.class.getName(), "isAvailable", new Object[0]);hookMethodByClassMethodName(NetworkInfo.class.getName(), "isConnectedOrConnecting", new Object[0]);hookMethodByClassMethodName(NetworkInfo.class.getName(), "getSubtypeName");hookMethodByClassMethodName(NetworkInfo.class.getName(), "getSubtype");hookMethodByClassMethodName(ConnectivityManager.class.getName(), "getNetworkInfo", new Object[] { Integer.TYPE.getName() });hookMethodByClassMethodName(ConnectivityManager.class.getName(), "getMobileDataEnabled", new Object[0]);//hookMethodByClassMethodName(ConnectivityManager.class.getName(), "getActiveNetworkInfo", new Object[0]);hookMethodByClassMethodName(NetworkInterface.class.getName(), "getHardwareAddress", new Object[0]);hookMethodByClassMethodName(NetworkInterface.class.getName(), "getInetAddresses", new Object[0]);hookMethodByClassMethodName(NetworkInterface.class.getName(), "getInterfaceAddresses", new Object[0]);hookMethodByClassMethodName(NetworkInterface.class.getName(), "getNetworkInterfaces");hookMethodByClassMethodName(NetworkInterface.class.getName(), "getName");hookMethodByClassMethodName("android.net.wifi.WifiInfo", "getLinkSpeed");hookMethodByClassMethodName("android.net.wifi.WifiInfo", "getNetworkId");hookMethodByClassMethodName("android.net.wifi.WifiInfo", "getRssi");hookMethodByClassMethodName("android.net.wifi.WifiInfo", "getBSSID");hookMethodByClassMethodName("android.net.wifi.WifiInfo", "getMacAddress");hookMethodByClassMethodName("android.net.wifi.WifiInfo", "getSSID");hookMethodByClassMethodName("android.net.wifi.WifiInfo", "getIpAddress");hookMethodByClassMethodName("android.net.wifi.WifiManager", "getWifiState");hookMethodByClassMethodName("android.net.wifi.WifiManager", "isWifiEnabled");hookMethodByClassMethodName("android.net.wifi.WifiManager", "getDhcpInfo");

9.HideHook.javaSome codes for Xposed anti-detection, etc..

XposedHelpers.findAndHookMethod(classLoaderClazz, "loadClass", String.class, new XC_MethodHook() {        @Override        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {            if ("org.apache.pog.qianxun.XposedBridge".equals(param.args[0])) {                isHookComing = true;                //Hide                param.args[0] = null;            }        }    });    XposedHelpers.findAndHookMethod(classClazz, "getDeclaredField", String.class, new XC_MethodHook() {        @Override        protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {            if ("disableHooks".equals(param.args[0])) {                Log.d(TAG, ""disableHooks" found.");                if (isHookComing) {                    param.args[0] = null;                    isHookComing = false;                }            }        }    });     XposedHelpers.findAndHookMethod(classClazz, "getDeclaredFields", new XC_MethodHook() {        @Override        protected void afterHookedMethod(MethodHookParam param) throws Throwable {            if (XposedBridge.class.equals(param.thisObject)) {                param.setResult(null);            }        }    });    Class<?> clazz = null;    try {        clazz = Runtime.getRuntime().exec("echo").getClass();    } catch (IOException ignore) {    }    if (clazz != null) {        XposedHelpers.findAndHookMethod(                clazz,                "getInputStream",                new XC_MethodHook() {                    @Override                    protected void afterHookedMethod(MethodHookParam param) {                        InputStream is = (InputStream) param.getResult();                        if (is instanceof FilterXpInputStream) {                            param.setResult(is);                        } else {                            param.setResult(new FilterXpInputStream(is));                        }                    }                }        );    }     XposedHelpers.findAndHookMethod(            Throwable.class,            "getStackTrace",            hookStack    );    XposedHelpers.findAndHookMethod(            Thread.class,            "getStackTrace",            hookStack    );    XC_MethodHook hookClass = new XC_MethodHook() {        @Override        protected void beforeHookedMethod(MethodHookParam param) {            String packageName = (String) param.args[0];            if (packageName.matches("de\.robv\.android\.xposed\.Xposed+.+")) {                param.setThrowable(new ClassNotFoundException(packageName));            }        }    };    // FIXME: 18-6-23 w568w: It's very dangerous to hook these methods, thinking to replace them.    XposedHelpers.findAndHookMethod(            ClassLoader.class,            "loadClass",            String.class,            boolean.class,            hookClass    );    XposedHelpers.findAndHookMethod(            Class.class,            "forName",            String.class,            boolean.class,            ClassLoader.class,            hookClass    );}XC_MethodHook hookStack = new XC_MethodHook() {    @Override    protected void afterHookedMethod(MethodHookParam param) {        StackTraceElement[] elements = (StackTraceElement[]) param.getResult();        List<StackTraceElement> clone = new ArrayList<>();        for (StackTraceElement element : elements) {            if (!element.getClassName().toLowerCase().contains("xposed")) {                clone.add(element);            }if (!element.getClassName().toLowerCase().contains("ZygoteInit")) {                clone.add(element);            }        }        param.setResult(clone.toArray(new StackTraceElement[0]));    }};

10.BatteryManagerHook.java

Code related to battery level.

public class BatteryManagerHook extends MethodHook{    public BatteryManagerHook(XC_LoadPackage.LoadPackageParam paramLoadPackageParam, DeviceInfoModel deviceInfoModel){        super(paramLoadPackageParam, deviceInfoModel);        //Battery level        hookMethodByClassMethodName("android.os.BatteryManager", "getIntProperty");    }     @Override    protected void afterHookedMethod(XC_MethodHook.MethodHookParam xc_MethodHook$MethodHookParam) throws Throwable {        if ("getIntProperty".equals(xc_MethodHook$MethodHookParam.method.getName())) {            final int intValue = (int)xc_MethodHook$MethodHookParam.args[0];            if (intValue == 2) {                xc_MethodHook$MethodHookParam.setResult((Object)(-306394));            }            else if (intValue == 4) {                xc_MethodHook$MethodHookParam.setResult((Object)this.deviceInfoModel.getBatteryLevel());            }        }        super.afterHookedMethod(xc_MethodHook$MethodHookParam);    }     protected void beforeHookedMethod(XC_MethodHook.MethodHookParam paramMethodHookParam) throws Throwable {        super.beforeHookedMethod(paramMethodHookParam);    }}

There are also some codes that are not posted here; some codes are attached for your own reference.The final effectDeveloping Your Own Custom ROM Software with Xposed Framework4. Summary In this lesson, we explained the advantages and disadvantages of Xposed customization, introduced three commonly used solutions for customization, including some Xposed customization points and how to find these customization points. Due to the large amount of code in this lesson, I hope you can digest it well. If you want to make a good customization, it is best to look at the corresponding Android source code for each hook point to see how the code is implemented at the bottom level and whether there are better ways to modify it.Homework1. Develop your own custom ROM software using Xposed 2. Analyze the source code for each customization point

See the original text in the lower left corner for attachments.

– Official Forum

www.52pojie.cn

👆👆👆

Public AccountSet “Star Mark”, Youwill not missnew message notifications
Ifopen registration, excellent articles and surrounding activitiesand other announcements

Developing Your Own Custom ROM Software with Xposed Framework

Leave a Comment