标签:its 实验 val add user windows rgs window oid
一、系统调用简述
三、实验过程
所有的socket系统调用的总入口是sys_socketcall(),在include/linux/Syscalls.h中定义,其中参数call是标识接口编号,args是接口参数指针,接口编号的定义在 include/uapi/linux/net.h中定义
1 #include <linux/socket.h> 2 #include <asm/socket.h> 3 4 #define NPROTO AF_MAX 5 6 #define SYS_SOCKET 1 /* sys_socket(2) */ 7 #define SYS_BIND 2 /* sys_bind(2) */ 8 #define SYS_CONNECT 3 /* sys_connect(2) */ 9 #define SYS_LISTEN 4 /* sys_listen(2) */ 10 #define SYS_ACCEPT 5 /* sys_accept(2) */ 11 #define SYS_GETSOCKNAME 6 /* sys_getsockname(2) */ 12 #define SYS_GETPEERNAME 7 /* sys_getpeername(2) */ 13 #define SYS_SOCKETPAIR 8 /* sys_socketpair(2) */ 14 #define SYS_SEND 9 /* sys_send(2) */ 15 #define SYS_RECV 10 /* sys_recv(2) */ 16 #define SYS_SENDTO 11 /* sys_sendto(2) */ 17 #define SYS_RECVFROM 12 /* sys_recvfrom(2) */ 18 #define SYS_SHUTDOWN 13 /* sys_shutdown(2) */ 19 #define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */ 20 #define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */ 21 #define SYS_SENDMSG 16 /* sys_sendmsg(2) */ 22 #define SYS_RECVMSG 17 /* sys_recvmsg(2) */ 23 #define SYS_ACCEPT4 18 /* sys_accept4(2) */ 24 #define SYS_RECVMMSG 19 /* sys_recvmmsg(2) */ 25 #define SYS_SENDMMSG 20 /* sys_sendmmsg(2) */
启动gdb server
qemu -kernel ../linux-5.0.1/arch/x86/boot/bzImage -initrd ../rootfs.img -append nokaslr -s -S
设置断点
gdb file ~/LinuxKernel/linux-5.0.1/vmlinux break sys_socketcall target remote:1234 c
执行结果:
不止一次调用了sys_socketcall
在net/socket.c中可以找到SYS_DEFINE2的定义
SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) { unsigned long a[AUDITSC_ARGS]; unsigned long a0, a1; int err; unsigned int len; if (call < 1 || call > SYS_SENDMMSG) return -EINVAL; call = array_index_nospec(call, SYS_SENDMMSG + 1); len = nargs[call]; if (len > sizeof(a)) return -EINVAL; /* copy_from_user should be SMP safe. */ if (copy_from_user(a, args, len)) return -EFAULT; err = audit_socketcall(nargs[call] / sizeof(unsigned long), a); if (err) return err; a0 = a[0]; a1 = a[1]; switch (call) { case SYS_SOCKET: err = __sys_socket(a0, a1, a[2]); break; case SYS_BIND: err = __sys_bind(a0, (struct sockaddr __user *)a1, a[2]); break; case SYS_CONNECT: err = __sys_connect(a0, (struct sockaddr __user *)a1, a[2]); break; case SYS_LISTEN: err = __sys_listen(a0, a1); break; case SYS_ACCEPT: err = __sys_accept4(a0, (struct sockaddr __user *)a1,(int __user *)a[2], 0); break; case SYS_GETSOCKNAME: err =__sys_getsockname(a0, (struct sockaddr __user *)a1,(int __user *)a[2]); break; case SYS_GETPEERNAME: err =__sys_getpeername(a0, (struct sockaddr __user *)a1,(int __user *)a[2]); break; case SYS_SOCKETPAIR: err = __sys_socketpair(a0, a1, a[2], (int __user *)a[3]); break; case SYS_SEND: err = __sys_sendto(a0, (void __user *)a1, a[2], a[3],NULL, 0); break; case SYS_SENDTO: err = __sys_sendto(a0, (void __user *)a1, a[2], a[3],(struct sockaddr __user *)a[4], a[5]); break; case SYS_RECV: err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3],NULL, NULL); break; case SYS_RECVFROM: err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3],(struct sockaddr __user *)a[4],(int __user *)a[5]); break; case SYS_SHUTDOWN: err = __sys_shutdown(a0, a1); break; case SYS_SETSOCKOPT: err = __sys_setsockopt(a0, a1, a[2], (char __user *)a[3],a[4]); break; case SYS_GETSOCKOPT: err =__sys_getsockopt(a0, a1, a[2], (char __user *)a[3],(int __user *)a[4]); break; case SYS_SENDMSG: err = __sys_sendmsg(a0, (struct user_msghdr __user *)a1,a[2], true); break; case SYS_SENDMMSG: err = __sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2],a[3], true); break; case SYS_RECVMSG: err = __sys_recvmsg(a0, (struct user_msghdr __user *)a1,a[2], true); break; case SYS_RECVMMSG: if (IS_ENABLED(CONFIG_64BIT) || !IS_ENABLED(CONFIG_64BIT_TIME)) err = __sys_recvmmsg(a0, (struct mmsghdr __user *)a1,a[2], a[3],(struct __kernel_timespec __user *)a[4],NULL); else err = __sys_recvmmsg(a0, (struct mmsghdr __user *)a1,a[2], a[3], NULL,(struct old_timespec32 __user *)a[4]); break; case SYS_ACCEPT4: err = __sys_accept4(a0, (struct sockaddr __user *)a1,(int __user *)a[2], a[3]); break; default: err = -EINVAL; break; } return err; }
可以看到实现的核心是一个switch语句,通过call参数来处理sys_socket、sys_bind等系统调用,每个case都和上面的系统调用表中的项对应。在socket中有不同的函数如Socket():创建套接字,Bind():指定本地地址,Connect():将套接字连接到目的地址等,根据传入参数的不同进行相应的处理。
标签:its 实验 val add user windows rgs window oid
原文地址:https://www.cnblogs.com/maotx/p/12069424.html