ptrace(PTRACE_PEEKDATA,...)错误:数据转储

问题描述 投票:1回答:1

我希望从运行过程中获取指令并使用ptrace进行更改。当变量instr(包含当前指令 - PTRACE_PEEKDATA)是无符号时,一切正常,但是当我将其更改为long int时会出现错误(内存转储)。 ptrace(PTRACE_PEEKDATA,...)返回long int,所以这应该不是问题。我在Ubuntu上工作。

我犯了哪个错误?我是新手,所以这可能是愚蠢的。

我的代码:

#include <stdio.h>
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/types.h>
#include <stdlib.h>
#include <wait.h>

int main()
{
    int status; 
    char *pid_char;
    pid_t PID;
    struct user_regs_struct  reg; /* register */
    long int instr;
    unsigned changedInstr;


    printf("Tracee PID: ");
    scanf("%s", pid_char);
    PID = atoi(pid_char);
    printf("\n");

    /* PTRACE STARTS */
    ptrace(PTRACE_ATTACH, PID, NULL, NULL);
    waitpid(PID, &status, 0); 

    ptrace(PTRACE_GETREGS, PID, NULL, &reg);

    instr = ptrace(PTRACE_PEEKDATA, PID, reg.rip, NULL);
    printf("Current Instruction: %llx\n", instr);

    scanf("%u", &changedInstr);
    ptrace(PTRACE_POKEDATA, PID, reg.rip, &changedInstr);

    ptrace(PTRACE_DETACH, PID, NULL, NULL);

    return 0;
}
c linux ubuntu ptrace
1个回答
2
投票

在x86_64上,PTRACE_PEEKDATA返回8个字节,PTRACE_POKEDATA从其addr参数指向的地址开始传输8个字节。使用long或unsigned long应该没问题。

如果附加到nanosleep系统调用中的进程,则指令流如下所示:

(gdb) disass /r
Dump of assembler code for function __nanosleep_nocancel:
   0x00007ffff7ad92e9 <+0>: b8 23 00 00 00  mov    $0x23,%eax
   0x00007ffff7ad92ee <+5>: 0f 05   syscall 
=> 0x00007ffff7ad92f0 <+7>: 48 3d 01 f0 ff ff   cmp    $0xfffffffffffff001,%rax
   0x00007ffff7ad92f6 <+13>:    73 31   jae    0x7ffff7ad9329 <nanosleep+73>
   0x00007ffff7ad92f8 <+15>:    c3  retq  

在执行instr = ptrace(PTRACE_PEEKDATA, PID, reg.rip, NULL);之后,instr将是3173fffff0013d48,如果它是无符号长,或f0013d48,如果它是未签名的。

在你的程序中,changedInstr是无符号的,ptrace(PTRACE_POKEDATA, PID, reg.rip, &changedInstr);将传输4个字节的changedInstr,然后是4个字节的堆栈上与它相邻的任何东西,可能是其他一些局部变量的一部分。正如您所看到的那样,这4个字节可能是无害的,或者会使目标进程获得异常的东西。

如果你想在reg.rip写一个4字节的指令,那么在这种情况下应该工作的是

unsigned changedInstr;
...
instr = ptrace(PTRACE_PEEKDATA, PID, reg.rip, NULL);
scanf("%u", &changedInstr);
instr = (instr & ~0xFFFFFFFFul) | changedInstr
ptrace(PTRACE_POKEDATA, PID, reg.rip, &instr);
© www.soinside.com 2019 - 2024. All rights reserved.