04 里面的重定位表没讲完,这里继续,我们说过重定位的类型有很多,04 里面基本只介绍了一种,就是 plt 表。重定位不仅仅发生在代码里面,还会发生在数据里面,比如so程序里面对一些全局变量的引用,它们的重定位信息是放在另外一个表里面:

对应 section 的:

里面的结构体与 rela.plt 的结构体是一样的。以第一项为例:

0x05D690 表示符号地址。
0x0403 表示符号重定位类型。由于它不属于符号表,所以索引为0。0x403 表示的重定位类型是:
对应的逻辑:
load_bias,就是第一个可加载段所在的位置,需要是页对齐的,否则:
所以,我们只需要在这个位置按照上面的方式计算好地址填进去就行。
打印一下 ls 这个 elf 有哪些类型:
发现只有两种类型,非常nice。
0x401的逻辑如下(8.0 逻辑):
8.0 相比 2.0 没啥变化,就是多了一个 addend。
傀儡进程
实验失败了,还没分析出问题,可以不用往下看
前面,我们分析了重定位表
- rela.plt
- rela.dyn
ls elf 文件里面的重定位类型一共有3种:
- 0x401
- 0x402
- 0x403
我们可以手动将其重定位:
主要是利用 dlopen 与 dlsym 这两个函数,从依赖的 so 文件里面定位到符号地址。拿到地址之后,就根据重定位类型回填符号地址就行。
做完之后,我们就可以主动调用入口地址,然后执行这个 elf 文件:
由于ls在执行的时候,是使用的栈来传递参数,所以我们使用额外的8个参数来占用寄存器,后面真正的参数 argc,argv 放在第9 与 10 位置,这样这两个参数就分配在了栈中。
我们将 ls 入口地址改成死循环,看一下栈中的数据,好模仿参数传递:


栈中,第一个参数是 1,第二个参数是一个地址,去地址看看:

第二个参数是字符串:
/data/local/tmp/ls后面是一些环境变量。也是放在栈中的。
参数都模仿好之后,调用入口地址,发现报了
Segmentation fault ,用 IDA 调试发现是一个空指针错误,寄存器访问了一个 0 地址,暂时没找到原因。如果能成功运行,我们就可以将 ls 这个程序运行到我们的进程中,并执行里面的功能,非常的神奇。










