使用ptrace读取和修改syscall的数据

问题描述 投票:0回答:1

我正在尝试做一件简单的事情(只是为了学习),我希望在64位linux上拦截clock_gettime,读取输出并对其进行修改,以便将flase日期/时间返回到示踪(/ bin / date)。

我要做的是:

   ptrace(PTRACE_GETREGS, pid, NULL, &regs);
   if(regs.orig_rax==228){  // this is the clock_gettime syscall number in 64 bit linux
     unsigned long p1=ptrace(PTRACE_PEEKDATA, pid, regs.rcx, NULL); // rcx is ARG1
     printf("ARG1: 0x%lx\n",p1);
   }

现在,如果我正确理解(显然不能正确理解),regs.rcx应该指向一个timespec结构,因此我应该读取该结构的第一个long int,即以秒为单位的时间(unixtime)。但我读0。

此外,printf被调用两次,一次进入syscall,第二次退出。好吧,进入时正常为0,但退出时不应该为0。Infact strace可以正确显示它:

strace 2>&1 date|grep CLOCK

clock_gettime(CLOCK_REALTIME, {tv_sec=1583960872, tv_nsec=403163000}) = 0

我该怎么做?

linux date x86-64 ptrace
1个回答
0
投票

发现错误..错误的寄存器..是RSI

 ptrace(PTRACE_GETREGS, pid, NULL, &regs);
   if(regs.orig_rax==228){  // this is the clock_gettime syscall number in 64 bit linux
     unsigned long p1=ptrace(PTRACE_PEEKDATA, pid, regs.rsi, NULL); // rsi is ARG2
     printf("ARG2: 0x%lx\n",p1);
   }

对于x86_64:

#define SYSCALL_ENTRY ((long)RET == -ENOSYS)
#define REGS_STRUCT struct user_regs_struct

#define SYSCALL (regs.orig_rax)
#define ARG1 (regs.rdi)
#define ARG2 (regs.rsi)
#define ARG3 (regs.rdx)
#define ARG4 (regs.r10)
#define ARG5 (regs.r8)
#define ARG6 (regs.r9)
#define RET (regs.rax)
© www.soinside.com 2019 - 2024. All rights reserved.