会飞的丑小鸭 发表于 2024-1-27 04:19

《教我兄弟学Android逆向15 xpose改机开发03-写一款自己的改机软件》

本帖最后由 会飞的丑小鸭 于 2024-1-27 04:19 编辑

上一篇 《教我兄弟学Android逆向14 xpose改机开发02-改机代码基础编写》我带你熟悉了一下改机的流程,搭建了改机的基础代码,改机参数数据储存方面我们用的是SharedPreferences存储数据,界面方面写了一个一键新机的按钮,点一键新机的时候会随机生成imei数据存储到xml数据中,然后xpose代码hook到了getDeviceId函数会将返回值设置成xml文件读取的值,这样就完成了对imei的修改。

关于界面方面上节课也是粗略的写了一下,你可以根据自己想实现的功能去写自己想要的界面。
前面两节课我们配置了xpose开发的环境并且编写了xpose改机的第一个demo
那么本节课我会给你介绍一下改机的总体,以及改机点的寻找和编写。

要么学!要么不学!学和不学之间没有中间值 不学就放弃,学就要去认真的学!    --致选择

xpose改机的优缺点
优点
易上手,便于使用,所需时间成本比较少。
缺点
很容易被检测,只能在java层去操作,Native层,内核层,C库的一些函数无法被修改。
比如libc的函数open,fopen,access,rename,Unix的popen函数还有一些C层内核层获取设备信息的结构体这些都是无法通过xpose去改的。

那么如果想做一款比较好的改机有什么解决方案呢?
1.用xpose去配合一些可以hook so层函数的工具比如Inlinehook,frida等。
2.针对性修改,逆向出协议数据配合xpose模拟数据发包。
3.自定义安卓系统,全局修改。


一 .改机点介绍
1.硬件信息
手机的唯一标识imei,android,序列号serial,手机品牌,手机机型,制造商,蓝牙名,蓝牙MAC地址,系统版本,系统版本名称,开发代号,源码控制版本号,编译类型,CPU架构,无线电固件版本,设备版本号,主板名称,引导程序版本号,设备参数,设备地址,产品名称,ROM名称,硬件名称,指纹,开发ROM编译用户,设备的ROM生成的时间.....
2.手机卡信息
3.蓝牙信息
4.UA信息
5.电池电量
5.开机时间
6.手机内存的信息
7.屏幕大小
8.传感器
9.位置基站信息
10.wifi信息
11.文件信息
12.环境检测
13.设备信息真实性检测
......


看到这么多信息你应该有疑问了,上面说的这些点都是怎么去找到的?

二.改机点寻找
1.从百度google等搜索引擎去搜索xpose改机代码,github上面也有一些开源的xpose改机代码都可以去参考。
2.逆向一些app去看对方是怎么去获取设备信息的,怎么去检测环境信息的从而针对性的去完善改机代码。
3.研究分析安卓源码,找到一切可以获取设备信息的点,要知道大厂做安全的都是从研究Android源码开始的。

三.改机代码编写
1. 因为改机代码量比较大,所以我们首先写一个抽象类去继承XC_MethodHook后面的hook类都可以去继承这个类。
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;
            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 = paramArrayOfObject;
            }
      }
      catch (Throwable localThrowable)
      {
            Log.e("xposed-MethodHook", "addHookMethodWithParms Exception " + paramString1);
      }
    }

    public void hookMethodByClassMethodName(String paramString, Object[] paramArrayOfObject)
    {
      try
      {
            Object[] arrayOfObject = new Object;
            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 = paramArrayOfObject;
            }
      }
      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;
            v2.setAccessible(true);
            if(v2.getType().toString().endsWith(arg5)) {
                return v2;
            }
      }
      return null;
    }
}



