I've seen one article recommend using call *%gs:0x10to invoke _kernel_vsyscall, because GNU libc uses this register to locate its early-initialized magic globals.ĭon't do this. The main disadvantage of my solution is it can't be used in a statically linked executable, which are useful for system recovery tools (e.g. The dynamic linker solution can be trivially extended to other Linux vDSO symbols like _vdso_gettimeofday, again with no ELF parsing needed.I don't want my programs to embed ELF parsers, especially when a perfectly good one is available in ld.so. AT_SYSINFO_EHDR provides the address of the vDSO, which requires further parsing using an ELF library to extract relevant symbol addresses.AT_SYSINFO provides the address of _kernel_vsyscall directly, but is deprecated and requires the discovered address to be plumbed through client code (or assigned to a magic global in some very early initializer).I avoided this because it seems complicated and fussy: Some articles about the Linux vDSO describe looking up its address using the ELF auxiliary vector. The resulting binary is a totally normal dynamic ELF executable.Įcho '.type _kernel_vsyscall STT_FUNC' | as -32 -o dummy_so.o Creating a dummy shared object with ld -shared -soname=linux-gate.so.1 causes the linker to add a DT_NEEDED entry for the vDSO, so the dynamic linker will know to use it as a source of symbol addresses.This also prevents the linker from warning about an unresolved symbol. -defsym _kernel_vsyscall=0 creates a place for the symbol address to be written to, once resolved.To get the correct symbols and ELF headers into the executable, we need to inject some fake data: The linux-gate.so.1 library that will be available at runtime is not available to the linker at compile time. This code is slightly more complicated than the int 0x80 example because all functions loaded from shared objects (including _kernel_vsyscall) must use indirect calls. Later kernel versions also added fast paths for certain read-only syscalls. It's used in i386 linux to implement faster syscalls via the SYSENTER instructions available in modern 32-bit x86 processors. # hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, not strippedĪ vDSO is a shared library injected into processes by the kernel, rather than loaded by the dynamic linker. # hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped Linux syscall numbers for i386 are defined in arch/x86/entry/syscalls/syscall_32.tbl. Syscalls with more than six parameters use ebx to pass a memory address, in a way that doesn't seem to be well documented. Syscalls with six or fewer parameters pass them in registers. The syscall number is passed in register eax. Adding a Hello World System Call to Linux kernel 3.16.0 (Surya Seetharaman).Implementing a system call in Linux Kernel 4.7.1 (Sreehari S.).Adding hello world system call to Linux (Arvind S.Tutorial - Write a System Call (Stephen Brennan).LWN: Anatomy of a system call (David Drysdale).Manpage syscall(2) lists per-architecture calling conventions and register assignments.ĭocumentation and tutorials for implementing a Linux syscall: Manpage syscalls(2) lists syscalls and which kernel version they were added in. sys_clone) have different parameters depending on kernel compilation options. sys_stat64) are only defined on some platforms, and others (e.g. Syscalls use the same parameter order across platforms, but some (e.g. Linux syscalls are defined in include/linux/syscalls.h. It is obsolete since the mid 2000s for performance reasons, but can still be found in tutorials because it's easier to understand than more modern mechanisms. It triggers a software interrupt that transfers control to the kernel, which inspects its registers and stack to find the syscall number + parameters. Int $0x80 (also styled as int 80h) is the traditional syscall instruction on i386 UNIX-like platforms. This page is a catalog of how to invoke syscalls on different UNIX-like platforms. ![]() ![]() Performing a syscall is usually done via a special assembly instruction, though some platforms use other mechanisms (e.g. Each syscall is identified by a "syscall number" and has a short list of parameters, which both can vary between operating systems, hardware platforms, and configuration options. On UNIX-like operating systems, userland processes invoke kernel procedures using the "syscall" feature.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |