强制程序使用int 0x80做系统调用
因为大多数情况下程序都是通过libc间接地发出系统调用的,所以只要编译一个只使用int 0x80的glibc库,然后在执行程序的时候用LD_LIBRARY_PATH或其他方法指定使用新编译的glibc库即可。
以glibc-2.9, Linux i386为例,在sysdeps/unix/sysv/linux/i386/syscall.S中可以看到
ENTRY (syscall)
PUSHARGS_6 /* Save register contents. */
_DOARGS_6(44) /* Load arguments. */
movl 20(%esp), %eax /* Load syscall number into %eax. */
ENTER_KERNEL /* Do the system call. */
POPARGS_6 /* Restore register contents. */
cmpl $-4095, %eax /* Check %eax for error. */
jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
这里使用了ENTER_KERNEL这个宏做系统调用,接下来在sysdeps/unix/sysv/linux/i386/sysdep.h里可以找到这个宏的定义
/* The original calling convention for system calls on Linux/i386 is
to use int $0x80. */
#ifdef I386_USE_SYSENTER
# ifdef SHARED
# define ENTER_KERNEL call *%gs:SYSINFO_OFFSET
# else
# define ENTER_KERNEL call *_dl_sysinfo
# endif
#else
# define ENTER_KERNEL int $0x80
#endif
而I386_USE_SYSENTER这个宏也是在同一个头文件中定义的
#if defined USE_DL_SYSINFO \
&& (!defined NOT_IN_libc || defined IS_IN_libpthread)
# define I386_USE_SYSENTER 1
#else
# undef I386_USE_SYSENTER
#endif
把这个条件宏改成
#undef I386_USE_SYSENTER
就能强制glibc使用int 0x80了。
这个方法只能过滤通过glibc做的系统调用。对于程序里写死使用sysenter的情况就要使用反汇编或者其他手段了。
本作品采用知识共享署名-非商业性使用 3.0 版本许可协议进行许可,欢迎转载,演绎,但是必须保留本文的署名 zellux(包含链接),且不得用于商业目的。