Android C/C++层hook和java层hook原理以及比较

作者:Denny Qiao(乔希明),云智慧/架构师。

云智慧集团成立于2009年,是一家全栈智能业务运维解决方案提供商。公司经过多年自主研发,形成了从IT运维、电力运维到物联网运维的产业布局,涵盖ITOM、ITOA、ITSM、IoT几大领域,服务于金融、政府、运营商、能源、交通、制造我们已为数百个行业的客户提供数字化运维系统建设和全生命周期运维管理解决方案。云智慧秉承Make的使命,致力于通过先进的产品技术,持续赋能企业数字化转型,提升IT运营效率。

java层钩子机制虚拟机与JVM的区别虚拟机没有按照Java虚拟机的规范实现,与jvm不兼容。 Java虚拟机运行Java字节码,而虚拟机运行其专有的文件格式DEX() Davic读取dex文件,JVM读取的.class和jar文件是基于寄存器的,JVM是基于栈的每个应用程序都运行在一个虚拟机实例中,每个虚拟机实例都是一个独立的进程空间。虚拟机的线程机制、内存分配与管理、Mutex等都是依赖于底层操作系统来实现的。所有的应用线程都对应一个Linux线程,所以虚拟机可以更多地依靠操作系统的线程调度和管理机制来拥有一个专门的虚拟机进程,它是虚拟机实例的孵化器。每当系统要求执行一个应用程序时,它都会 FORK 一个子进程来执行该应用程序。系统启动时生成,完成虚拟机的初始化、库的加载、预置类库和初始化。如果系统需要一个新的虚拟机实例,它会快速复制自己,以最快的速度提供系统的启动过程

编译的结构图

hook原理Javac流程

Java类文件是8位字节的二进制流

与jvm相比,虚拟机多了一个dex模块

目的是:优化类,减小大小,加快加载运行速度,我们hook的关键是修改类文件,在原类文件中添加、修改方法或变量,所以至于将我们的钩子代码添加到类中,并自动埋点。 hook的入口是dex模块。

修改类的关键技术:asm框架中hook的实现方案直接修改了SDK中的dex模块dx.jar,修改了asm加载dx.jar中类的入口API,增加了我们的hook机制函数代码,它为每个加载的类执行代码注入。最后以安装包的形式提供给用户。

优点:一劳永逸,适用于所有开发工具,适用于、、、各种脚本编译等,开发周期短。早期我们采用这种方式,很快就完成了产品的开发并推向市场。

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

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

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

优点:用户使用更方便,无需修改用户的SDK环境,易于升级维护。比如插件,版本放在仓库里,直接配置即可。

实施方案的特点

针对每个开发环境,实现插件,在编译过程中hook类文件。这是一个静态钩子,不影响系统的运行效率,与系统的兼容性更好。

但是有个缺点,不能hook sdk,只能hook sdk上面的代码,那么随着不同模块代码的升级和变化,我们的hook代码也要变化,需要要不断适应。配备新出现的第三引擎功能模块。不断推出新的 sdk 版本以支持此更改。需要升级、维护。代码大小、内存、CPU等性能逐渐下降。

c/c++的ndk介绍

NDK是为本地开发发布的本地开发工具,包括Na# ve API、公共库和编译工具。

注意:NDK 需要 1.5 或以上版本的支持。 NDK和SDK是平行关系,DNK是SDK的有效补充。

一个项目由两部分组成:java部分和ndk扩展

图片[1]-Android C/C++层hook和java层hook原理以及比较-唐朝资源网

so库文件结构

我们更关心执行视图中段中的.rel.plt项:重定位在.got.plt段中(注意它也在.got中,具体区别仅此而已)。主要针对外部函数符号,一般是函数。第一次调用时已重新定位。第一次调用时,函数地址会被重定位,最终的函数地址会放在.got中。读取.got后直接得到最终的函数地址。

so hook关注so hook基本流程:通过读取FILE *fd = fopen(“/proc/self/maps”,”r”)内存映射表,找到进程内存基址中的so库。通过基地址,读取并解析SO的结构,在GOT表中找到外部函数的存储地址。 GOT表NDK hook中替换外部函数地址的基本流程:NDK hook实现关键方法:

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

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

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

4、 遍历链表,进行替换表函数地址操作,需要修改才能访问内存,然后调用系统指令清缓存:(addr, , )

5、遍历链表,进行替换表函数地址操作,需要修改才能访问内存,然后调用系统指令清缓存:(addr, , ))

6、释放资源并关闭精灵句柄:();

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

目前的钩子方法有以下缺点:

下一代代理实现概念

它是用naXve sdk,动态hook app的思想实现的。

写在最后

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

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

视觉编排平台-:

项目介绍:

地址:

吉特地址:

行业案例:

一些大屏案例:

© 版权声明
THE END
喜欢就支持一下吧
点赞10赞赏 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容