我在程序运行时使用裸功能来修补程序的各个部分。我可以在Windows中的VC ++中轻松完成此操作。我试图在Linux中这样做,似乎gcc不支持裸功能。用裸函数编译代码给了我:警告:'naked'属性指令被忽略了。在CentOS 5.5 i386下编译。
答案 0 :(得分:4)
裸属性仅在某些平台(ARM,AVR,MCORE,RX和SPU)上由GCC根据docs支持:
<强>
naked
强>: 在ARM,AVR,MCORE,RX和SPU端口上使用此属性 表明指定的函数不需要序言/结尾 编译器生成的序列。这取决于程序员 提供这些序列。唯一可以安全的陈述 包含在裸函数中的是asm语句,没有 操作数。所有其他陈述,包括当地的声明 应避免使用变量,if语句等。裸 函数应该用于实现程序集的主体 函数,同时允许编译器构造必需的 汇编程序的函数声明。
我不确定为什么。
答案 1 :(得分:1)
GCC仅支持ARM和其他嵌入式平台上的裸功能。 http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
此外,您正在做的事情本质上是不安全的,因为如果程序正在运行,您无法保证您正在修补的代码没有执行。
答案 2 :(得分:1)
这是一个丑陋的解决方案。链接目标体系结构的.asm文件。
答案 3 :(得分:0)
在x86上,您可以在全局范围内使用asm来解决此问题:
int write(int fd, const void *buf, int count);
asm
(
".global write \n\t"
"write: \n\t"
" pusha \n\t"
" movl $4, %eax \n\t"
" movl 36(%esp), %ebx \n\t"
" movl 40(%esp), %ecx \n\t"
" movl 44(%esp), %edx \n\t"
" int $0x80 \n\t"
" popa \n\t"
" ret \n\t"
);
void _start()
{
#define w(x) write(1, x, sizeof(x));
w("hello\n");
w("bye\n");
}
同样naked
列在x86 function attributes中,所以我认为它适用于较新的gcc。