Linux 可执行内存映射
Linux executable memory mapping
elf executable 包含一个部分 table。当程序加载到内存中时,这些部分将映射到段。
我认为是编译器决定内存中的段地址吗?
你认为操作系统有可能在加载程序时更改段地址吗?
我说的是单个精灵 executable。这不是图书馆。
事实上,我有一个二进制文件。我知道内存中的一个函数地址,我想从外部程序挂钩这个函数。我只是想确保这个地址永远不会改变。我不会重新编译或更改目标程序中的任何内容。
An elf executable contains a section table.
错误:table 部分从完全 linked ET_EXEC
或 ET_DYN
二进制文件中剥离是完全有效的。
This sections are mapped to segments when the program is loaded in memory.
False:部分到段映射发生在静态 link 时间,而不是 运行 时间。
I think it is the compiler which decide the segments address in memory ?
False:静态 linker 为 ET_EXEC
决定了这一点。对于ET_DYN
,static linker和运行time loader配合。
Do you think it is possible for the operating system to change the segments address when the program is loaded.
对于ET_EXEC
,二进制文件总是加载到静态linker linked那个二进制文件的地址。在其他地方加载它会导致程序崩溃。
对于 ET_DYN
,也称为 PIE
二进制,在随机地址加载是可能的 和 预期。
i have a binary. I know a function address in memory and i want to hook this function from an external program. I just want to be sure that this address will never change.
如果二进制文件是 ET_EXEC
类型,所有段总是加载到 linked-at 地址,所以是的。
更新:
在 PIE
二进制文件中,所有东西 将一起移动(main
、foo
、_start
等)通过相同的重定位(重定位通常会从 运行 运行 变化;但是 GDB 禁用地址 space 随机化,所以必须做 (gdb) set disable-randomization off
)。
要在 GDB 中查找重定位,您可以这样做:
(gdb) p &main
(gdb) start
(gdb) p &main
进程开始前 &main
的第一个值应该与 nm test | grep main
的输出相同。第二个值(在进程启动后)应该是重新定位的值(其中 main
落在内存中)。两者的区别是(页面对齐)重定位。
要在 运行 时找到此重定位(从程序本身内部),需要使用 dl_iterate_phdr()
和 dlpi_addr
。 Documentation.
elf executable 包含一个部分 table。当程序加载到内存中时,这些部分将映射到段。 我认为是编译器决定内存中的段地址吗? 你认为操作系统有可能在加载程序时更改段地址吗?
我说的是单个精灵 executable。这不是图书馆。 事实上,我有一个二进制文件。我知道内存中的一个函数地址,我想从外部程序挂钩这个函数。我只是想确保这个地址永远不会改变。我不会重新编译或更改目标程序中的任何内容。
An elf executable contains a section table.
错误:table 部分从完全 linked ET_EXEC
或 ET_DYN
二进制文件中剥离是完全有效的。
This sections are mapped to segments when the program is loaded in memory.
False:部分到段映射发生在静态 link 时间,而不是 运行 时间。
I think it is the compiler which decide the segments address in memory ?
False:静态 linker 为 ET_EXEC
决定了这一点。对于ET_DYN
,static linker和运行time loader配合。
Do you think it is possible for the operating system to change the segments address when the program is loaded.
对于ET_EXEC
,二进制文件总是加载到静态linker linked那个二进制文件的地址。在其他地方加载它会导致程序崩溃。
对于 ET_DYN
,也称为 PIE
二进制,在随机地址加载是可能的 和 预期。
i have a binary. I know a function address in memory and i want to hook this function from an external program. I just want to be sure that this address will never change.
如果二进制文件是 ET_EXEC
类型,所有段总是加载到 linked-at 地址,所以是的。
更新:
在 PIE
二进制文件中,所有东西 将一起移动(main
、foo
、_start
等)通过相同的重定位(重定位通常会从 运行 运行 变化;但是 GDB 禁用地址 space 随机化,所以必须做 (gdb) set disable-randomization off
)。
要在 GDB 中查找重定位,您可以这样做:
(gdb) p &main
(gdb) start
(gdb) p &main
进程开始前 &main
的第一个值应该与 nm test | grep main
的输出相同。第二个值(在进程启动后)应该是重新定位的值(其中 main
落在内存中)。两者的区别是(页面对齐)重定位。
要在 运行 时找到此重定位(从程序本身内部),需要使用 dl_iterate_phdr()
和 dlpi_addr
。 Documentation.