Android通过修改ELF实现注入

news/2024/11/20 12:38:49/文章来源:https://www.cnblogs.com/ovo-fisherman/p/18556620

Android通过修改ELF实现注入

在实现外挂的过程中,是通过将外挂的模块进行注入到对应的游戏进程中去实现的,我们可以通过相同的原理去注入so,来实现so注入进程实现frida-gadget的注入

首先是通过ELF文件的修改注入so

+------------------------+
| ELF Header            | 文件头,描述整体结构和入口点
+------------------------+
| Program Header Table  | 程序头表,描述加载的段
+------------------------+
| Segment/Sections      | 实际段内容,如代码、数据等
+------------------------+
| Section Header Table  | 段表,描述每个段的位置和功能
+------------------------+

这里是ELF文件的文件结构类型

ELF Header (ELF 文件头)

作用:描述文件类型、目标架构和入口点等元数据。

字段 描述
e_ident 魔数、文件类型标识、架构信息 (32/64 位,大小端)
e_type 文件类型(可执行文件、共享库、目标文件等)
e_machine 目标架构(如 x86、ARM 等)
e_version ELF 版本
e_entry 程序入口点虚拟地址
e_phoff 程序头表在文件中的偏移
e_shoff 段表在文件中的偏移
e_flags 与架构相关的标志
e_ehsize ELF Header 的大小
e_phentsize 程序头表中每个条目的大小
e_phnum 程序头表中的条目数
e_shentsize 段表中每个条目的大小
e_shnum 段表中的条目数
e_shstrndx 段表中字符串表的索引

** Program Header Table (程序头表)**

作用:描述进程运行时需要加载到内存的段信息,仅对可执行文件和共享库有用。

字段 描述
p_type 段类型(如 PT_LOAD 表示加载段)
p_offset 段在文件中的偏移
p_vaddr 段在内存中的虚拟地址
p_paddr 段在内存中的物理地址(通常忽略)
p_filesz 段在文件中的大小
p_memsz 段在内存中的大小
p_flags 段的访问权限(读、写、执行)
p_align 段在内存中的对齐粒度

常见段类型:

  • PT_LOAD:加载到内存的段,通常对应 .text.data 等。
  • PT_DYNAMIC:动态链接相关信息。
  • PT_INTERP:解释器路径(动态加载器)。
  • PT_NOTE:注释段,通常用于核心转储文件。
  • PT_NULL:无效条目,表示结束。

Program Header Table中是包含了对于程序运行时的进程需要加载到内存的数据,而其中就保留对于依赖库,函数库..的相关函数信息,so文件的信息也包含在内。

所有我们要注入so到进程中去,主要的过程就是去实现so的注册以及写入

修改 DT_STRTAB 指向的新字符串表

通过定位 .dynstr 段找到对应的当前字符串表的位置,里面包含了各种字符串数据,通过也包含了现有 .so 名称列表

创建新的字符串表,由于修改原字符串表会使得其下的所有文件偏移都被修改了,为了使得文件偏移都不变,我们就继续保留原本的Program Header Table,同时将原字符串表复制到文件尾部,添加新的 .so 名称(如 frida-gadget.so)。

更新 PT_LOAD 表项,由于新的字符串表要被映射到新的内存,需要通过PT_LOAD来实现

比如这样:

原始 Program Header Table:

Entry Index p_type p_offset p_vaddr p_filesz p_memsz p_flags
0 PT_LOAD 0x00000040 0x08000000 0x00100000 0x00100000 R+E
1 PT_LOAD 0x00100040 0x08001000 0x00001000 0x00001000 RW
... ... ... ... ... ... ...

新 Program Header Table(文件末尾):

Entry Index p_type p_offset p_vaddr p_filesz p_memsz p_flags
0 PT_LOAD 0x00000040 0x08000000 0x00100000 0x00100000 R+E
1 PT_LOAD 0x00100040 0x08001000 0x00001000 0x00001000 RW
... ... ... ... ... ... ...
5 PT_LOAD 文件尾偏移 映射地址 大小 大小 R

使得我们添加在文件末尾的数据被真实的加载映射了

修改动态段 (.dynamic):因为添加了新的字符串数目,对应的字符串表的虚拟地址以及字符串总数目也会改变

更新 DT_STRTABDT_STRSZ

  • 修改 DT_STRTAB,使其指向新字符串表的虚拟地址。
  • 修改 DT_STRSZ,更新字符串表的总大小。

新增 DT_NEEDED 条目

  • 在 .dynamic 的尾部新增一个条目:
    • d_tagDT_NEEDED
    • d_val:新字符串表中 .so 名称的偏移。

同时更新ELF header 的e_phoff,这里指向的是Program Header Table的位置,所有设置为新的Program Header Table

原始的ELF文件结构:

+------------------------+
| ELF Header            | 包含文件元信息(如入口点、PHT/SHT 偏移等)
+------------------------+
| Program Header Table  | PHT,描述 Segments 的加载信息
+------------------------+
| Segment 1 (.text)     | 包含代码段
+------------------------+
| Segment 2 (.data)     | 包含已初始化的全局和静态变量
+------------------------+
| Segment 3 (.bss)      | 包含未初始化的全局和静态变量(运行时分配)
+------------------------+
| Section Header Table  | SHT,描述 Sections 的信息
+------------------------+

