小研究 - Android 字节码动态分析分布式框架(四)

news2024/9/29 15:21:44

安卓平台是个多进程同时运行的系统,它还缺少合适的动态分析接口。因此,在安卓平台上进行全面的动态分析具有高难度和挑战性。已有的研究大多是针对一些安全问题的分析方法或者框架,无法为实现更加灵活、通用的动态分析工具的开发提供支持。此外,很多研究只是针对单进程的分析,在安卓平台多个应用进程协作完成事务的情境下,则无法进行很好的分析。

目录

4  系统实现

4.1 安卓源代码的修改

 4.2 安卓系统 ACS 通信服务

4.2.1 初始化功能

4.2.2 注入服务

4.2.3 事件接受和转发

 4.3 Dalvik 虚拟机的扩展

4.3.1 ShadowVM 支持

4.3.2 虚拟机事件

 4.4 Binder 的扩展


4  系统实现

本章将会详细介绍本文的动态分析框架的各个模块是如何实现的,包括新增的安卓系统 ACS 通信服务、Dalvik 虚拟机的扩展、系统 Binder 库的扩展、以及远程注入和分析服务器的实现。首先,第一部分会先介绍实现这些系统需要涉及的Android 源代码目录,介绍它们原先的作用以及进行了哪些修改;接着第二部分介绍本文在 Android 系统中实现的 ACS 通信服务模块,讲述了如何高效的进行Android 内外部通信;然后在第三部分,通过介绍 DVM 部分的实现,讲述了虚拟机事件的产生以及如何处理系统库共享带来的弊端;在第四部分,介绍了如何扩展 Binder 的中间层以及内核部分,以提供分析需要的 IPC Binder 事件;最后还简单介绍了 Android 系统外对原有ShadowVM 的改造。

4.1 安卓源代码的修改

在介绍这些模块的实现之前,有必要介绍一下安卓源代码的组织结构。安卓源代码是由 repo 工具管理的许多的 git 项目仓库组成的。本文是基于 Android 开源项目的 4.1.1_r6 版本实现的。

表 4-1 列出 Android 源代码根目录下的主要的目录,并依次简介了本文实现需要修改的部分:Dalvik 文件夹含有所有 DVM 实现相关的代码,通过修改 DVM,提供了框架需要的虚拟机事件、注入事件等扩展;而 external 目录则放了 ACS 服务的实现,并编译成动态库为 DVM 提供支持;为了支持 Binder 事件,除了需要修改 frameworks/native/binder 意外,还需要修改内核 kernel 目录,为此需要修改涉及内核的 bionic 目录里的 binder.h 头文件。

 4.2 安卓系统 ACS 通信服务

为了能够在系统开始的时候就提供服务,本文通过修改 init.rc 文件,设置了 ACService 的主程序开机自动启动,并向 Service Manager 注册该服务。

ACService 主要承担的职责分为如下几个部分:

1)初始化系统的必要配置。为了能够让系统库在不同的进程中得到不同方式的处理,以减少注入系统库带来的污染,系统允许用户在外部系统分析服务器提供配置。配置中会指明哪些进程需要被监控,并利用 bypass 机制来控制不同进程的行为。因此,启动 ACS 过程中,ACS 需要先与分析服务器通信,获取分析的必要配置。此外,ACS 还需要负责清空不同应用加载的缓存。

2)完成字节码的转发。接收来自 DVM 虚拟机的字节码加载事件,并转发给外部系统的注入服务器进行注入。在注入完成后,接收注入服务器发回的字节码并交还给相应 DVM 以继续完成字节码的加载;

3)完成事件的转发。ACS 需要能够将不同进程的事件发送到分析服务器以推动分析的进行。本文采用了 Ashmem 共享内存的方式,来实现应用进程与 ACS进程的事件传输,以减少内存消耗提高性能。而在 ACS 的主程序中会单独设置一个线程,通过轮询的方法,将不同进程的事件发送出去。

ACService 采用 C++语言开发,代码位置放在外部 库 external 目录下。通过配置安卓的启动进程选项,可以让 ACService 在系统刚开始的时候就自动启动并注册,这样能够在第一时间为第一个 DVM 进程提供服务。

下图显示了在如何向 Service Manager 注册 ACService 服务,以及在程序中如何获取该服务。

/* Register ACSerivce to Service Manager */
void register_service(){
    IACService* service = new ACService();
    defaultServiceManager()->addService(
        String16("ACService"), service);
    android::ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}
/* Get ACService from Service Manager */
Sp<IACService> get_service(){
    sp<IServiceManager> sm = defaultServiceManager();
    sp<IBinder> binder sm->getService(String16("ACService"));
    sp<IACService> interface_cast<IACService>(binder);
}
4.2.1 初始化功能

在 ACService 主程序的 main 方法里,会首先执行清除 DVM 字节码缓存的任务,即删除所有位于/data/dalvik-cache 目录下的 odex 字节码。接着,通过 register_service 向系统注册服务。register_service 以后,主程序会进入循环,等待服务请求。

4.2.2 注入服务

为了实现 2)中的注入功能,ACS 为 DVM 提供了一个接口,在 DVM 加载字节码文件的时候会将字节码以共享内存的方式发送给 ACService,ACService 则通过建立一个网络连接与注入服务器进行通信。DVM 加载字节码的时候,是通过IACService 的 instrumentDex 接口来与 ACService 通信的。instrumentDex 接收四个参数,分别表示含有字节码的文件的名称、原字节码的长度以及存储了原字节码的共享内存文件描述符及其最大容量。每次收到字节码,ACService 会向注入服务器发送新的注入事件。

4.2.3 事件接受和转发

而上述 3)的功能实现分为两个部分:从不同进程获取事件、以及将这些事件发送到分析服务器,实现如图4-3所示。图中上方部分表示进程Process 1,Process2……Process N 分别表示不同的待观测的 DVM 进程(DVM 进程包括了 Zygote 进程、所有从 Zygote fork 生成的进程以及其它利用 dalvikvm 程序启动的进程),各个 DVM 进程在运行的过程中,会产生 Binder IPC 调用事件、Dalvik 虚拟机的事件以及用户的分析事件。

在 ACService 进程中,有一个专门的线程,不断轮询所有队列,将未发送的事件内存块的内容转发出去。这里需要特殊说明的一点是,应用进程从 Zygote fork产生,但不同应用进程与 zygote 并不共享事件发送队列,因而所有进程可以被同等看待。

IACService 还有两个接口 mapPidPname 和 clientClose。mapPidPname 发生在zygote 通过 fork 产生子进程后,用于在 ACService 中维护进程号与进程名的映射关系,并根据进程名来判断该进程是否应当被监听;而 clientClose 表示一个虚拟机进程完成了分析任务或者在虚拟机结束后,需要在 ACS 服务中注销,注销后ACS 服务端能够进一步释放相关资源,提高运行效率。

 

 4.3 Dalvik 虚拟机的扩展

Dalvik 虚拟机的扩展,为本文框架提供了类似 JVMTI 接口中的虚拟机事件,丰富了 ShadowVM 的语意。

4.3.1 ShadowVM 支持

AREDispatch 是本文提供给用户实现异步分析的接口。它提供的 API 如图 3-6所示。这些 API 都是 native 方法,本文将其实现放在 Dalvik 虚拟机中。dalvik/vm/native 目录放置了许多 Java 库中与虚拟机运行时直接相关的类的 native方法实现。AREDispatch 必须作为系统第一批加载的类,因此其 native 方法的实现也放在这个目录下,以保证在系统 JNI 环境准备完毕前,AREDipstach 就可用。

最后通过 ACService 封装的接口 svmNewClassInfo 来将需要的类信息发送到服务器端。

jlong SetAndGetTag(Object* obj){
    jlong res;
    if(obj == NULL)
        res = 0;
    else if(obj->tag != 0)
        res = obj->tag;
    else if(dvmIsClassObject(obj))
        res = newClass((ClassObject*)obj);
    else {
        if(obj->clazz->tag == 0){ //its class not registered
            newClass(obj->clazz);
        }
        obj->tag = set_tag (obj_id++,get_class_id(obj->clazz->tag));
        res = obj->tag;
}
    return res;
}
jlong newClass(ClassObject *obj){
    jlong superid = SetAndGetTag(obj->super);
    jlong loaderid = SetAndGetTag(obj->classLoader);
    obj->tag = set_tag (obj_id++,clz_id++,1,1);
    svmNewClassInfo(obj->tag, obj->descriptor, loaderid, superid);
    return obj->tag;
}
4.3.2 虚拟机事件

在 DVM 中可以提供的事件,如下表。

 4.4 Binder 的扩展

