2014-10-17 171 views
0

我有以下代碼,我試圖用來獲取套接字另一端的地址,但getpeername()總是失敗,並且出現bad file descriptor錯誤。我究竟做錯了什麼?getpeername總是給出錯誤的文件描述符

#include <arpa/inet.h> 
#include<syscall.h> 
#include<errno.h> 
#include <netinet/in.h> 
#include<string.h> 
#include<sys/socket.h> 
#include<stdio.h> 
#include<sys/ptrace.h> 
#include<sys/types.h> 
#include<sys/wait.h> 
#include<unistd.h> 
#include<sys/user.h> 
#include<sys/syscall.h> /* For SYS_write etc */ 
#include<stdlib.h> 

#define ORIG_RAX 15 
#define SYSCALL_MAXARGS 6 
#define RDI 14 

int main() 
{ 
    //**********declarations and memory allocations**********// 
    ssize_t size; 
    long sys_call_number, temp_long; 
    int status, temp, i, j, k, flag; 

    struct sockaddr_in ip_addr_struct; 
    socklen_t ip_addr_structlen = sizeof(ip_addr_struct); 
    struct user_regs_struct regs; 

    struct sockaddr_in* connect_struct; 

    char* filepath = malloc(1024); 
    char* fdpath = malloc(1024); 
    char* message = malloc(1024); 
    char* connect_ip = malloc(1024); 
    char* ip_addr = malloc(1024); 

    char* temp_char1,* temp_char2; 

    pid_t proc; 

    //**********getting pid and attaching to process**********// 
    scanf("%d",&proc); 

    ptrace(PTRACE_ATTACH,proc, NULL, NULL); 

    //**********starting the trace process**********// 

    //The system call number used in switch() case to determine particular system calls// 
    while(1) 
    { 
      wait(&status); 
      if(WIFEXITED(status)) 
      { 
       printf("****Process exited****\n"); 
       break; 
      } 
       ptrace(PTRACE_GETREGS, proc, NULL, &regs); 
       sys_call_number = regs.orig_rax; 

     switch(sys_call_number) 
     { 
      case 44: 
       printf("sendto\n"); 
       //***printing the register values containing system call parameters***// 
       printf("%llu - %llu - %llu - %llu - %llu - %llu\n", regs.rdi, regs.rsi, regs.rdx, regs.r10, regs.r8, regs.r9); 
       //***getting the peer address***// 
       errno = 0; 
       temp = getpeername(regs.rdi, (struct sockaddr *)&ip_addr_struct, &ip_addr_structlen); 
       if(temp == -1) 
       { 
        printf("error is getpeername-%d-%s\n",temp,strerror(errno)); 
        return -1; 
       } 

       int port = ntohs(ip_addr_struct.sin_port); 
       inet_ntop(AF_INET, &(ip_addr_struct.sin_addr), ip_addr, 1024); 
       printf("%d-%s\n", port, ip_addr); 
       port = 0; 
       //***reading message being send***// 
       temp_char2 = message; 
       j = 0; 
       while(j < (regs.rdx/8)) 
       { 
        temp_long = ptrace(PTRACE_PEEKDATA, proc, regs.rsi + (j*8) , NULL); 
        memcpy(temp_char2, &temp_long, 8); 
        temp_char2 += 8; 
        ++j; 
       } 
       temp_long = ptrace(PTRACE_PEEKDATA, proc, regs.rsi + (j*8) , NULL); 
       memcpy(temp_char2, &temp_long, regs.rdx - (j*8)); 
       message[regs.rdx] = '\0'; 
       printf("Message-%s-\n\n", message); 
      break; 
     } 
    } 
} 

下面是從一個這樣的系統調用

sendto 
14 - 32064144 - 884 - 16384 - 0 - 0 
--1-Bad file descriptor 
0-0.0.0.0 
Message-GET /?gfe_rd=cr&ei=2WYzVLCjFq7M8gfLlICoDg HTTP/1.1^M 
User-Agent: NetSurf/2.9 (Linux; x86_64)^M 
Host: www.google.co.in^M 
Accept: */ 
Accept-Encoding: gzip^M 
Cookie:PREF=ID=yu3vtr7i452389b4o236v4t28o37v723tn8vt0783tnv0723p78 N823748923bt87t2387b473287b8273t48 
+0

@nos:但下面的代碼在sendto()系統時打印寫入'http header'調用被執行,文件描述符如何無效? 我將發佈一些輸出 – Haris 2014-10-17 07:57:44

+2

無論您的ptrace'ing正在使用的另一個進程的文件描述符是什麼,在您的程序中都是無效的,因此也就是錯誤的文件描述符。 另外,如果其他程序發送的套接字是一個不是connect()的UDP套接字,getpeername()在任何情況下都不會給你任何信息。 – nos 2014-10-17 07:58:36

+0

@nos:我應該如何嘗試UDP套接字? – Haris 2014-10-17 08:00:11

回答

1

套接字描述符不是兩個過程之間共享的輸出。捕獲的套接字描述符僅在跟蹤過程中有效,在跟蹤過程中不起作用。這就是爲什麼getpeername抱怨壞描述符。
來自ptrace手冊:
ptrace()系統調用提供了一種方法,通過該方法,父進程可以觀察並控制另一個進程的執行,並檢查並更改其核心映像和寄存器。它主要用於實現斷點調試和系統調用跟蹤。
沒有詞說他們共享進程空間,因此,他們不能共享套接字描述符,內存地址等。

+0

Thanx,我明白了.. :) – Haris 2014-10-17 09:24:42