【问题标题】:(ORIG_EAX*4) in ptrace calls(ORIG_EAX*4) 在 ptrace 调用中
【发布时间】:2012-06-21 04:40:36
【问题描述】:

我正在阅读一篇文章 here 并尝试我在下面复制的代码 sn-p :-

#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <linux/user.h>   /* For constants
                                   ORIG_EAX etc */
int main()
{   pid_t child;
    long orig_eax;
    child = fork();
    if(child == 0) {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        execl("/bin/ls", "ls", NULL);
    }
    else {
        wait(NULL);
        orig_eax = ptrace(PTRACE_PEEKUSER,
                          child, 4 * ORIG_EAX,
                          NULL);
        printf("The child made a "
               "system call %ld\n", orig_eax);
        ptrace(PTRACE_CONT, child, NULL, NULL);
    }
    return 0;
}

我对 ORIG_EAX 到底是什么以及为什么将 4*ORIG_EAX 传递给 ptrace 调用有疑问。我最初假设ORIG_EAXEBXECX 等将是存储寄存器值的特定结构的偏移量。

所以我决定在等待之后使用printf("origeax = %ld\n", ORIG_EAX); 打印 ORIG_EAX 的值。值为11。所以,我之前关于偏移量的假设是错误的。

我了解wait 调用在子级发生状态更改时终止(在这种情况下,发出系统调用)并且 ORIG_EAX 将包含系统调用号。

但是,为什么将 ORIG_EAX * 4 传递给 ptrace 调用?

【问题讨论】:

    标签: c linux ptrace systems-programming


    【解决方案1】:

    参数是user_regs_struct 的偏移量。请注意,每个都是unsigned long,因此要获得第 11 个条目 (orig_eax),字节偏移量是 44,(当然前提是您使用的是 x86 机器)。

    【讨论】:

    • 32 位和 64 位之间的差异如何?我们不应该对此进行编译时案例吗?
    • 进一步...,这只是 ptrace x86 吗?如果不是,我们需要一些更通用的独立于目标的方法!
    • AMD64 user_regs_struct 肯定有定义,但我不确定您是否可以混合和匹配架构。 IIRC ptrace 中的 cmets 提到单独的标题是一个问题。由于ptrace 是一个系统调用,它应该可以工作(您可能只需要手动切换每个架构的偏移量)但我不能说我曾经尝试过。
    • 这似乎不必要地暴露了实现细节;为什么 ptrace 不做 *4 本身?
    • 在 Ubuntu 18.0.4 上,“sys/user.h”的路径是“/usr/include/x86_64-linux-gnu/sys/user.h”
    猜你喜欢
    • 2011-01-22
    • 2012-02-27
    • 2012-07-01
    • 2016-02-12
    • 2014-08-12
    • 1970-01-01
    • 2012-08-14
    • 1970-01-01
    • 2011-06-09
    相关资源
    最近更新 更多