El principio y la comparación del gancho de capa Android C/C++ y el gancho de capa Java

Autor: Denny Qiao (Qiao Ximing), Cloud Wisdom/Arquitecto.

Fundado en 2009, Cloud Wisdom Group es un proveedor de soluciones de mantenimiento y operación comercial inteligente de pila completa. Después de años de investigación y desarrollo independientes, la empresa ha formado un diseño industrial que abarca desde operación y mantenimiento de TI, operación y mantenimiento de energía hasta operación y mantenimiento de IoT, que abarca varios campos importantes de ITOM, ITOA, ITSM, DevOps e IoT, al servicio de finanzas, El gobierno, los operadores, la energía, el transporte, los clientes en cientos de industrias, como la fabricación, han proporcionado la construcción de sistemas digitales de operación y mantenimiento y soluciones de gestión de operación y mantenimiento de ciclo de vida completo. Cloud Wisdom se adhiere a la misión de Make Digital Online y se compromete a potenciar continuamente la transformación digital de las empresas y mejorar la eficiencia de las operaciones de TI a través de tecnología de productos avanzada.

Mecanismo de enlace de capa Java de Android

La diferencia entre la máquina virtual android dalvic y JVM

  1. La máquina virtual Dalvik no está implementada según la especificación de la máquina virtual Java y no es compatible con jvm
  2. La máquina virtual de Java ejecuta el código de bytes de Java, mientras que la máquina virtual de Dalvik ejecuta su formato de archivo patentado DEX (Dalvik Executable)
  3. Davic lee archivos dex y jvm lee archivos .class y jar
  4. Dalvik se basa en registros, mientras que JVM se basa en pilas
  5. Cada aplicación de Android se ejecuta en una instancia de máquina virtual Dalvik y cada instancia de máquina virtual es un espacio de proceso independiente. El mecanismo de subprocesos de la máquina virtual, la asignación y administración de memoria, Mutex, etc. se implementan según el sistema operativo subyacente. Todos los subprocesos de aplicaciones de Android corresponden a un subproceso de Linux, por lo que la máquina virtual puede confiar más en el mecanismo de gestión y programación de subprocesos del sistema operativo.
  6. Hay un proceso de máquina virtual especial, Zygote, que es una incubadora de instancias de máquinas virtuales. Cada vez que el sistema solicite ejecutar una aplicación de Android, Zygote FORK un proceso secundario para ejecutar la aplicación. Se generará cuando se inicie el sistema y completará la inicialización de la máquina virtual, la carga de la biblioteca, la biblioteca de clases preestablecidas y la inicialización. Si el sistema necesita una nueva instancia de máquina virtual, se replica rápidamente y se la proporciona al sistema lo más rápido posible.

proceso de inicio de Android

Diagrama de estructura de compilación de Android

Principio de gancho de Android

proceso Javac

Los archivos de clase Java son flujos binarios de bytes de 8 bits

Android dalvik虚拟机相比 jvm 有一个dex模块

目的是: 优化class,减小体积,加快加载运行速度,我们hook的关键就是修改class文件,在原有class文件中增加,修改方法或者变量,以便加入我们的hook代码到class中,自动埋点。在android中hook的入口点是dex模块。

修改class的关键技术: asm框架

  • ASM 是一个 Java 字节码操控框架。它能被用来动态生成类或者增强既有类的功能。
  • ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。
  • Java class 被存储在严格格式定义的.class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。
  • ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。

Android hook的实现方案

  1. 直接修改android SDK中的dex模块dx.jar,用asm修改dx.jar中加载class的入口API,在函数中加入我们hook机制代码,对每一个加载的class进行代码注入。最后以安装包的形式提供用户。

优点:一劳永逸,适用于所有的android 开发工具,适合eclipse,android studio,各种脚本编译等,开发工期短。在初期,我们采用这种方法,很快完成了产品的开发,推向市场

缺点: 安装过程中需要替换用户android sdk中的dx.jar文件,属于侵入式安装,有一些用户不太接受。Android sdk不断的升级,我们也需要不断推出新的sdk,升级维护比较麻烦。

  1. 插件机制:需要实现不同的开发环境的插件:eclipse插件,gradle插件,各种自动化编译脚本的插件等。

基本原理: 在各个编译工具调用dx完成dex的过程中,通过编译环境提供的接口,调用我们class注入代码。

优点: 用户使用比较方便,不用修改用户android SDk环境,升级维护方便。比如gradle插件,版本放在jcenter仓库,直接配置就可以了。

实现方案的特点

针对各个开发环境,实现插件,在编译过程中对class文件进行hook。这是一种静态hook,不影响系统运行效率,而且对android的系统兼容性较好。

但是有一个缺点,不能hook android sdk,只能hook sdk之上的代码,那么随着不同模块代码的升级和改变,我们的hook 代码就不得不随之改变,而且需要不断适配新出现的第三发功能模块。不断地推出新的sdk版本支持这种变化。需要升级,维护。代码体积以及内存,CPU等性能逐渐降低。

Android c/c++ hook

android的ndk简介

NDK是Google为Android进行本地开发而放出的一个本地开发工具,包括Android的Na#ve API、公共库以及编译工具。

