martes, marzo 15, 2005

Como llamar a funciones del sistema sin pasar por libc

En el subdirectorio /usr/src/linux/include/asm-ARQUITECTURA (ej: /usr/src/linux/include/asm-i386/) existe el archivo unistd.h, donde estan definidos los codigos de entrada a cada función del sistema:

...
#define __NR_chmod 15
#define __NR_lchown 16
#define __NR_break 17
#define __NR_oldstat 18
#define __NR_lseek 19
#define __NR_getpid 20
#define __NR_mount 21
#define __NR_umount 22
...

Y las funciones para llamarlas en función de los parámetros que de esa función:

#define _syscall0(type,name) type name(void) { long __res; __asm__ volatile ("int $0x80" : "=a" (__res) : "0" (__NR_##name)); __syscall_return(type,__res); }

...

#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, type5,arg5,type6,arg6) type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) { long __res; __asm__ volatile ("push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; int $0x80 ; pop %%ebp" : "=a" (__res) : "i" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)), "0" ((long)(arg6))); __syscall_return(type,__res); }

De esta manera, para llamar a la función del sistema directamente se necesita el siguiente código:

#include <sys/syscall.h>

_syscall0(pid_t, __NR_getpid);

Hay funciones de sistema que necesitan un tratamiento de los parametros antes de hacer el syscall, como por ejemplo sigaction, open y mmap.