ARM ELF的函数重定位与x86是一致的,但由于汇编指令不同,再鼓捣一遍。

示例代码:

#include <stdio.h>
#include <stdlib.h> int main () {
puts ("Hello world");
sleep (1);
FILE *fp = fopen ("1.c", "r");
fclose (fp);
exit (0);
}

通过 readelf -r 可以查看ELF中所有需要重定位的函数,我们以fopen()函数为例,分析其重定位过程。

$ arm-linux-androideabi-readelf -r elf_2

Relocation section '.rel.plt' at offset 0x278 contains 7 entries:
Offset Info Type Sym.Value Sym. Name
00009ff4 00000516 R_ARM_JUMP_SLOT 00000000 fopen

首先main()函数中,通过 bl 82f4调用fopen(),82f4是一个16进制表示的地址,位于.plt节。

$ arm-linux-androideabi-objdump -d elf_2
000083c8 <main>:
...
8404: ebffffba bl 82f4 <fopen@plt>
 Disassembly of section .plt:

 000082f4 <fopen@plt>:
82f4: e28fc600 add ip, pc, #0, 12 @由于ARM三级流水,PC = 0x82f4 + 0x8
82f8: e28cca01 add ip, ip, #4096
82fc: e5bcfcf8 ldr pc, [ip, #3320]! @ip + 0xcf8 = 0x9ff4

以上三条指令执行完,从0x9ff4位置取值给pc,完成间接寻址的跳转。看一下0x9ff4处内容:

(gdb) p/x *0x9ff4
$1 = 0x82b0

程序跳转到0x82b0位置:

Disassembly of section .plt:

000082b0 <__libc_init@plt-0x14>:
82b0: e52de004 push {lr} ; (str lr, [sp, #-4]!)
82b4: e59fe004 ldr lr, [pc, #4] ; 82c0 <__libc_init@plt-0x4>
82b8: e08fe00e add lr, pc, lr
82bc: e5bef008 ldr pc, [lr, #8]!
82c0: 00001d18 andeq r1, r0, r8, lsl sp

可以看到,这是.plt节的开始位置,IDA帮助我们做了一些显示的优化,所以其汇编结果与objdump看到的不同,它假装替我们完成了GOT的重定位过程,实际并非如此:

@ida的显示结果
.got:00009FF4 fopen_ptr DCD __imp_fopen

下面解析一下.plt节开头的这几条指令:

@ 1. stack <- lr

@ 2. lr <- 0x1d18

@ 3. lr <- 0x82c0 + 0x1d18 = 0x9fd8

@ 4. pc <- [0x9fd8 + 0x8], lr <- 0x9fd8 + 0x8 = 0x9fe0

发现程序最终从0x9fe0地址处取值,并间接寻址将其作为地址跳转过去执行。使用gdb发现,此处静态值为0x0。显然这块地址内容,要由程序运行时动态补充的,否则这条指令将产生0地址访问异常。

(gdb) p/x *0x82c0
$1 = 0x1d18
(gdb) p/x *0x9fe0
$2 = 0x0
(gdb)

原来GOT的前3项,是为系统预留的(GOT[0][1][2]),其中GOT[1]中是ELF中所有动态库构成的链表的指针,GOT[2]是_dl_runtime_resolve函数指针。这个函数将具体完成函数的重定向过程,并将结果反馈到GOT表中。

因此上面静态分析时,GOT这3个表项是没有值的,它们由加载器动态填充。

以前画的x86的图,同样适应 ARM:

ARM ELF函数重定位的更多相关文章

  1. Linux pwn入门教程(10)——针对函数重定位流程的几种攻击

    作者:Tangerine@SAINTSEC 本系列的最后一篇 感谢各位看客的支持 感谢原作者的付出一直以来都有读者向笔者咨询教程系列问题,奈何该系列并非笔者所写[笔者仅为代发]且笔者功底薄弱,故无法解 ...

  2. CTF丨Linux Pwn入门教程:针对函数重定位流程的相关测试(下)

    Linux Pwn入门教程系列分享已接近尾声,本套课程是作者依据i春秋Pwn入门课程中的技术分类,并结合近几年赛事中出现的题目和文章整理出一份相对完整的Linux Pwn教程. 教程仅针对i386/a ...

  3. ELF学习--重定位文件

    add.c int data = 1;int bss;const int rodata = 1;int add(int num1, int num2){ int sum = 0; sum = num1 ...

  4. S3C2440—10.代码重定位

    文章目录 一.启动方式 1.1 NAND FLASH 启动 1.2 NOR FLASH 启动 二. 段的概念 2.1 重定位数据段 2.2 加载地址的引出 三.链接脚本 3.1 链接脚本的引入 3.2 ...

  5. 鸿蒙内核源码分析(重定位篇) | 与国际接轨的对外部发言人 | 百篇博客分析OpenHarmony源码 | v55.01

    百篇博客系列篇.本篇为: v55.xx 鸿蒙内核源码分析(重定位篇) | 与国际接轨的对外部发言人 | 51.c.h.o 加载运行相关篇为: v51.xx 鸿蒙内核源码分析(ELF格式篇) | 应用程 ...

  6. IOAPIC重定位中断处理函数思路整理

    因为小可并非硬件编程出身,汇编基础又比较差...所以刚开始理解利用IOAPIC重定位技术的时候相当困难. 何为IOAPIC? 首先,必须认识到它是一个硬件,可编程的硬件.我理解的它在整个流程中的作用如 ...

  7. ELF Format 笔记(十)—— 重定位(relocation)

    ilocker:关注 Android 安全(新手) QQ: 2597294287 重定位就是把符号引用与符号定义链接起来的过程,这也是 android linker 的主要工作之一. 当程序中调用一个 ...

  8. ELF 动态链接 - so 的 重定位表

    动态链接下,无论时可执行文件还是共享对象,一旦对其他共享对象有依赖,也就是所有导入的符号时,那么代码或数据中就会有对于导入符号的引用.而在编译时期这些导入符号的确切地址时未知的.只有在运行期才能确定真 ...

  9. 一款多功能的移动端滚动选择器,支持单选到多选、支持多级级联、提供自定义回调函数、提供update函数二次渲染、重定位函数、兼容pc端拖拽等等..

    https://github.com/onlyhom/mobileSelect.js/blob/master/docs/README-CN.md mobileSelect.js 一款多功能的移动端滚动 ...

随机推荐

  1. AWS EC2 MySQL迁移到RDS案例

    Amazon Relational Database Service (Amazon RDS) 是一种Web 服务,可让用户更轻松地在云中设置.操作和扩展关系数据库.它可以为行业标准关系数据库提供经济 ...

  2. Python的字典dict和set

    Python内置了字典:dict的支持,dict全称dictionary: 表达式为dict{key,value} 使用键值对来存储数据 eg: 使用dict来存储姓名和分数 d = {'bob':2 ...

  3. rpc框架实现(持续更新)

    网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,rpc基于长连接的远程过程调用应用而生. 一:A服务调用B服务,整个调用过程,主要经历如下几个步骤:(摘自 ...

  4. Vuejs选项卡案例

    css .active { color: red; border-bottom: 1px solid red; } ul li { padding: 0 15px; float: left; list ...

  5. Python日志、序列化、正则模块

    使用Python内置模块的目的:拿来别人已经写好的模块功能,直接import内置模块使用,简化程序,避免重复造轮子的过程,提示自己的开发效率: 一. loging日志模块: 1. loging模块可以 ...

  6. 2.python函数编程-filter函数

    fileter功能主要使用在需要对数据进行多种操作,并对数据进行过滤的操作. 普通函数实现: movie = ['sb_alex', 'wupei', 'tiger', 'goosb','xxfd', ...

  7. centos 安装 TortoiseSVN svn 客户端

    1 安装 svn客户端 yum install -y subversion 2 常用命令操作   检出命令 svn checkout http://svn.com/path

  8. c语言亲缘线程通过管道通信一些疑问

    亲缘线程在使用管道时,发现第一次使用管道进行进行通信完全正常(./a.out 1),但当重新运行并使用新管道文件时候出现数据无法读取的问题(./a.out 2)(./a.out 3),甚至出现子线程部 ...

  9. [POJ2985]The k-th Largest Group

    Problem 刚开始,每个数一个块. 有两个操作:0 x y 合并x,y所在的块 1 x 查询第x大的块 Solution 用并查集合并时,把原来的大小删去,加上两个块的大小和. Notice 非旋 ...

  10. [POJ3416]Crossing

    Problem 给你n个点,m个询问,每个询问有x, y 问以(x,y)为原点建立的平面直角坐标系分割的第一象限和第三象限的点数和减去第二象限和第四象限的点数和 Solution 用2个树状数组维护一 ...