Asm How Glibc Wrap Syscall
Asm How Glibc Wrap Syscall
April 21, 2025
实验平台: x86_64 GNU/Linux mint22.1
使用 glibc
的函数
write1.c
#include <unistd.h>
int main()
{
const char msg[] = "Hello, glibc!\n";
write(1, msg, sizeof(msg) - 1); // glibc's write() wrapper
return 0;
}
- gcc -o write1 write1.c
- 使用
ltrace ./write1
查看调用了 write 库函数
不使用 glibc 的函数
write2.c
#include <errno.h>
#include <syscall.h>
#include <unistd.h>
ssize_t write_no_glibc(int fd, const void *buf, size_t count)
{
long ret;
asm volatile(
"syscall"
: "=a"(ret) // Output: result in rax
: "a"(__NR_write), "D"(fd), "S"(buf), "d"(count) // Inputs
: "rcx", "r11", "memory" // Clobbered registers
);
if (ret < 0)
{
errno = -ret; // Set errno on error
return -1;
}
return ret; // Return bytes written
}
int main()
{
const char msg[] = "Hello, glibc!\n";
write_no_glibc(1, msg, sizeof(msg) - 1);
return 0;
}
- gcc -o write2 write2.c
- 使用
ltrace ./write2
查看没有调用 write 库函数
How glibc Wraps System Calls
System Call Number
Each system call (e.g., write, read) is assigned a unique number
(e.g., __NR_write). 要使用哪一个 syscall
Argument Setup
The wrapper loads the system call number and arguments into specific registers (architecture-dependent). 设置 syscall 的参数
Kernel Transition
The wrapper uses an instruction like syscall (x86-64) to switch to kernel mode. 进入 kernel mode
Result Handling
After the kernel finishes, the wrapper checks for errors, sets errno if needed, and returns the result. 处理返回值
References
Last updated on