一、
1.支付宝的Xposed hook 检测原理: Xposed Hook 框架将Hook信息存储在fieldCache, methodCache,constructorCache 中,
利用java 反射机制获取这些信息,检测Hook信息中是否含有支付宝App中敏感的方法,字段,构造方法。

2.支付宝的SO检测原理: 检测进程中使用so名中包含关键"hack|inject|hook|call" 的信息。

3.支付宝的Root检测: 是否含有su程序和ro.secure是否为1

安全建议:

像这些 "de.robv.android.xposed.XposedHelpers",
"fieldCache","methodCache","constructorCache" 想这些敏感字符串信息可以进行一些简单加密。防止用户直接根据关键字搜索找到关键函数。

fieldCache, methodCache,constructorCache然是XposedHelpers的静态成员,类型是HashMap<String, Field>

通过反射遍历这些HashMap 缓存字段, 如字段项的key中包含支付宝的关键字"alipy" "taobao",等信息, 则认为是检测有Xposed 注入。

二、抖音的Xposed hook检测原理

1.尝试加载xposed的类,如果能加载则表示已经安装了。
XposedHelpers类中存在fieldCache methodCache constructorCache 这三个静态成员,都是hashmap类型,凡是需要被hook的且已经被找到的对象都会被缓存到这三个map里面。
我们通过便利这三个map来找到相关hook信息。
备注:方法a是检测xposed到底改了什么东西存放到a中。抖音似乎会收集相关信息并上报。

通过反射获取de.robv.android.xposed.XposedHelpers类的一个对象obXposedHelpers,
然后调用CheckKeywordInFiled 检测obXposedHelper成员fieldCache,methodCache,constructorCache是否有抖音包的关键字

public void b()
{
    try
    {
        Object localObject = ClassLoader.getSystemClassLoader()
                .loadClass("de.robv.android.xposed.XposedHelpers").newInstance();
        // 如果加载类失败 则表示当前环境没有xposed
        if (localObject != null)
        {
            a(localObject, "fieldCache");
            a(localObject, "methodCache");
            a(localObject, "constructorCache");
        }
        return;
    }
    catch (Throwable localThrowable) {}
}
 
private void a(Object arg5, String arg6) {
    try {
        // 从XposedHelpers中读取相关的hook信息
        Field v0_1 = arg5.getClass().getDeclaredField(arg6);
        v0_1.setAccessible(true);
        Set v0_2 = v0_1.get(arg5).keySet();
        if(v0_2 == null) {
            return;
        }
        if(v0_2.isEmpty()) {
            return;
        }
        Iterator v1 = v0_2.iterator();
        // 排除无关紧要的类
        while(v1.hasNext()) {
            Object v0_3 = v1.next();
            if(v0_3 == null) {
                continue;
            }
            if(((String)v0_3).length() <= 0) {
                continue;
            }
            if(((String)v0_3).toLowerCase().startsWith("android.support")) {
                continue;
            }
            if(((String)v0_3).toLowerCase().startsWith("javax.")) {
                continue;
            }
            if(((String)v0_3).toLowerCase().startsWith("android.webkit")) {
                continue;
            }
            if(((String)v0_3).toLowerCase().startsWith("java.util")) {
                continue;
            }
            if(((String)v0_3).toLowerCase().startsWith("android.widget")) {
                continue;
            }
            if(((String)v0_3).toLowerCase().startsWith("sun.")) {
                continue;
            }
            this.a.add(v0_3);
        }
    }
    catch(Throwable v0) {
        v0.printStackTrace();
    }
}

2.检测xposed相关文件

检测XposedBridge.jar这个文件和de.robv.android.xposed.XposedBridge
XposedBridge.jar存放在framework里面,de.robv.android.xposed.XposedBridge是开发xposed框架使用的主要接口。
在这个方法里读取了maps这个文件,在linux内核中,这个文件存储了进程映射了的内存区域和访问权限。在这里我们可以看到这个进程加载了那些文件。
如果进程加载了xposed相关的so库或者jar则表示xposed框架已注入。
public static boolean a(String paramString)
  {
    try
    {
      Object localObject = new HashSet();
       // 读取maps文件信息
      BufferedReader localBufferedReader =
                new BufferedReader(new FileReader("/proc/" + Process.myPid() + "/maps"));
       // 遍历查询关键词 反编译出来的代码可能不太准确
      for (;;)
      {
        String str = localBufferedReader.readLine();
        if (str == null) {
          break;
        }
        if ((str.endsWith(".so")) || (str.endsWith(".jar"))) {
          ((Set)localObject).add(str.substring(str.lastIndexOf(" ") + 1));
        }
      }
      localBufferedReader.close();
      localObject = ((Set)localObject).iterator();
      while (((Iterator)localObject).hasNext())
      {
        boolean bool = ((String)((Iterator)localObject).next()).contains(paramString);
        if (bool) {
          return true;
        }
      }
    }
    catch (Exception paramString) {}
    return false;
  }