2.BuildHook.java
这里包含手机的一些硬件信息的修改和android系统属性的修改,但是缺点的话SystemProperties的get方法很多大厂都是通过native去调用底层的native_get方法检测,这样就要配合其他方式去修改了。
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", "unkown");
      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)) {
            if(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);

            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)) {
                  ((HashMap) v0_1).put("android_id", this.deviceInfoModel.getAndroidId());
                  xc_MethodHook$MethodHookParam.setResult(this.deviceInfoModel.getAndroidId());
                }

                if ("accessibility_enabled".equals(xc_MethodHook$MethodHookParam.args)) {
                  ((HashMap) v0_1).put("accessibility_enabled", "0");
                  name = "0";
                  xc_MethodHook$MethodHookParam.setResult(name);

                }

                if ("enabled_accessibility_services".equals(xc_MethodHook$MethodHookParam.args)) {
                  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)) {
                xc_MethodHook$MethodHookParam.setResult((Object) this.deviceInfoModel.getAndroidId());
            }
            if ("adb_enabled".equals(xc_MethodHook$MethodHookParam.args)) {
                xc_MethodHook$MethodHookParam.setResult((Object) 0);
            }
            if ("data_roaming".equals(xc_MethodHook$MethodHookParam.args)) {
                xc_MethodHook$MethodHookParam.setResult((Object) 0);
            }

         /* if ("wifi_on".equals(xc_MethodHook$MethodHookParam.args)) {
                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)) {
                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)) {
                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)) {
                xc_MethodHook$MethodHookParam.setResult(0);
            }

            if ("enabled_accessibility_services".equals(xc_MethodHook$MethodHookParam.args)) {
                xc_MethodHook$MethodHookParam.setResult(null);
                super.afterHookedMethod(xc_MethodHook$MethodHookParam);
            }

            if (xc_MethodHook$MethodHookParam.args.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)) {
                        ((HashMap) v0_1).put("android_id", this.deviceInfoModel.getAndroidId());
                        xc_MethodHook$MethodHookParam.setResult(this.deviceInfoModel.getAndroidId());
                  }

                  if ("accessibility_enabled".equals(xc_MethodHook$MethodHookParam.args)) {
                        ((HashMap) v0_1).put("accessibility_enabled", "0");
                        name = "0";
                        xc_MethodHook$MethodHookParam.setResult(name);

                  }

                  if ("enabled_accessibility_services".equals(xc_MethodHook$MethodHookParam.args)) {
                        ((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)) {
                  xc_MethodHook$MethodHookParam.setResult((Object)this.deviceInfoModel.getAndroidId());
                }
                if ("adb_enabled".equals(xc_MethodHook$MethodHookParam.args)) {
                  xc_MethodHook$MethodHookParam.setResult((Object) 0);
                }
                if ("data_roaming".equals(xc_MethodHook$MethodHookParam.args)) {
                  xc_MethodHook$MethodHookParam.setResult((Object) 0);
                }

                if ("bluetooth_address".equals(xc_MethodHook$MethodHookParam.args)) {
                  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)) {
                  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)) {
                  xc_MethodHook$MethodHookParam.setResult(0);
                }

                if ("enabled_accessibility_services".equals(xc_MethodHook$MethodHookParam.args)) {
                  xc_MethodHook$MethodHookParam.setResult(null);
                  super.afterHookedMethod(xc_MethodHook$MethodHookParam);
                }

                if (xc_MethodHook$MethodHookParam.args.toString().contains("accessibility")) {
                  xc_MethodHook$MethodHookParam.setResult(null);
                }
            }

            if("set".equals(name)) {
                Log.i("SysPropertyHook", "SystemProperties set : " + xc_MethodHook$MethodHookParam.args + " , " + xc_MethodHook$MethodHookParam.args);
            }

            if(!"getInt".equals(name)) {
            }

            if("ro.build.version.sdk".equals(xc_MethodHook$MethodHookParam.args)) {
                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;
            arrayOfClass = ContentResolver.class;
            arrayOfClass = String.class;
            arrayOfClass = Integer.TYPE;
            Method localMethod = localClass.getDeclaredMethod("getStringForUser", arrayOfClass);
            Object[] arrayOfObject = new Object;
            arrayOfObject = paramMethodHookParam.args;
            arrayOfObject = paramMethodHookParam.args;
            arrayOfObject = paramMethodHookParam.args;
            String str2 = (String) localMethod.invoke(localClass, arrayOfObject);
            String str3 = localClass.getSimpleName() + "," + paramMethodHookParam.args + "," + paramMethodHookParam.args + "," + str2;
            Log.i("SysPropertyHook"," Settings putStringForUser : "+str3);
      }else if("get".equals(str1)){
            setBuilds();
      }
    }
    }

3.RobuildHook.java
这里会通过Build类的getString获取到一些系统属性的值。
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;
            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(MethodHookParam param) throws Throwable {
      super.beforeHookedMethod(param);
    }


4.ScreenHook.java
屏幕信息数据的修改
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);
      this.hookMethodByClassMethodName(Display.class.getName(), "getHeight", new Object);
      this.hookMethodByClassMethodName(Resources.class.getName(), "getDisplayMetrics", new Object);
    }
         
}

    @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;
            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;
                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.java
这里修改了手机卡相关的一些信息。
public class PhoneSubInfoHook extends MethodHook
{
    private staticXC_LoadPackage.LoadPackageParam lpp;
    public PhoneSubInfoHook(XC_LoadPackage.LoadPackageParam paramLoadPackageParam, DeviceInfoModel deviceInfoModel)
    {
      super(paramLoadPackageParam, deviceInfoModel);
      lpp = paramLoadPackageParam;
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "getDeviceId", new Object);
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "getSimSerialNumber", new Object);
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "getSubscriberId", new Object);
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "getLine1Number", new Object);
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "hasIccCard", new Object);
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "isSmsCapable", new Object);
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "getDataState", new Object);
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "getIsimImpi", new Object);
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "getIsimDomain", new Object);
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "getIsimImpu", new Object);
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "getLine1AlphaTag", new Object);
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "getMsisdn", new Object);
      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);
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "getNetworkType", new Object);*/
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "getPhoneType", new Object);
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "getNetworkClass", new Object[] { Integer.TYPE.getName() });
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "getSimCountryIso", new Object);
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "getSimOperator", new Object);
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "getSimOperatorName", new Object);
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "getNetworkCountryIso", new Object);
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "getNetworkOperator", new Object);
      hookMethodByClassMethodName(TelephonyManager.class.getName(), "getNetworkOperatorName", new Object);
    }

    @Override
    protected void afterHookedMethod(XC_MethodHook.MethodHookParam paramMethodHookParam) throws Throwable {
      String str1 = paramMethodHookParam.method.getName();
      String str2 = paramMethodHookParam.method.getDeclaringClass().getName();
      System.out.println("getString-->str0"+str1);
      if("asInterface".equals(str1)) {
            paramMethodHookParam.setResult(null);
      }

      if ("hasIccCard".equals(str1)){
            paramMethodHookParam.setResult(Boolean.valueOf(true));
      }
      if ("isSmsCapable".equals(str1))
      {
            paramMethodHookParam.setResult(Boolean.valueOf(true));
      }
      if ("getDataState".equals(str1))
      {
            paramMethodHookParam.setResult(Integer.valueOf(2));
      }
      if ("getCallState".equals(str1))
      {
            paramMethodHookParam.setResult(Integer.valueOf(0));
      }

      if (("getLine1AlphaTag".equals(str1)) || ("getMsisdn".equals(str1)))
      {
            paramMethodHookParam.setResult(this.deviceInfoModel.getLine1Number());
      }
      if ("getLine1Number".equals(str1))
      {
            paramMethodHookParam.setResult(this.deviceInfoModel.getLine1Number());
      }
      if ("getState".equals(str1))
      {
            paramMethodHookParam.setResult(Integer.valueOf(0));
      }
      if ("getDataActivity".equals(str1))
      {
            paramMethodHookParam.setResult(Integer.valueOf(0));
      }
      if (("getVoiceMailAlphaTag".equals(str1)) || ("getVoiceMailNumber".equals(str1)))
      {
            paramMethodHookParam.setResult(this.deviceInfoModel.getLine1Number());
      }

      if ("getDeviceSoftwareVersion".equals(str1))
      {
            paramMethodHookParam.setResult("00");
      }
      if ("getProccmdline".equals(str1))
      {
            String str =Filec.readToString(PathFileUtil.ownPath+"proccmdline");
            paramMethodHookParam.setResult(str);
      }

      if ("getImei".equals(str1))
      {
            paramMethodHookParam.setResult(this.deviceInfoModel.getDeviceId());
      }
      if ("getDeviceId".equals(str1))
      {
            paramMethodHookParam.setResult(this.deviceInfoModel.getDeviceId());
      }
      if ("getIccSerialNumber".equals(str1))
      {
            paramMethodHookParam.setResult(this.deviceInfoModel.getSimSerialNumber());
      }
      super.afterHookedMethod(paramMethodHookParam);
    }
}

