【发布时间】:2021-02-28 18:36:28
【问题描述】:
我有以下汇编函数(已经用 objdump 显示)
0000000000000000 <add>:
0: b8 06 00 00 00 mov $0x6,%eax
5: c3 retq
现在我用 C 编写了以下代码:
#include <stdio.h>
typedef int (*funcp) (int x);
unsigned char foo[] = {0xb8,0x06,0x00,0x00,0x00,0xc3};
int main(void)
{
int i;
funcp f = (funcp)foo;
i = (*f);
printf("exit = %d\n", i);
return 0;
}
在全局变量 foo 中,我在汇编中输入了我的函数的内存地址并尝试执行它,但它没有按预期返回 6。 如何为其内存地址执行函数?此外,我在哪里可以对这个主题进行更多研究?
obs:有时我收到分段错误(核心转储)错误
【问题讨论】:
-
首先,您必须使用
()来调用函数。 -
数据部分通常是不可执行的,这意味着你的代码会遇到分段错误。
-
gcc -z execstack temp1.c为我工作。我得到6作为输出。 -
@fuz:
-z execstack在 Linux 上使 all 可读页面可执行,直到最近的内核版本。 Linux 的 ELF 程序加载器在看到可执行的 GNU 堆栈元数据时会设置 read-implies-exec 进程“个性”标志。 Linux default behavior against `.data` section -PT_GNU_STACK == RWX不再暗示 exec-all;我刚刚更新了我的 Arch Linux 并且gcc -zexecstack不会使 .data(或.rodata)可执行。另请参阅Unexpected exec permission from mmap...。 -
@fuz:是的,
__attribute__((section(".text")))有效。我收到 Assembler 消息:/tmp/ccNetmKQ.s:28: Warning: ignoring changed section attributes for .text 但它确实运行。 godbolt.org/z/draGeh。在我的桌面上,-Wl,-N使其无法链接:/usr/bin/ld: cannot find -lgcc_s。 这两件事(文本部分中的数组和读/写文本部分)对于非常量可执行数组都是必需的。
标签: c linux assembly x86 disassembly