【问题标题】:Reading and modifying data of syscall with ptrace使用 ptrace 读取和修改 syscall 的数据
【发布时间】:2020-03-11 21:10:05
【问题描述】:

我正在尝试做一件简单的事情(只是为了学习), 我希望在 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 被调用两次,一次进入系统调用,第二次退出。 所以好的,进入时正常为0,但退出时不应该是。 事实上 strace 显示正确:

strace 2>&1 date|grep CLOCK

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

我该怎么做?

【问题讨论】:

  • 请注意,clock_gettime 是特殊的,纯粹在用户空间中运行(VDSO 页面中的代码和比例因子),通常不使用syscall 指令进入内核。在我的系统(Arch Linux)上,strace date 不包含任何 clock_gettime 系统调用,但显然你的包含。无论如何,你如何决定什么时候做PTRACE_GETREGS?为什么你认为 RCX 是第一个参数? x86-64 System V 使用 RDI 作为函数和系统调用的调用约定中的第一个参数。 syscall 本身使用 RCX 来保存 RIP,而不是系统调用 arg。 (这是第 4 个函数 arg)
  • 我在这里和那里阅读..我正在试图弄清楚这个......我的程序是错误的,否则它会起作用:D
  • 看看blog.packagecloud.io/eng/2016/04/05/…,也可以使用 GDB 单步进入clock_gettime。有关 Linux 上的函数和系统调用约定,请参阅 What are the calling conventions for UNIX & Linux system calls on i386 and x86-64。 (不是 Windows,其中 RCX 函数调用的第一个参数传递寄存器;也许这就是你读到的?)
  • 找到了.. reg 是 rsi
  • 好的,所以你在调用 glibc 的 clock_gettime 或其他东西的断点处执行此操作。是的,这是第二个参数,而不是第一个:int clock_gettime(clockid_t clk_id, struct timespec *tp);

标签: linux date x86-64 ptrace


【解决方案1】:

发现错误..错误的寄存器..它是 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)

【讨论】:

    猜你喜欢
    • 2017-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多