6.CellIdentityGsmHook.java
基站和位置的信息修改,这里需要注意的是基站信息的真实性,附近基站的模拟。
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))
      {
            paramMethodHookParam.setResult(this.deviceInfoModel.getMnc());
      }
      if ("getNetworkId".equals(str))
      {
            paramMethodHookParam.setResult(Integer.valueOf(this.deviceInfoModel.getLac()));
            return;
      }
      if ("getLongitude".equals(str))
      {
            paramMethodHookParam.setResult(Double.valueOf(this.deviceInfoModel.getLongitude()));
            return;
      }
      if ("getLatitude".equals(str))
      {
            paramMethodHookParam.setResult(Double.valueOf(this.deviceInfoModel.getLatitude()));
            return;
      }
      if ("getBaseStationId".equals(str))
      {
            paramMethodHookParam.setResult(Integer.valueOf(this.deviceInfoModel.getCi()));
            return;
      }
      if (("getLac".equals(str)) || ("getTac".equals(str)))
      {
            paramMethodHookParam.setResult(Integer.valueOf(this.deviceInfoModel.getLac()));
            return;
      }
      if (("getCid".equals(str)) || ("getCi".equals(str)))
      {
            paramMethodHookParam.setResult(Integer.valueOf(this.deviceInfoModel.getCi()));
            return;
      }
      if ("getMcc".equals(str)) {
            paramMethodHookParam.setResult(Integer.valueOf(460));
            return;
      }
      if (!"getMnc".equals(str));
            paramMethodHookParam.setResult(this.deviceInfoModel.getMnc());
    }
}

7.StorageHook.java
这里修改了设备内存的一些数据,包括一些xpose的防检测代码,native层也有一些内存的检测,还有一些C层的结构体也会检测手机存储这些信息
public StorageHook(XC_LoadPackage.LoadPackageParam paramLoadPackageParam, DeviceInfoModel deviceInfoModel) {
      super(paramLoadPackageParam, deviceInfoModel);
      Object[] arrayOfObject1 = new Object;
      arrayOfObject1 = ActivityManager.MemoryInfo.class.getName();

      if(true){
            hookMethodByClassMethodName("android.app.ActivityManager", "getMemoryInfo", arrayOfObject1);//内存
            hookMethodByClassMethodName("android.content.pm.ApplicationInfo", "getApplicationInfo", new Object);
            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;
            arrayOfObject2 = String.class;
            arrayOfObject2 = Integer.TYPE;
            hookMethodByClassMethodName(str, "getIntExtra", arrayOfObject2);
            hookMethodByClassMethodName(Window.class.getName(), "getAttributes", new Object);
            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);
      hookMethodByClassMethodName(Throwable.class.getName(), "getStackTrace", new Object);
      this.hookMethodByClassMethodName(Modifier.class.getName(), "isNative");
      hookMethodByClassMethodName(File.class.getName(), "lastModified", new Object);
      hookMethodByClassMethodName("com.google.android.gms.ads.identifier.AdvertisingIdClient.Info", "getId");
      hookMethodByClassMethodName(SystemClock.class.getName(), "elapsedRealtime", new Object);
      hookMethodByClassMethodName("java.lang.System", "getProperty");
    }


    @Override
    protected void afterHookedMethod(XC_MethodHook.MethodHookParam xc_MethodHook$MethodHookParam) throws Throwable {
      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;
            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;

                String[] v1_1 = IIl1lIIlll.split("|");
                if(intValue == 7937) {
                  xc_MethodHook$MethodHookParam.setResult(v1_1);
                }
                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)) {
                        xc_MethodHook$MethodHookParam.setResult((Object)this.deviceInfoModel.getBatteryLevel());
                  }
                }
   
                else if ("getProperty".equals(name)) {
                  final String s = (String)xc_MethodHook$MethodHookParam.args;
         
                  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;
                            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;
                        for (int k = 0; k < n2; ++k) {
                            result3 = linkedHashMap.get(k);
                        }
                        xc_MethodHook$MethodHookParam.setResult((Object)result3);
                  }
                }
            }
      }
    }