对 Binder 事件的扩展,允许分析将不同进程、线程之间的事件串联起来,以提供一个更加完整的分析模型。为此通过修改 frameworks 目录下 Binder 实现,以及 service manager 中 C 语言实现的 binder 调用实现了 Binder 事件。

每次 Binder 调用,可以用<client_pid, client_tid, transaction_id>唯一标识,transaction_id 是一个线程局部自增长变量。原来的 Binder 库在被调用端,只能查询调用进程的进程号,而不能查询线程号,为了使 Binder 调用的接收端能够识别出 Binder 调用的完整来历,需要在传输 binder 信息的时候加上额外的信息,包括发起端的线程 id 和事务 id。

struct binder_transaction_data {
    ...
    pid_t sender_pid;
    //records the sender’s thread id

    pid_t sender_tid;
    //records the incremental counter for each binder call
    pid_t transaction_id;
    uid_t sender_euid;
    size_t data_size;
    ...
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/906291.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

水电站防雷工程综合解决方案

水电站防雷工程是指为了保护水电站的建筑物、设备和人员免受雷电危害而采取的一系列技术措施。水电站防雷工程的主要内容包括接地装置、引下线、接闪器、等电位连接、屏蔽、综合布线和电涌保护器等分项工程。水电站防雷工程的施工和质量验收应遵循国家标准《建筑物防雷工程施工…

算法leetcode|72. 编辑距离(rust重拳出击)

文章目录 72. 编辑距离&#xff1a;样例 1&#xff1a;样例 2&#xff1a;提示&#xff1a; 分析&#xff1a;题解&#xff1a;rust&#xff1a;二维数组&#xff08;易懂&#xff09;滚动数组&#xff08;更加优化的内存空间&#xff09; go&#xff1a;c&#xff1a;python&a…

vue引入 import { decode } from ‘js-base64‘

vue引入 import { decode } from ‘js-base64’ package.json 里面加上 需要用的地方 加上 import { decode } from ‘js-base64’ let params decode(loook)最后 npm install

【数据分享】2006-2021年我国城市级别的节约用水相关指标(免费获取\20多项指标)

《中国城市建设统计年鉴》中细致地统计了我国城市市政公用设施建设与发展情况&#xff0c;在之前的文章中&#xff0c;我们分享过基于2006-2021年《中国城市建设统计年鉴》整理的2006—2021年我国城市级别的市政设施水平相关指标、2006-2021年我国城市级别的各类建设用地面积数…

@Accessors和@Builder区别

目录 Accessors和Builder Accessors(chaintrue)BuilderAccessors和Builder的区别Accessors和Builder使用的坑详细看看Accessors注解 Accessors的源码Accessors属性说明 fluent属性chain属性makeFinal属性prefix属性 Accessors和Builder Accessors(chaintrue) 就是new一个对象…

c语言每日一练(10)

前言&#xff1a;每日一练系列&#xff0c;每一期都包含5道选择题&#xff0c;2道编程题&#xff0c;博主会尽可能详细地进行讲解&#xff0c;令初学者也能听的清晰。每日一练系列会持续更新&#xff0c;暑假时三天之内必有一更&#xff0c;到了开学之后&#xff0c;将看学业情…

计算机农业类重点SCIE征稿中

SciencePub学术 刊源推荐: 计算机农业类重点SCIE征稿中&#xff01;信息如下&#xff0c;录满为止&#xff1a; 一、期刊概况&#xff1a; 计算机农业类重点SCIE 【期刊简介】IF&#xff1a;3.0-3.5&#xff0c;JCR2区&#xff0c;中科院4区&#xff1b; 【版面类型】正刊&a…

传统车间VS数字化车间,以MES为核心打造智能工厂!

传统车间的生产制造场景往往存在着信息沟通不顺畅&#xff0c;传达不到位的情况&#xff0c;导致生产效率受影响。 其次车间数据的“缓存期”偏短&#xff0c;无法进行长时间的复盘总结&#xff0c;从而难以发现企业管理问题&#xff0c;无法持续改善。 随着大数据、工业互联…

Gate相关记录

1 如何在virtual box里面创建共享文件夹 如果没有设置密码&#xff0c;密码就是默认的virtual 需要现在设置-共享文件夹-设置windows的共享路径&#xff0c;然后再执行下面的命令&#xff0c;Gateshare是我自己建的在windows里面的共享文件夹名字 sudo mount -t vboxsf GateS…

中期国际:外汇新手必读:常见的外汇交易误区与避免方法

对于外汇交易的新手来说&#xff0c;了解和避免常见的交易误区是非常重要的。在本文中&#xff0c;我们将带您一起探讨一些常见的误区&#xff0c;并提供一些实用的避免方法&#xff0c;帮助您在外汇市场上取得更好的交易结果。 误区一&#xff1a;盲目跟单 很多新手会犯一个错…

推特营销6大策略助您制霸国际市场

策略一&#xff1a;专业推文中的链接数量 推特群推王研究发现&#xff0c;无链接的推文策略更能激发粉丝互动。因此&#xff0c;并非每条推文都必须附带链接&#xff0c;要保证链接内容与推文实质相关。通过限制带链接推文的数量&#xff0c;能提升粉丝参与度。 策略二&#…

手机直播源码开发,协议讨论篇(三):RTMP实时消息传输协议

实时消息传输协议RTMP简介 RTMP又称实时消息传输协议&#xff0c;是一种实时通信协议。在当今数字化时代&#xff0c;手机直播源码平台为全球用户进行服务&#xff0c;如何才能增加用户&#xff0c;提升用户黏性&#xff1f;就需要让一对一直播平台能够为用户提供优质的体验。…

IntelliJ IDEA下基于Scala实现的Git检查工具

本文使用Scala实现自定义的Git检查工具,读者可以基于本文的示例进行扩展与实现,也可以进行其他应用方向的尝试。 01、Git检查工具 在实现Git检查工具之前需要知道程序究竟要做什么。我们知道,在管理Git分支时可以进行代码合并操作,这样可以将其他开发者提交的内容同步到当前分支…

cloud 问题

eureka 自我保护机制 eureka 是定时去拿 统计最近15分钟的eureka实例正常的心跳占比&#xff0c;如果低于85%&#xff0c;那么就会触发自我保护机制。 触发了自我保护机制&#xff0c;eureka 暂时会把失效的服务保护起来&#xff0c;不让其过期&#xff0c;但是这些服务也不是…

Amazon S3 对象存储Java API操作记录(Minio与S3 SDK两种实现)缘起

缘起 今年(2023年) 2月的时候做了个适配Amazon S3对象存储接口的需求&#xff0c;由于4月份自学考试临近&#xff0c;一直在备考就拖着没总结记录下&#xff0c;开发联调过程中也出现过一些奇葩的问题&#xff0c;最近人刚从考试缓过来顺手记录一下。 S3对象存储的基本概念 …

Git:本地仓库创建和远程绑定

创建远程仓库 登录git网站&#xff0c;创建一个远程仓库 创建时可以选择仓库属性&#xff0c;公共/私有。仓库命名之类。创建完毕后可以在网站上看到仓库所在网址。 创建本地仓库 打开一个文件夹&#xff0c;鼠标右键Git Bash Here&#xff0c;打开git的命令行 git init//…

什么是室温超导?室温超导意味着什么?

前言&#xff1a; 7月22日&#xff0c;韩国一个科学团队发布论文声称“实现了室温超导”&#xff0c;引发了全球关注&#xff0c;全球很多科学实验室都开始着手按照论文来进行实验&#xff0c;尝试验证论文的真实性&#xff0c;因为如果真的可以实现室温超导&#xff0c;那么影…

REI EDI 项目测试流程

在此前的文章REI EDI 项目案例中&#xff0c;我们了解了REI EDI项目的需求以及实现&#xff0c;项目中采用的是知行之云 LIP 解决方案&#xff0c;供应商需要接收来自 REI 的 EDI 850采购订单、EDI 860 采购订单变更&#xff0c;向REI发送 EDI 856 提前发货通知以及EDI 810发票…

【C语言】选择排序

基本原理 先找到数组中最大的那个数&#xff0c;将最大的数放到数组最右端&#xff08;交换a[maxid]和a[len-1]这两个数的位置&#xff09;&#xff0c;然后继续从a[0]到a[len-2]中找到最大的数&#xff0c;然后交换a[maxid]和a[len-2]位置&#xff0c;依次查找交换&#xff0c…

Golang gorm many2many查询

多对多关系 多对多关系&#xff0c;需要用第三张表存储两张表的关系 多对多就必须得加上many2many的tag。article_tags是用来指定第三张表&#xff0c; package mainimport ("gorm.io/driver/mysql""gorm.io/gorm" )type Tag struct {ID uintName …