鉴于main.c
:
#include <stdio.h>
void (*fn_ptr)(void);
void foo(void);
void bar(void) {
printf("bar\n");
}
int main(void) {
fn_ptr = bar;
foo();
}
和foo.s
:
extern fn_ptr
global foo
foo:
mov rax, fn_ptr
call [rax]
ret
我们可以像这样运行并编译它:
clear &&
nasm foo.s -f elf64 -O0 &&
clang main.c foo.o -z noexecstack &&
./a.out
成功打印bar
,但同时也打印了一条警告:
/usr/bin/ld: foo.o: warning: relocation against `fn_ptr' in read-only section `.text'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
bar
我找不到在 NASM 中调用全局函数指针的任何在线示例,并将其更改为mov rax, fn_ptr wrt ..plt
或call [fn_ptr wrt ..plt]
打印此错误:
foo.s:7: error: ELF format cannot produce non-PC-relative PLT references
-z noexecstack
(如果有人想知道消除了什么警告):
/usr/bin/ld: warning: foo.o: missing .note.GNU-stack section implies executable stack
/usr/bin/ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker