我使用裸函数在程序运行时修补程序的一部分。我可以在Windows的VC++中轻松做到这一点。我试图在Linux中做到这一点,似乎gcc不支持裸函数。用裸函数编译代码给我带来了这样的好处:警告:'naked'属性指令被忽略。在CentOS 5.5 i386下编译。
piah890a1#
根据docs,GCC仅在某些平台(ARM、AVR、MCORE、RX和SPU)上支持裸属性:
一月一日:在ARM、AVR、MCORE、RX和SPU端口上使用此属性表示指定函数不需要编译器生成的序言/结尾序列。由程序员提供这些序列。裸函数中可以安全包含的唯一语句是没有操作数的asm语句。所有其他语句,包括局部变量的声明、if语句等,裸函数应该用来实现汇编函数的主体,同时允许编译器为汇编器构造必需的函数声明。
我不知道为什么。
xdyibdwo2#
===更新===
截至2023年,他们工作:
__attribute__((naked)) void my_write(int fd, char const* str, int size) { asm ( " 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() { my_write(1, "hi\n", 3); my_write(1, "bye\n", 4); }
使用gcc version 10.2.1 20210110 (Debian 10.2.1-6)编译gcc -m32 -nostdlib my_write.c
gcc version 10.2.1 20210110 (Debian 10.2.1-6)
gcc -m32 -nostdlib my_write.c
===老答案===
在x86上,您可以通过在全局范围内使用asm来解决问题:
void my_write(int fd, const void *buf, int count); asm ( ".global my_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() { my_write(1, "hi\n", 3); my_write(1, "bye\n", 4); }
naked也列在x86 function attributes中,所以我认为它适用于较新的gcc。
naked
up9lanfz3#
这是一个丑陋的解决方案。链接到目标架构的.asm文件。
ndh0cuux4#
GCC只支持ARM和其他嵌入式平台上的裸函数。http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html此外,您所做的事情本质上是不安全的,因为您无法保证正在修补的代码在程序运行时不会执行。
4条答案
按热度按时间piah890a1#
根据docs,GCC仅在某些平台(ARM、AVR、MCORE、RX和SPU)上支持裸属性:
一月一日:在ARM、AVR、MCORE、RX和SPU端口上使用此属性表示指定函数不需要编译器生成的序言/结尾序列。由程序员提供这些序列。裸函数中可以安全包含的唯一语句是没有操作数的asm语句。所有其他语句,包括局部变量的声明、if语句等,裸函数应该用来实现汇编函数的主体,同时允许编译器为汇编器构造必需的函数声明。
我不知道为什么。
xdyibdwo2#
===更新===
截至2023年,他们工作:
使用
gcc version 10.2.1 20210110 (Debian 10.2.1-6)
编译gcc -m32 -nostdlib my_write.c
===老答案===
在x86上,您可以通过在全局范围内使用asm来解决问题:
naked
也列在x86 function attributes中,所以我认为它适用于较新的gcc。up9lanfz3#
这是一个丑陋的解决方案。链接到目标架构的.asm文件。
ndh0cuux4#
GCC只支持ARM和其他嵌入式平台上的裸函数。http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
此外,您所做的事情本质上是不安全的,因为您无法保证正在修补的代码在程序运行时不会执行。