3.检测方法的调用栈
如果你的手机安装了xposed框架,那么你在查看app崩溃时候的堆栈信息,一定能在顶层找到xposed的类信息,
既然xposed想改你的信息,那么在调用栈里面肯定是有它的身影的。
比如出现de.robv.android.xposed.XposedBridge这个类,
方法被hook的时候调用栈里会出现de.robv.android.xposed.XposedBridge.handleHookedMethod
 和de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative这些xposed的方法,
在dalvik.system.NativeStart.main方法后出现de.robv.android.xposed.XposedBridge.main调用
try {
        throw new Exception("");
    } catch (Exception localException) {
        StackTraceElement[] arrayOfStackTraceElement = localException.getStackTrace();
        int m = arrayOfStackTraceElement.length;
        int i = 0;
        int j;
        // 遍历整个堆栈查询xposed相关信息
        for (int k = 0; i < m; k = j) {
            StackTraceElement localStackTraceElement = arrayOfStackTraceElement[i];
            j = k;
            if (localStackTraceElement.getClassName()
                    .equals("com.android.internal.os.ZygoteInit")) {
                k += 1;
                j = k;
                if (k == 2) {
                    return true;
                }
            }
            if (localStackTraceElement.getClassName().equals(e)) {
                return true;
            }
            i += 1;
        }
    }
    return false;
}
 
  try
 
{
    throw new Exception("");
}
catch(
Exception localException)
 
{
    arrayOfStackTraceElement = localException.getStackTrace();
    j = arrayOfStackTraceElement.length;
    i = 0;
}
for(;;)
 
{
    boolean bool1 = bool2;
    if (i < j) {
        if (arrayOfStackTraceElement[i].getClassName()
                .equals("de.robv.android.xposed.XposedBridge")) {
            bool1 = true;
        }
    } else {
        return bool1;
    }
    i += 1;
}

4.修改hook方法的查询结果
   数组c包含了抖音里比较重要的及各类, this.a指的是检测出的被修改的方法,字段。
他执行了两者的匹配,将结果存放到了一个JSONObject里面,里面包含了是否使用模拟器,
系统的详细信息,是否是双开xpp,是否适用了xp,hook了那些方法等信息上报到https://xlog.snssdk.com/do/y?ver=0.4&ts=

private String[] c = {"android.os.Build#SERIAL",
        "android.os.Build#PRODUCT",
        "android.os.Build#DEVICE",
        "android.os.Build#FINGERPRINT",
        "android.os.Build#MODEL",
        "android.os.Build#BOARD",
        "android.os.Build#BRAND",
        "android.os.Build.BOOTLOADER",
        "android.os.Build#HARDWARE",
        "android.os.SystemProperties#get(java.lang.String,java.lang.String)",
        "android.os.SystemProperties#get(java.lang.String)",
        "java.lang.System#getProperty(java.lang.String)",
        "android.telephony.TelephonyManager#getDeviceId()",
        "android.telephony.TelephonyManager#getSubscriberId()",
        "android.net.wifi.WifiInfo#getMacAddress()",
        "android.os.Debug#isDebuggerConnected()",
        "android.app.activitymanager#isUserAMonkey()",
        "com.ss."};
 
 
public ArrayList<String> c() {
    ArrayList localArrayList = new ArrayList();
    Iterator localIterator = this.a.iterator();
    while (localIterator.hasNext()) {
        String str1 = (String) localIterator.next();
        String[] arrayOfString = this.c;
        int j = arrayOfString.length;
        int i = 0;
        while (i < j) {
            if (true == str1.startsWith(arrayOfString[i])) {
                String str2 = str1.replace(")#exact", ")").replace(")#bestmatch", ")").replace("#", ".");
                if (str2.length() > 0) {
                    localArrayList.add(str2);
                }
            }
            i += 1;
        }
    }
    return localArrayList;
}
5.检测方法是否被篡改
Modifier.isNative方法判断是否是native修饰的方法,xposedhook方法的时候,
会把方法转位native方法,我们检测native方法中不该为native的方法来达到检测的目的,
比如getDeviceId,getMacAddress这些方法如果是native则表示已经被篡改了。
public static boolean a(String paramString1, String paramString2, Class... paramVarArgs)
  {
    try
    {
      // 判断方法是不是用native修饰的
      boolean bool = Modifier.isNative(Class.forName(paramString1)
                   .getDeclaredMethod(paramString2, paramVarArgs).getModifiers());
      if (bool) {
        return true;
      }
    }
    catch (Exception paramString1)
    {
      paramString1.printStackTrace();
    }
    return false;
  }

6.检测包名
   这个是最简单也是最不靠谱的方法,因为只要禁止app读取应用列表就没办法了。
if (((ApplicationInfo)localObject).packageName.equals("de.robv.android.xposed.installer"))
     {
       Log.wtf("HookDetection", "Xposed found on the system.");
     }
 }

