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
{
    unsigned short int 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
{
    unsigned short int 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@kali:~/pin-2.14-71313-gcc.4.4.7-linux/source/tools/MyPinTool# make

從網上下載一個簡單的TCP小程序將其放到根目錄下,首先生成可執行文件tcp_server和tcp_client,開始做實驗,代碼見附件。

root@kali:~/pin-2.14-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: 0x4
0x7f709913258e: 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);  
 }  

可以看出關於socket()函數的參數,分析結果與源程序是完全一致的。
我們在這一步獲得了參數AF_INET


0x7f709913258e: 43(0x4, 0x0, 0x0, 0x0, 0xffffffff, 0x0)returns: 0x5

系統調用號: 43,即系統調用accept()
參數1: 0x0,即socket句柄爲4,也就是socket()的返回值。
參數2: 0x0,這是一個(struct sockaddr*)類型的地址
參數3: 0x0,是參數2結構體的長度
返回值: 0x5,返回已連接socket句柄爲5
下面我們看一下tcp_server.c的源代碼:

 //阻塞直到有客戶端連接,不然多浪費CPU資源。  
 if( (connect_fd = accept(socket_fd, (struct sockaddr*)NULL, NULL)) == -1){  
     printf("accept socket error: %s(errno: %d)",strerror(errno),errno);  
     continue;  
 }  

可以看出關於accept()函數的參數,分析結果與源程序是也完全一致的。

但是,客戶端的IP地址在哪裏,如何獲得,這個。。。。。再想想

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章