在MacOS X下,如何在GCC中使用内联汇编程序调用write系统调用?
在MacOS X下,如何在GCC中使用内联汇编程序调用write系统调用?,c,gcc,assembly,system-calls,inline-assembly,C,Gcc,Assembly,System Calls,Inline Assembly,writesyscall具有以下功能原型: size_t write(int, const void *buf, size_t nbytes); 如何在MacOS X下使用GCC中的内联汇编程序调用writesyscall?这类问题的一般解决方案:编写一个简短的测试程序,执行您感兴趣的write()调用,然后使用GCC-S生成程序集或使用otool反汇编二进制文件;了解write()调用是如何组装的,并将其转换为相应的内联程序集 (编辑)要查看实际的系统调用,请在汇编代码中跟随库调用。在wri
write
syscall具有以下功能原型:
size_t write(int, const void *buf, size_t nbytes);
如何在MacOS X下使用GCC中的内联汇编程序调用
write
syscall?这类问题的一般解决方案:编写一个简短的测试程序,执行您感兴趣的write()调用,然后使用GCC-S
生成程序集或使用otool
反汇编二进制文件;了解write()调用是如何组装的,并将其转换为相应的内联程序集
(编辑)要查看实际的系统调用,请在汇编代码中跟随库调用。在write()
的示例中,以下间接操作将引导您通过libSystem.B.dylib
在libSystem\u kernel.dylib
中写入,您可以使用otool
对其进行反汇编
(编辑2)下面的完整示例,使用此测试程序test.c
:
#include <stdio.h>
int main(void)
{
char buf[] = "test\n";
ssize_t n;
n = write(2, buf, sizeof(buf));
return n;
}
使用otool
在test
二进制文件中反汇编main()
:
% otool -p _main -tvV test
test:
(__TEXT,__text) section
_main:
0000000100000ef0 pushq %rbp
0000000100000ef1 movq %rsp,%rbp
0000000100000ef4 subq $0x10,%rsp
0000000100000ef8 leaq 0xfa(%rbp),%rsi
0000000100000efc movb $0x74,0xfa(%rbp)
0000000100000f00 movb $0x65,0xfb(%rbp)
0000000100000f04 movb $0x73,0xfc(%rbp)
0000000100000f08 movb $0x74,0xfd(%rbp)
0000000100000f0c movb $0x0a,0xfe(%rbp)
0000000100000f10 movb $0x00,0xff(%rbp)
0000000100000f14 movl $0x00000002,%edi
0000000100000f19 movl $0x00000006,%edx
0000000100000f1e xorb %al,%al
0000000100000f20 callq 0x100000f32 ; symbol stub for: _write
0000000100000f25 addq $0x10,%rsp
0000000100000f29 popq %rbp
0000000100000f2a ret
列出动态链接以查找\u write
的测试
库:
% otool -L test
test:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
尝试在libSystem.B.dylib
中找到\u write
:
% otool -p _write -tvV /usr/lib/libSystem.B.dylib
/usr/lib/libSystem.B.dylib:
(__TEXT,__text) section
Can't find -p symbol: _write
% otool -L /usr/lib/libSystem.B.dylib
/usr/lib/libSystem.B.dylib:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
/usr/lib/system/libcache.dylib (compatibility version 1.0.0, current version 47.0.0)
/usr/lib/system/libcommonCrypto.dylib (compatibility version 1.0.0, current version 55010.0.0)
/usr/lib/system/libcompiler_rt.dylib (compatibility version 1.0.0, current version 6.0.0)
/usr/lib/system/libcopyfile.dylib (compatibility version 1.0.0, current version 85.1.0)
/usr/lib/system/libdispatch.dylib (compatibility version 1.0.0, current version 187.9.0)
/usr/lib/system/libdnsinfo.dylib (compatibility version 1.0.0, current version 395.11.0)
/usr/lib/system/libdyld.dylib (compatibility version 1.0.0, current version 195.6.0)
/usr/lib/system/libkeymgr.dylib (compatibility version 1.0.0, current version 23.0.0)
/usr/lib/system/liblaunch.dylib (compatibility version 1.0.0, current version 392.38.0)
/usr/lib/system/libmacho.dylib (compatibility version 1.0.0, current version 800.0.0)
/usr/lib/system/libmathCommon.A.dylib (compatibility version 1.0.0, current version 2026.0.0)
/usr/lib/system/libquarantine.dylib (compatibility version 1.0.0, current version 36.6.0)
/usr/lib/system/libremovefile.dylib (compatibility version 1.0.0, current version 21.1.0)
/usr/lib/system/libsystem_blocks.dylib (compatibility version 1.0.0, current version 53.0.0)
/usr/lib/system/libsystem_c.dylib (compatibility version 1.0.0, current version 763.13.0)
/usr/lib/system/libsystem_dnssd.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/system/libsystem_info.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/system/libsystem_kernel.dylib (compatibility version 1.0.0, current version 1699.26.8)
/usr/lib/system/libsystem_network.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/system/libsystem_notify.dylib (compatibility version 1.0.0, current version 80.1.0)
/usr/lib/system/libsystem_sandbox.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/system/libunc.dylib (compatibility version 1.0.0, current version 24.0.0)
/usr/lib/system/libunwind.dylib (compatibility version 1.0.0, current version 30.0.0)
/usr/lib/system/libxpc.dylib (compatibility version 1.0.0, current version 77.19.0)
检查libSystem.B.dylib
的依赖项:
% otool -p _write -tvV /usr/lib/libSystem.B.dylib
/usr/lib/libSystem.B.dylib:
(__TEXT,__text) section
Can't find -p symbol: _write
% otool -L /usr/lib/libSystem.B.dylib
/usr/lib/libSystem.B.dylib:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
/usr/lib/system/libcache.dylib (compatibility version 1.0.0, current version 47.0.0)
/usr/lib/system/libcommonCrypto.dylib (compatibility version 1.0.0, current version 55010.0.0)
/usr/lib/system/libcompiler_rt.dylib (compatibility version 1.0.0, current version 6.0.0)
/usr/lib/system/libcopyfile.dylib (compatibility version 1.0.0, current version 85.1.0)
/usr/lib/system/libdispatch.dylib (compatibility version 1.0.0, current version 187.9.0)
/usr/lib/system/libdnsinfo.dylib (compatibility version 1.0.0, current version 395.11.0)
/usr/lib/system/libdyld.dylib (compatibility version 1.0.0, current version 195.6.0)
/usr/lib/system/libkeymgr.dylib (compatibility version 1.0.0, current version 23.0.0)
/usr/lib/system/liblaunch.dylib (compatibility version 1.0.0, current version 392.38.0)
/usr/lib/system/libmacho.dylib (compatibility version 1.0.0, current version 800.0.0)
/usr/lib/system/libmathCommon.A.dylib (compatibility version 1.0.0, current version 2026.0.0)
/usr/lib/system/libquarantine.dylib (compatibility version 1.0.0, current version 36.6.0)
/usr/lib/system/libremovefile.dylib (compatibility version 1.0.0, current version 21.1.0)
/usr/lib/system/libsystem_blocks.dylib (compatibility version 1.0.0, current version 53.0.0)
/usr/lib/system/libsystem_c.dylib (compatibility version 1.0.0, current version 763.13.0)
/usr/lib/system/libsystem_dnssd.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/system/libsystem_info.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/system/libsystem_kernel.dylib (compatibility version 1.0.0, current version 1699.26.8)
/usr/lib/system/libsystem_network.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/system/libsystem_notify.dylib (compatibility version 1.0.0, current version 80.1.0)
/usr/lib/system/libsystem_sandbox.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/system/libunc.dylib (compatibility version 1.0.0, current version 24.0.0)
/usr/lib/system/libunwind.dylib (compatibility version 1.0.0, current version 30.0.0)
/usr/lib/system/libxpc.dylib (compatibility version 1.0.0, current version 77.19.0)
猜测\u write
可能包含在libsystem\u kernel.dylib
中(或者尝试所有这些):
现在我们有了构建test
的内联程序集版本所需的所有程序集:
#include <stdio.h>
int main(void)
{
char buf[] = "test\n";
ssize_t n;
asm volatile (
"movl $0x00000002, %%edi\n" /* first argument */
"movl $0x00000006, %%edx\n" /* third argument */
"movl $0x02000004, %%eax\n" /* syscall number */
"syscall\n"
: "=A"(n) /* %rax: return value */
: "S"(buf)); /* %rsi: second argument */
return n;
}
这似乎奏效了。上面的内联装配不是很精细;例如,您也可以动态地传入第一个和第三个参数,而不是在汇编代码中对它们进行硬编码。Linux解决方案是这样的:
.data mytext:
.ascii "Hello World\n"
.text
_mywrite:
movl $0x04, %eax # Syscall No. 4 = write
movl $0x01, %ebx # File. 1 = stdout
movl $mytext, %ecx
movl $0x0c, %edx # text length (hope I counted correctly)
int $0x80 # Interrupt 0x80 -> make syscall
在Mac等其他Unix系统上应该类似,但最好检查文档中的系统调用号(0x04)。请注意,这将显示对库的系统调用包装函数的调用。它不会显示对内核的实际调用。这错过了调用内核空间的大部分乐趣,但我对Darwin/Mach/知之甚少。。。要回答true,取决于OP想要实现什么,需要实际的系统调用;我已经相应地编辑了我的解决方案。与使用标准Cwrite
函数相比,有什么优势?@BoPersson实用优势?显然没有。学习优势?在挑剔的方面:POSIX没有标准化系统调用接口,只是标准化了系统库接口;实际的调用接口没有被定义为文档化的或稳定的,事实上可能有多种方法——例如,BSD、Solaris和Linux内核同时支持几种方法(旧的int$0x80
和/或lcall 0x27:0
方法以及Intel/AMDsyscenter
/syscall
)。MacOSX的“特权”是只支持具有syscall
指令的x86硬件。。。因此不必和其他任何人打交道…@FrankH。正确-我已相应地更新了问题。谢谢请注意,返回值实际上是ssize\u t
,而不是size\u t
(在MacOS X上)。
.data mytext:
.ascii "Hello World\n"
.text
_mywrite:
movl $0x04, %eax # Syscall No. 4 = write
movl $0x01, %ebx # File. 1 = stdout
movl $mytext, %ecx
movl $0x0c, %edx # text length (hope I counted correctly)
int $0x80 # Interrupt 0x80 -> make syscall