xposed检测原理分析 -案例某付宝、某音相关推荐

  1. xposed hook java_[原创]Android Hook 系列教程(一) Xposed Hook 原理分析

    章节内容 一. Android Hook 系列教程(一) Xposed Hook 原理分析 二. Android Hook 系列教程(二) 自己写APK实现Hook Java层函数 三. Androi ...

  2. Xposed 实现原理分析

    Xposed 实现原理分析 文章目录 Xposed 实现原理分析 前言 Xposed 使用方法 Xposed 原理概述 Android zygote 进程 基于 Dalvik 的方法 Hook 基于 ...

  3. OpenCV——角点检测原理分析(Harris,Shi-Tomasi、亚像素级角点检测)

    一.角点(corner) 角点通常被定义为两条边的交点,或者说,角点的局部邻域应该具有两个不同区域的不同方向的边界.角点检测(Corner Detection)是计算机视觉系统中获取图像特征的一种方法 ...

  4. Android Hook原理分析--Xposed hook 原理分析

    hook寓意为钩子,在编程中寓意拦截替换. 整体逻辑就是将执行的方法拦截执行替换之后再执行回去,各大框架原理不同但是过程类似. Xposed Xposed框架核心思想在于将Java层普通函数注册成本地 ...

  5. 【Audio音频兴趣拓展】耳机类型检测原理

    =耳机类型检测原理分析= 手机的耳机常见的3芯音频插头立体声耳机或带有麦克风的单声道耳机,带有麦克风的立体声耳机. ==利用比较器检测== 可以用比较器区分出立体声和单声道+麦克风耳机.电路设计依据为 ...

  6. 读书笔记之 大型网站技术架构(核心原理与案例分析)

    前言 坚持看了十几天的书,终于完成了毕业后第一次静下心来,利用业务时间看书并做笔记的成就了.废话不多说,这回看的是一直很膜拜的李智慧大神写的大型网站技术架构-核心原理与案例分析. 简短的读后感 极其推 ...

  7. 大型网站技术架构:核心原理与案例分析pdf

    下载地址:网盘下载 编辑推荐 编辑 本书作者是阿里巴巴网站构建的亲历者,拥有核心技术部门的一线工作经验,直接体验了大型网站构建与发展过程中的种种生与死,蜕与变,见证了一个网站架构从幼稚走向成熟稳定的历 ...

  8. 一文讲透大型网站架构模式核心原理与案例分析

    什么是模式?每一个模式描述了一个在我们周围不断发生的问题及该问题解决方案的核心.这样,你就能一次又一次地使用该方案而不必做重复的工作. 也许互联网产品不是随便复制就能成功的,创新的产品更能为用户创造价 ...

  9. 阅读《大型网站技术架构:核心原理与案例分析》第五、六、七章

    阅读<大型网站技术架构:核心原理与案例分析>第五.六.七章,结合我们的系统,分析如何增加相应的功能,提高系统的可用性和易用性. 这三章主要讲述的是网站的可用性.伸缩性和可扩展性. 高可用架 ...

最新文章

  1. [译] RxJS: 避免 takeUntil 造成的泄露风险
  2. 关于量子计算,你应该知道的七个事实
  3. python基础知识整理-python爬虫基础知识点整理
  4. django 类取消csrf_Django之Form组件详解、图片上传及定制
  5. php类常量的特点,php类常量是什么?类常量用法详解
  6. python安装matlab库_[python][matlab]在python36上安装matlab2015b引擎
  7. ubuntu 14.04 LTS(64bit) Anacoda2环境下安装gensim
  8. 项目管理学习总结(14)——优秀技术Leader应该具备什么哪些方面的能力
  9. mysql 修改data目录后 无法使用脚本启动
  10. 系统学习NLP(十二)--文本表示综述
  11. QFIL and FASTBOOT
  12. OFC2020论文笔记 M1F.5 25.78-Gbit/s Burst-mode Receiver for 50G-EPON OLT
  13. asp dotnet core 从零开始创建一个 WebApi 服务
  14. Don't Starve:饥荒
  15. 其实嵌入式编程还是很难很复杂的
  16. Spring BcryptPasswordEncorder Log Rounds参数说明
  17. 爱上一个自己讨厌的人
  18. 使用react完成图片放大功能(淘宝放大镜)
  19. js获取当前服务器的ip
  20. GBase 8a数据库加载流程介绍

热门文章

  1. 浏览器点击URL的响应过程
  2. c语言实验,c语言实验报告
  3. python-将DataFrame中的 pandas 系列从字符串(财务缩写)转换为数字
  4. zbrush 制作麻绳
  5. PCB设计系列文章-印刷电路发展历史
  6. 单个字符串json返回问号解决
  7. php图片居中显示图片,怎样让css图片居中显示
  8. ABAP Report一般格式
  9. php condition 语法,condition的五个语法要点
  10. lm80认证_LM80测试是什么,LM80报告是什么,LM80认证是什么