。 兹向您提供与主要可执行部分相对应的<条码>指示链接。
电话:dl_iterate_phdr
还将主要可执行的条目退回, 每一首批执行背书。
链接图中l_addr = 0
,以及dlpi_addr = 0
时使用dl_iterate_phdr
,可能会使你感到困惑。
This is happening, because l_addr
(and dlpi_addr
) don t actually record the load address of an ELF image. Rather, they record the relocation that has been applied to that image.
主要可执行部分通常在x400000(关于x86_64-030)或0x08048000
(关于六LC/86)上安装,并装在同一地址(即不迁移)。
但是,如果你把你的可执行性与-pie
的旗帜联系起来,则该旗帜将连接0x0
,,并移至其他地址。
因此,你们如何去ELF负责人?
<>2023 最新情况:
是否采用一种较简单的方法(如果依赖无证件的细节),仅打电话dladdr
,l_ld Address in the structlink_map
,然后从中删除dli_fbase
? Simon Kissane
确实如此。 更简单的解决办法:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <link.h>
#include <stdio.h>
int main()
{
void *dyn = _DYNAMIC;
Dl_info info;
if (dladdr(dyn, &info) != 0) {
printf("a.out loaded at %p
", info.dli_fbase);
}
return 0;
}
gcc -g -Wall -Wextra x.c -ldl && ./a.out
a.out loaded at 0x556433ea0000 # high address here because my GCC defaults to PIE.
gcc -g -Wall -Wextra x.c -ldl -no-pie && ./a.out
a.out loaded at 0x400000
gcc -g -Wall -Wextra x.c -ldl -no-pie -m32 && ./a.out
a.out loaded at 0x8048000
原始2012年解决办法:
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <link.h>
#include <stdio.h>
#include <stdlib.h>
static int
callback(struct dl_phdr_info *info, size_t size, void *data)
{
int j;
static int once = 0;
if (once) return 0;
once = 1;
printf("relocation: 0x%lx
", (long)info->dlpi_addr);
for (j = 0; j < info->dlpi_phnum; j++) {
if (info->dlpi_phdr[j].p_type == PT_LOAD) {
printf("a.out loaded at %p
",
(void *) (info->dlpi_addr + info->dlpi_phdr[j].p_vaddr));
break;
}
}
return 0;
}
int
main(int argc, char *argv[])
{
dl_iterate_phdr(callback, NULL);
exit(EXIT_SUCCESS);
}
$ gcc -m32 t.c && ./a.out
relocation: 0x0
a.out loaded at 0x8048000
$ gcc -m64 t.c && ./a.out
relocation: 0x0
a.out loaded at 0x400000
$ gcc -m32 -pie -fPIC t.c && ./a.out
relocation: 0xf7789000
a.out loaded at 0xf7789000
$ gcc -m64 -pie -fPIC t.c && ./a.out
relocation: 0x7f3824964000
a.out loaded at 0x7f3824964000
最新情况:
为什么人页说“基本地址”而不是迁移?
a bug ;-
我猜测,在<条码>之前很久才写上人页(<>t/code>和pie
>和ASLR
。 如果没有事先的联系,共享图书馆总是与在<代码>0x0上的载荷联系在一起,然后<代码>re place和base<
上载荷也一样。
当信息指主要可起诉时,姓名指空洞吗?
这是一种执行事故。
这一工作方式是,可执行的舱面条码<>开放式(2)将开放式卷宗说明交给装载人(见auxv[ ]
矢量,作为AT_EXECFD
)。 每一thing 装载者通过阅读该记录员获得的可执行性。
UNIX无法轻易地将档案描述重新贴上其公开名称。 一种情况是,UNIX支持硬链条,并且可能有多个档案名称来查阅同一档案。
Newerlav kernels还以以下名称通过:execve(2)
可执行(也载于auxv[]
,作为AT_EXECFN
。 但这是任择性的,即使在通过时,glibc don t 把它列入.l_name
/dlpi_name
,以便不中断现有的方案,因为这些方案依赖于空名。
相反,glibc在progname
和上省略了这一名称。
装载机coud/readlink(2)
关于使用AT_EXECFN
的系统名称,但/proc
的文档系统没有保证安装,因此有时仍用空名离开。