getpeername总是给出错误的文件描述符

时间:2014-10-17 07:44:10

标签: c sockets trace

我有以下代码,我试图用它来获取套接字另一端的地址,但getpeername()始终失败并出现bad file descriptor错误。我做错了什么?

#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

1 个答案:

答案 0 :(得分:1)

套接字描述符不在两个进程之间共享。捕获的套接字描述符仅在跟踪过程中有效,并且在跟踪过程中无效。这就是getpeername抱怨错误描述符的原因。
来自ptrace的手册:
ptrace()系统调用提供了一种方法,父进程可以通过它监视和控制另一个进程的执行,并检查和更改其核心映像和寄存器。它主要用于实现断点调试和系统调用跟踪。
没有说他们共享进程空间,因此,他们不能共享套接字描述符,内存地址等。