如何解释PTRACE_PEEKTEXT的返回值

时间:2017-04-14 13:15:23

标签: c unix system-calls strace

我一直在使用迷你 strace 程序进行重新编码,而不使用PTRACE_SYSCALL来熟悉寄存器。

因此在使用ptrace(PTRACE_GETREGS,...)设置user_reg_struct字段后的代码中,我使用ptrace(PTRACE_PEEKDATA,...)来读取它。

不知道如何处理该功能的使用以使用它的数据(系统调用等...),我开始查看一些代码,我遇到了类似的事情:

int is_a_syscall() {

struct user_reg_struct regs;
unsigned short int ret;

ret = ptrace(PTRACE_PEEKDATA, pid, regs.rip, 0);
if (ret == 0xFFFF) {
   perror("failed")
   exit(1); }
if (ret == 0x80CD || ret == 0x50F)
   return (true);
return (false);
}

现在有人可以向我解释if()语句中的数字是什么,a.k.a:

  • 0xFFFF ,我认为它与处理器的体系结构有关,但我无法验证它
  • 0x80CD 0x50F

我想知道它们是什么,我在哪里可以找到它们,我能解释它们吗?如何使用它们来获取我的系统调用及其参数。

2 个答案:

答案 0 :(得分:2)

你所包含的代码有些不同寻常,所以我会解释它的作用,然后以不同的方式来做。

unsigned short int ret;
ret = ptrace(PTRACE_PEEKDATA, pid, regs.rip, 0);
Linux上的ptrace返回一个很长的,而不是一个未签名的短片。代码的作者只是查看ptrace返回的4或8字节的低位2字节。由于x86是little-endian,因此可以完成工作,但我稍后会再次展示这种方法。

if (ret == 0xFFFF) {
   perror("failed")
   exit(1); }

ptrace失败时返回-1。由于代码只存储了返回值的低位2字节,并且将值视为无符号,因此-1的测试使用0xFFFF代替。

由于ptrace(PTRACE_PEEKDATA, ...)即使成功也可以返回-1,因此最好还是查看errno(我稍后会再次展示)。

if (ret == 0x80CD || ret == 0x50F)
   return (true);
return (false);

您可以在http://ref.x86asm.net/coder64.html等网站上找到操作码列表。 CDintCD80int 800F05syscall。这些是x86 Linux中用于进行系统调用的两个操作码。有关详情,请访问What is better “int 0x80” or “syscall”?

这是另一种检查系统调用指令的方法(未经测试):

int is_a_syscall(regs)
struct user_reg_struct regs;
{
    long ret;
    unsigned char primary, secondary;
    extern int errno;

    errno = 0;
    ret = ptrace(PTRACE_PEEKTEXT, pid, regs.rip, 0);
    if (ret == -1 && errno != 0) {
        perror("failed")
        exit(1);
    }
    primary = (unsigned)0xFF & ret;
    secondary = ((unsigned)xFF00 & ret) >> 8;
    if (primary == 0xCD && secondary == 0x80 || primary == 0x0F && secondary == 0x05)
        return true;
    return false;
}

我使用ptrace的全宽返回值。如果它是-1并且如果已设置errno,则表示错误。我也使用PTRACE_PEEKTEXT代替PTRACE_PEEKDATA,尽管在x86上它并不重要。 Bitmasks用于获取主要和次要操作码字节。

  

如何使用它们来获取系统调用及其参数。

为此,请参阅此详细答案:What are the calling conventions for UNIX & Linux system calls on x86-64

答案 1 :(得分:0)

你的意思是这些与十进制有什么关系(例如0x80CD = 32973),或者它们与ptrace()的语义是什么(例如0xFFFF可能意味着函数遇到错误)?

如果是前者,这些是以十六进制表示的数字。也就是说,数字范围包括的数字系统:0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F。

如果是后者,请查看man page for ptrace

中的返回值部分