从second answer for this question中可以看出,使用节的名称从内部获取指向程序特定部分的指针非常简单。使用libelf
,只需打开程序自己的文件,循环遍历所有部分(由Elf64_Shdr
结构表示),当部分名称与您想要的部分匹配时停止并使用存储在sh_addr
结构的Elf64_Shdr
元素。在这种情况下,获取所需指针非常简单,因为它是在ELF可执行文件中定义的。
但是,假设您有一个使用动态库的程序,您需要获取指向该动态库的一部分的指针。由于其部分的地址是在运行时定义的,如何获得指向动态库部分的指针?
顺便说一句,动态库和主程序本身都有一个具有相同名称的部分(这是我需要获取指针的部分)。因此,在这种情况下,这两个具有相同名称的部分是否可能相邻存储在内存中,因此我只需要获取指向主文件部分的指针(如我在第一段中所述)并添加偏移量到达动态库部分?
答案 0 :(得分:5)
从内部获取指向程序特定部分的指针非常简单
不一定。部分表在运行时实际上并不需要,并且可以完全剥离(只有段很重要,而不是段)。
由于其部分的地址是在运行时定义的,如何获得指向动态库部分的指针?
该库与主可执行文件完全不同。主要区别在于库通常链接在地址0
(主可执行文件不是),并且由运行时加载程序重新定位到其他常量偏移量。
一旦你知道了这个偏移量,只需将它添加到section start(你可以从readelf -S foo.so
或libelf找到),并且瞧:你已经得到了该部分的运行时地址。
那么如何找到给定共享库的重定位?
非常优雅的解决方案(已经由Nick建议)是解析/proc/self/maps
。
更好的解决方案是使用(glibc特定的)dl_iterate_phdr
。文档here。您需要使用dlpi_addr
。
答案 1 :(得分:0)
这很简单,这里是一个例子:
ImageCollectionViewController