如何解释 PTRACE_PEEKTEXT 返回值 [英] How to interpret PTRACE_PEEKTEXT return value

查看:68
本文介绍了如何解释 PTRACE_PEEKTEXT 返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了熟悉寄存器,我一直在重新编写一个小型 strace 程序,而不使用 PTRACE_SYSCALL.

I've been working on a recode of a mini strace program without using PTRACE_SYSCALL in order to get familiar with the registers.

所以在我使用 ptrace(PTRACE_GETREGS, ...) 设置 user_reg_struct 字段后的代码中,我使用 ptrace(PTRACE_PEEKDATA, ...) 从中读取.

So in my code after using ptrace(PTRACE_GETREGS, ...) to set the user_reg_struct field, I'm using ptrace(PTRACE_PEEKDATA, ...) to read from it.

我真的不知道如何处理该函数的返回值以使用它的数据(系统调用等...),我开始查看一些代码,但我遇到了诸如:

Not really knowing what to do with the retur of that function to use it's data (syscalls etc...), I started looking at some code and I came across things like:

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() 语句中的数字是什么,又名:

Now can someone explain to me what are the numbers in the if() statement, a.k.a:

  • 0xFFFF,我认为这与处理器的架构有关,但我无法验证
  • 0x80CD0x50F
  • 0xFFFF, I assume it has to do with the architecture of the processor but I couldn't verify it
  • 0x80CD and 0x50F

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

I wish to know what they are, where can I find them, can I interpret them and how can I use them to get my system calls and their arguments.

推荐答案

你包含的代码有点不合常规,所以我会解释它的作用,然后展示一种不同的方法来做到这一点.

The code you included is somewhat unconventional, so I'll explain what it does and then show a different way to do it.

unsigned short int ret;
ret = ptrace(PTRACE_PEEKDATA, pid, regs.rip, 0);

Linux 上的 ptrace 返回一个 long,而不是一个无符号的 short.代码的作者只是在看ptrace返回的4或8个字节的低位2个字节.由于 x86 是 little-endian,这就完成了工作,但我会展示另一个稍后再做这件事.

ptrace on Linux returns a long, not an unsigned short. The author of the code is just looking at the low-order 2 bytes of the 4 or 8 bytes that ptrace returns. Since the x86 is little-endian, this gets the job done, but I'll show another way to do this later.

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

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

ptrace returns -1 on failure. Since the code stored only the low-order 2 bytes of the return value, and is treating the value as unsigned, the test for -1 uses 0xFFFF instead.

由于 ptrace(PTRACE_PEEKDATA, ...) 即使成功也可以返回 -1,所以最好也看看 errno(我会展示这个稍后).

Since ptrace(PTRACE_PEEKDATA, ...) can return -1 even when it succeeds, it would be better to also look at errno (I'll show this later).

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

您可以在 http://ref.x86asm.net/coder64.html 等网站上找到操作码列表 .CDintCD80int 800F05syscall.这是 x86 Linux 中用于执行系统调用的两个操作码.更多信息请访问 int 0x80"或syscall"哪个更好?.

You can find opcode lists at sites like http://ref.x86asm.net/coder64.html . CD is int and CD80 is int 80 and 0F05 is syscall. These are two opcodes used in x86 Linux to do system calls. Further info at What is better "int 0x80" or "syscall"?.

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

Here's another way to check for system call instructions (untested):

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)0xFF00 & ret) >> 8;
    if (primary == 0xCD && secondary == 0x80 || primary == 0x0F && secondary == 0x05)
        return true;
    return false;
}

我使用了 ptrace 返回值的全宽.如果它是 -1 并且 errno 已经被设置,那么这表明一个错误.我也使用 PTRACE_PEEKTEXT 而不是 PTRACE_PEEKDATA,尽管在​​ x86 上这无关紧要.位掩码用于获取主要和次要操作码字节.

I use the full width of ptrace's return value. If it's -1 and if errno has been set, then that indicates an error. I also use PTRACE_PEEKTEXT instead of PTRACE_PEEKDATA, although on x86 it doesn't matter. Bitmasks are used to get the primary and secondary opcode bytes.

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

how can I use them to get my system calls and their arguments.

为此,请参阅此详细答案:UNIX & 的调用约定是什么?Linux 系统调用 x86-64.

For this, please see this detailed answer: What are the calling conventions for UNIX & Linux system calls on x86-64.

这篇关于如何解释 PTRACE_PEEKTEXT 返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