Pin截获socket系统调用初步分析

Pin截获socket系统调用初步分析

根据为知笔记中上传的Pin tool for tracing system calls,修改代码过滤出socket相关的系统调用,并进行初步的分析。主要有2点: – 过滤socket相关的系统调用 – 分析得到的系统调用参数

过滤socket相关的系统调用

socket编程中与访问网络相关的主要关注socket()、accept()。然后在PinTool中过滤出这两个系统调用,对他们的参数进行初步的分析。下面先看一下这两个函数:

int socket(int domain,int type,int protocol);socket函数说明

socket()用来建立一个新的socket,也就是向系统注册,通知系统建立一通信端口。

参数domain 指定使用何种的地址类型,完整的定义在/usr/include/bits/socket.h 内,底下是常见的协议: PF_UNIX/PF_LOCAL/AF_UNIX/AF_LOCAL UNIX 进程通信协议 PF_INET/AF_INET Ipv4网络协议 PF_INET6/AF_INET6 Ipv6 网络协议 PF_IPX/AF_IPX IPX-Novell协议 PF_NETLINK/AF_NETLINK 核心用户接口装置 PF_X25/AF_X25 ITU-T X.25/ISO-8208 协议 PF_AX25/AF_AX25 业余无线AX.25协议 PF_ATMPVC/AF_ATMPVC 存取原始ATM PVCs PF_APPLETALK/AF_APPLETALK appletalk(DDP)协议 PF_PACKET/AF_PACKET 初级封包接口

参数type有下列几种数值: SOCK_STREAM 提供双向连续且可信赖的数据流,即TCP。支持OOB 机制,在所有数据传送前必须使用connect()来建立连线状态。 SOCK_DGRAM 使用不连续不可信赖的数据包连接 SOCK_SEQPACKET 提供连续可信赖的数据包连接 SOCK_RAW 提供原始网络协议存取 SOCK_RDM 提供可信赖的数据包连接 SOCK_PACKET 提供和网络驱动程序直接通信。

参数protocol用来指定socket所使用的传输协议编号,通常此参考不用管它,设为0即可。

返回值成功则返回socket处理代码,失败返回-1。

int accept(int s,struct sockaddr * addr,int * addrlen);struct sockaddr{sa_family;char sa_data[14];};accept函数说明

accept 系统调用是等待传入连接的阻塞调用。处理连接请求后,accept 将返回新的套接字描述符。将此新的套接字连接到客户端,使另外一个套接字 s 保持 LISTEN 状态,以接受进一步连接。 参数s是套接字描述符。参数addr所指的结构会被系统填入远程主机的地址数据,参数addrlen为scokaddr的结构长度。 此外sockaddr结构会因使用不同的socket domain而有不同结构定义,例如使用AF_INET domain,其socketaddr结构定义便为

struct socketaddr_in{sin_family;uint16_t sin_port;struct in_addr sin_addr;unsigned char sin_zero[8];};struct in_addr{uint32_t s_addr;};

sin_family 即为sa_family sin_port 为使用的port编号 sin_addr.s_addr 为IP 地址 sin_zero 未使用。

也就是说判断程序的网络访问情况我们主要考虑: socket(int domain,int type,int protocol)函数中的domain参数,是否为PF_INET/AF_INET accept(int s,struct sockaddr * addr,int * addrlen)函数中addr参数内的IP地址

另一方面SystemCallTrace.cpp中SysBefore()函数用来打印系统调用号和参数。通过查看unistd_64.h中定义的各个系统调用的系统调用号,其中(socket,41),(accept,43),(listen,50),系统调用号41到50之间都是与socket相关的,所以我就在代码中做一个简单的过滤。代码如下:

if((num >= 41) && (num <= 50))fprintf(trace,”0x%lx: %ld(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)”,(unsigned long)ip,(long)num,(unsigned long)arg0,(unsigned long)arg1,(unsigned long)arg2,(unsigned long)arg3,(unsigned long)arg4,(unsigned long)arg5);

修改makefile.rules,添加SystemCallTrace工具:

TEST_TOOL_ROOTS := MyPinTool SystemCallTrace

生成SystemCallTrace.so

root-71313-gcc.4.4.7-linux/source/tools/MyPinTool# make

从网上下载一个简单的TCP小程序将其放到根目录下,首先生成可执行文件tcp_server和tcp_client,开始做实验,代码见附件。

root-71313-gcc.4.4.7-linux# bash pin.sh -t ~/pin-2.14-71313-gcc.4.4.7-linux/source/tools/MyPinTool/obj-intel64/SystemCallTrace.so — ~/tcp_server

现在tcp_server已经运行起来了,运行tcp_client向server发送几个字符,,结束实验。打开strace.out,部分结果如下:

0x7f7099132a95: 41(0x2, 0x1, 0x0, 0x0, 0x7f70993dc300, 0x7f70ac435310)returns: 0x40x7f709913258e: 43(0x4, 0x0, 0x0, 0x0, 0xffffffff, 0x0)returns: 0x5分析得到的系统调用参数

strace.out中

0x7f7099132a95: 41(0x2, 0x1, 0x0, 0x0, 0x7f70993dc300, 0x7f70ac435310)returns: 0x4

系统调用号: 41,即系统调用socket() 参数1: 0x2,在/usr/include/x86_64-linux-gnu/bits/socket.h中定义了socket使用的协议的值,0x2即PF_INET/AF_INET 参数2: 0x1,在/usr/include/x86_64-linux-gnu/bits/socket.h定义了socket类型,SOCK_STREAM = 1 参数3: 0x0 返回值: 0x4,返回socket句柄为4 下面我们看一下tcp_server.c的源代码:

//初始化Socket if( (socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){printf(“create socket error: %s(errno: %d)\n”,strerror(errno),errno);exit(0); } 是会眨眼的星星,而当火车弯曲而行,这些星群便上上下下的画着弧线,

Pin截获socket系统调用初步分析

相关文章:

你感兴趣的文章:

标签云: