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