2014-10-17 4 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()'시스템 호출이 실행되면, 어떻게 파일 기술자가 무효가 될 수 있는가 ?? 일부 출력을 게시합니다 – Haris

+2

당신이 사용하고있는 다른 프로세스가 사용하고있는 파일 설명자가 프로그램에서 유효하지 않으므로 잘못된 파일 기술자입니다. 다른 프로그램이 보내는 소켓이 connect()되지 않은 UDP 소켓 인 경우 getpeername()은 어떤 경우에도 정보를 제공하지 않습니다. – nos

+0

@nos : 어떻게 UDP 소켓을 시도해야합니까? – Haris

답변

1

소켓 디스크립터 개의 프로세스간에 공유되지 않는 한 이러한 시스템 콜의 출력이다. 캡쳐 된 소켓 기술자는 트레이스 된 프로세스에서만 유효하고, 트레이서 프로세스에서는 효과적이지 않다. 그렇기 때문에 getpeername은 잘못된 디스크립터에 불만을 표시합니다.
ptrace :
ptrace() 시스템 호출은 상위 프로세스가 다른 프로세스의 실행을 관찰하고 제어하며 핵심 이미지와 레지스터를 검사하고 변경하는 방법을 제공합니다. 주로 중단 점 디버깅 및 시스템 호출 추적을 구현하는 데 사용됩니다.
프로세스 공간을 공유한다는 말은 없으므로 소켓 설명자, 메모리 주소 등을 공유 할 수 없습니다.

+0

고맙습니다. – Haris

관련 문제