注意:NDK需要Android 1.5版本以上的支持,NDK与SDK是并列关系,DNK是SDK的有效补充。

一个android工程包括2部分:java部分和ndk扩展

So库文件结构

  • ELF文件格式提供了两种视图,分别是链接视图和执行视图
  • 链接视图是以节(secXon)为单位,执行视图是以段(segment)为单位。链接视图就是在链接时用到的视图,而执行视图则是在执行时用到的视图。上图左侧的视角是从链接来看的,右侧的视角是执行来看的。

我们比较关注的是执行视图中,段中.rel.plt项:重定位的地方在.got.plt段内(注意也是.got内,具体区分而已)。 主要是针对外部函数符号,一般是函数。首次被调用时候重定位。首次调用时会重定位函数地址,把最终函数地址放到.got内,以后读取该.got就直接得到最终函数地址。

so hook关注点

  • 导入表(GOT表 hook),SO引用外部函数的时候,在编译时会将外部函数的地址以Stub 的形式存放在.GOT 表中,加载时linker 再进行重定位,即将真实的外部函数写到此 stub 中。
  • HOOK 的思路就是:替换GOT表中的外部函数地址。可以理解为hook导入函数。

So hook基本流程:

  1. 通过读取 FILE *fd = fopen("/proc/self/maps","r") 内存映射表,找到so库在进程内存中的基地址。
  2. 通过基地址,读取并解析 SO 的结构,找到外部函数对应在GOT 表中的存放地址。
  3. 替换GOT表中的外部函数地址

NDK hook的基本流程:

  • 主要原理:通过解析映射到内存中的elf的结构,解析出got,然后进行hook重定位替换。其中必须要基于执行视图(ExecuXon View)进行符号解析;
  • ELF文件格式是基于链接视图(Linking View),链接视图是基于节(SecXon)对ELF进行解析的。然而动态链接库在加载的过程中,linker只关注ELF中的段(Segment)信息。

NDK hook实现关键方法:

1、 从给定的so中获取基址,获取so句柄ElfHandle:ElfHandle* handle = openElfBySoname(soname);

2、从segment视图获取elf信息(即加载到内存的so):getElfInfoBySegmentView(info, handle);

3、根据符号名寻找函数地址Sym:findSymByName(info, symbol, &sym, &symidx);

4、遍历链表,进行一次替换relplt表函数地址操作,其中需要使用mprotect修改访问内存,然后调用系统指令 清除缓存:replaceFunc(addr, replace_func, old_func)

5、遍历链表,进行一次替换reldyn表函数地址操作,其中需要使用mprotect修改访问内存,然后调用系统指令 清除缓存:replaceFunc(addr, replace_func, old_func))

6、释放资源,关闭elf句柄 :closeElfBySoname(handle);

c/c++层与java层hook的对比

目前的android hook方式具有以下缺点:

  • 实现复杂:需要支持各种开发环境,eclipse android studio,各种自动化编译工具,每种都比较复杂,开发和维护成本都比较高。需要支持各种用户使用到的第三方库。
  • 集成升级和维护:用户集成比较复杂,升级比较困难,需要不断的适配新出现的各种第三方库,因为我们是对用户代码进行hook,而不是SDK。

下一代的android agent实现构想

以android naXve sdk 的思路实现,动态hook app。

  • 优点: 针对android sdk进行hook,acXvity 事件,网络,线程,崩溃,anr等直接在android sdk的基础上进行hook,而不是针对用户app的实现代码进行hook,这样就可以大大减少对第三方库新增,升级等问题的适配。减少对系统资源的占用。
  • 集成方式: 透视宝android sdk的提供方式so库和jar包,以普通的so和jar的方式集成,不再需要各种集成插件的支持,支持网络动态升级和维护。
  • Hook方式: 动态hook,在app启动过程中进行hook,可以各个功能点动态控制。
  • 性能: sdk的体积会大大减少,对CPU的占用会降低
  • 兼容性: 现在的兼容性是对各个android系统版本之间的兼容性,以后只需要对新出现的android 手机系统进行适配。
  • 缺点: 技术难度增加,需要进行大量兼容性测试!

写在最后

近年来,在AIOps领域快速发展的背景下,IT工具、平台能力、解决方案、AI场景及可用数据集的迫切需求在各行业迸发。基于此,云智慧在2021年8月发布了AIOps社区, 旨在树起一面开源旗帜,为各行业客户、用户、研究者和开发者们构建活跃的用户及开发者社区,共同贡献及解决行业难题、促进该领域技术发展。

社区先后 开源 了数据可视化编排平台-FlyFish、运维管理平台 OMP 、云服务管理平台-摩尔平台、 Hours 算法等产品。

可视化编排平台-FlyFish:

项目介绍:www.cloudwise.ai/flyFish.htm…

Github地址: github.com/CloudWise-O…

Gitee地址: gitee.com/CloudWise/f…

行业案例:www.bilibili.com/video/BV1z4…

部分大屏案例:

Supongo que te gusta

Origin juejin.im/post/7087860699740766216
Recomendado
Clasificación