我正在玩ASM,字节码和可执行内存。
我正在使用echo -e "<asm instruction here>" | as -o /dev/null -64 -al -msyntax=att
来“编译”我的代码。无论如何,我注意到movq 2, %rax
会产生0000 488B0425 02000000
,但call printk
和call printf
都会产生0000 E8000000 00
,我相信这是因为as
对printk
或printf
一无所知。
我的问题是如何获取这些函数的地址,以便在字节码中使用它们?
答案 0 :(得分:2)
汇编程序不知道外部符号的值。它写入一个包含多组数据的文件。一组数据是放入程序文本部分的字节。另一组数据是关于所使用的外部符号的信息,以及当解析这些外部符号时对文本部分中的字节进行的调整。汇编程序生成的文件不包含任何有关来自外部库的符号值的信息。
链接器解析外部符号。生成静态链接的可执行文件时,它将完全解析外部符号。生成动态链接可执行文件时,在程序执行期间完成外部符号的解析。
静态链接可执行文件后,您可以使用nm
之类的工具查看其中的符号值(如果它们尚未被剥离)。然后你可以在汇编中使用这些值。但是,如果程序以不同的方式链接,那么将这些值硬编码到汇编中将会失败,从而将例程放在不同的位置。
如果动态链接可执行文件,则必须检查执行程序以确定其外部符号的放置位置。同样,理论上你可以在汇编中使用这些值,但这比使用静态链接更容易失败,特别是在故意更改可执行文件中使用的地址以阻止恶意代码的系统上。
将符号值硬编码到汇编中不是编写汇编语言或其他代码的常规方法,除了学习或专用调试或系统检查外,不应该这样做。
答案 1 :(得分:0)
使用适当的工具检查目标文件。假设有任何Unix,请使用
nm -AP file.o
查看所有符号(函数和变量)的地址。由于printf可能在库中,因此在该库上运行nm
以获得相同的效果。