注入 .so 后的 ELF 文件结构

+------------------------+
| ELF Header            | 更新了 e_phoff 指向新的 PHT 位置
+------------------------+
| (原) Program Header    | 仍在文件起始,但未被使用
+------------------------+
| Segment 1 (.text)     | 包含代码段
+------------------------+
| Segment 2 (.data)     | 包含已初始化的全局和静态变量
+------------------------+
| Segment 3 (.bss)      | 包含未初始化的全局和静态变量
+------------------------+
| Section Header Table  | SHT,描述 Sections 的信息
+------------------------+
| 新字符串表 (.dynstr)   | 新增,包含注入的 .so 名字
+------------------------+
| 新 Program Header Table| 移动到文件末尾,新增 PT_LOAD 表项
+------------------------+

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

母亲的回头

写在前面392 字 | 亲情 | 思考 | 陪伴 | 细节 | 情感 | 感触 | 体验 | 时间正文等车。我说,自己一个人就可以了,都等,空耗两个人的时间。母亲不肯。司机迟到了十多分钟。这过程中,母亲很焦急。我上了车。母亲敲了敲司机的车窗。司机将窗摇下来,听见她问收不收现金。司机点…

[68] (NOIP集训) NOIP2024 加赛 5

恐将成为我改题时间最长的一场(也是分最低的一场)码长断崖式领先了 flowchart TBA(暴力操作)style A color:#ffffff,fill:#00c0c0,stroke:#ffffff 首先你肯定要让小于(等于)中位数的数变小,将较大的值变小是毫无意义的,因为即使你完全不管他们,也不会对答案造成任何影响…

考研打卡(23)

开局(23) 开始时间 2024-11-20 11:07:52 结束时间 2024-11-20 12:01:50十一点醒了数据结构已知 10 个元素 (54,28,16,34,73,62,95,60,26,43) , 按照依次插入的方法生成一棵二叉排序树,查找值为 62 的结点所需比较次数为_____(复旦大学 2014年) A 2 B 3 C 4 D 5B…

apache直接打印php代码或直接下载问题

在/etc/httpd/conf/httpd.conf中的添加圈出的代码:下载问题,直接执行,然后重启apache: yum install mod_php

Java易混知识点列表比较

前前后后遇到了一些容易混淆的知识点,特地做了表格专栏捋清思路类一级成员与实例成员类一级成员 实例成员属于 类本身 类创建的实例对象举例 static(变量/方法/初始化块)、内部类 普通成员直接访问 类名.member 对象.memberclass superc{int i=5;void show(){System.out.pri…

新兴数据仓库设计与实践手册:从分层架构到实际应用(二)

本手册将分为三部分发布,以帮助读者逐步深入理解数据仓库的设计与实践。第一部分介绍数据仓库的整体架构概述; 第二部分深入讨论ETL在数仓中的应用理论,ODS层的具体实现与应用; 第三部分将围绕DW数据仓库层、ADS层和数据仓库的整体趋势展开;通过这样的结构,您可以系统地学…

【跟着阿舜学音乐-笔记】1.14代理和弦

三和弦代理和弦 代理和弦是指两个和弦从功能上能够相互替代,彼此代替对方执行相互的功能。 这意味着互为代理和弦的两个和弦在功能上有一定的互通性,这就是1.12提到的——拥有两个以上共同音的称为代理和弦。 同时,这种功能上的共通性也有着一定的强弱,在同属关系下,关系大…

TCP/UDP套接字基础编程及拓展

本文章旨在进行TCP/UDP基础套接字编程并在其基础上进行更新拓展。一、环境 1.1 客户端:windows宿主机 1.2 服务器端:Linux虚拟机 1.3 注意事项 测试套接字编程通信时,先确保C/S能互相ping通,且双方主机防火墙允许目的端口号为“创建的端口号”的数据包通过。 二、代码 2…

6款Win电脑高效实用办公软件推荐

作为打工人,是不是总觉得工作效率提不上去呢?今天我就来给大家分享 6 款办公超实用的软件,让你的工作事半功倍! 一、WPS 比office更适合职场小白上手的办公软件!它涵盖了文字、表格、演示等多种功能。写文档时,丰富的模板库能让你快速找到灵感,各种排版和编辑工具一应俱…

bladeX物联网平台私库操作处理步骤

(一)获取对方私库代码并上传到自己的gitlab 步骤 1: 克隆对方的私有仓库 首先,您需要在本地计算机上克隆对方的私有仓库。这通常需要使用HTTPS或SSH URL,并且可能需要身份验证(如用户名和密码、SSH密钥等)。# 假设您已经配置了SSH密钥或知道HTTPS的用户名和密码 git cl…

震撼推荐!性能测试全攻略:零基础也能玩转性能测试!

1、提起性能测试,你的第一反应是什么? 当提到性能测试,你的第一反应是什么?是不屑一顾,认为它很简单,没发展前途、没技术含量?还是觉得它太难了,高不可攀,每当遇到系统的疑难杂症时,抓耳挠腮,无从下手? 很多IT从业人员,认为"性能测试仅仅只是测试的工作,会用…