8.WifiHook.java
手机wifi信息的修改,包括名称,地址,速度,是否开启wifi等
      hookMethodByClassMethodName(NetworkInfo.class.getName(), "getDetailedState", new Object);
      hookMethodByClassMethodName(NetworkInfo.class.getName(), "getExtraInfo", new Object);
      hookMethodByClassMethodName(NetworkInfo.class.getName(), "getTypeName", new Object);
      hookMethodByClassMethodName(NetworkInfo.class.getName(), "getType", new Object);
      hookMethodByClassMethodName(NetworkInfo.class.getName(), "isRoaming", new Object);
      hookMethodByClassMethodName(NetworkInfo.class.getName(), "isConnected", new Object);
      hookMethodByClassMethodName(NetworkInfo.class.getName(), "isAvailable", new Object);
      hookMethodByClassMethodName(NetworkInfo.class.getName(), "isConnectedOrConnecting", new Object);
      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);
      //hookMethodByClassMethodName(ConnectivityManager.class.getName(), "getActiveNetworkInfo", new Object);
      hookMethodByClassMethodName(NetworkInterface.class.getName(), "getHardwareAddress", new Object);
      hookMethodByClassMethodName(NetworkInterface.class.getName(), "getInetAddresses", new Object);
      hookMethodByClassMethodName(NetworkInterface.class.getName(), "getInterfaceAddresses", new Object);
      hookMethodByClassMethodName(NetworkInterface.class.getName(), "getNetworkInterfaces");
      hookMethodByClassMethodName(NetworkInterface.class.getName(), "getName");
      hookMethodByClassMethodName(InetAddress.class.getName(), "getHostAddress", new Object);
      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.java
xpose防检测等一些代码。
    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)) {
                  isHookComing = true;
                  //Hide
                  param.args = 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)) {
                  Log.d(TAG, "\"disableHooks\" found.");
                  if (isHookComing) {
                        param.args = 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;
                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));
      }
    };

10.BatteryManagerHook.java
电池电量相关的代码
public class BatteryManagerHook extends MethodHook
{
    public BatteryManagerHook(XC_LoadPackage.LoadPackageParam paramLoadPackageParam, DeviceInfoModel deviceInfoModel)
    {
      super(paramLoadPackageParam, deviceInfoModel);
      //电池电量
      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;
            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);
    }
}

还有一些代码就不贴了,部分代码放到附件了,可自行参考。


最终效果



四.总结
本节课我们讲解了xpose改机的优缺点,介绍了改机常用的三种方案,包括一些xpose的改机点以及这些改机点如何去寻找,由于本节课代码量比较多,希望你课下好好去消化一下,想做一款好的改机每一个hook点最好都去看一下对应的Android源码,看一下代码底层是怎么实现的,有没有其他更好的方式去修改它。


课后作业
1.利用xpose开发一款自己的改机软件
2.分析每一个改机点的源代码









GenW 发表于 2024-1-27 09:40

这辈子做不了大佬的兄弟了,学不上

dujc 发表于 2024-2-21 16:39

先给大佬磕一个再看,另外能不能出一个zygisk模块改机的?我有在看zygisk但没看懂?{:1_923:}另外我这边有个改机需求,可以付费开发{:1_893:}

大兵马元帅 发表于 2024-1-27 08:16

看了你的代码 我直呼经验,对不起 我不配做你兄弟{:1_911:}

lovnie 发表于 2024-1-27 08:50

大兵马元帅 发表于 2024-1-27 08:16
看了你的代码 我直呼经验,对不起 我不配做你兄弟

哈哈哈 确实是有难度

肉蛋葱鸡 发表于 2024-1-27 08:57

文章干活很多 但是 Lsposed是可以hook c层的

莫小沫rain 发表于 2024-1-27 09:02

厉害了 大佬

ruikai 发表于 2024-1-27 09:59

不是上一篇明明只有一个 imei这一篇怎么就13+了呢:'(weeqw

你这样我没法做你朋友了。。。

lose2836 发表于 2024-1-27 11:25

只能帮顶,膜拜下

mandarin 发表于 2024-1-27 11:50

注定和大佬无缘,唯有respect奉上

Yicimi 发表于 2024-1-27 13:05

只能帮顶,膜拜下{:1_932:}
页: [1] 2 3 4 5 6
查看完整版本: 《教我兄弟学Android逆向15 xpose改机开发03-写一款自己的改机软件》