我正在尝试做一件简单的事情(只是为了学习),我希望在64位linux上拦截clock_gettime,读取输出并对其进行修改,以便将flase日期/时间返回到示踪(/ bin / date)。
我要做的是:
ptrace(PTRACE_GETREGS, pid, NULL, ®s);
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
我该怎么做?
发现错误..错误的寄存器..是RSI
ptrace(PTRACE_GETREGS, pid, NULL, ®s);
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)