为什么ptrace写0xFFFFFFFFFFFFFFFFFF而不是真实数据?

问题描述

我不知道为什么会这样,我的代码就是这样,它来自this question, 我只更改 usigned long long int 中的地址和数据的类型(计算机为 x64 ,并且程序在WLS中运行)。 最小的可复制示例是以下示例:

<svg [class]="className" width="100%" height="100%" viewBox="0 0 100% 100%" version="1.1"
        xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <rect x="0" y="0" width="300" height="100" stroke="red" stroke-width="3" fill="none" />
        <text x="350" y="0" fill="red">Why is this string of text outside the svg?</text>
</svg>

上面的代码输出为:

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <signal.h>
#include <syscall.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/reg.h>
#include <sys/user.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>



 void procmsg(const char* format,...)
   {
    va_list ap;
    fprintf(stdout,"[%d] ",getpid());
    va_start(ap,format);
    vfprintf(stdout,format,ap);
    va_end(ap);
   }

   void run_target(const char* programname)
   {
    procmsg("target started. will run '%s'\n",programname);

    /* Allow tracing of this process */
    if (ptrace(PTRACE_TRACEME,0) < 0) {
        perror("ptrace");
        return;
    }

    /* Replace this process's image with the given program */
    execl(programname,programname,(char *)NULL);
 }

 void run_debugger(pid_t child_pid)
 {
        
    int wait_status;
    struct user_regs_struct regs;

    procmsg("debugger started\n");

    /* Wait for child to stop on its first instruction */
    wait(&wait_status);

    /* Obtain and show child's instruction pointer */
    ptrace(PTRACE_GETREGS,child_pid,&regs);
    procmsg("Child started. RIP = 0x%016x\n",regs.rip);

    
    unsigned long long int addr = 0x0000000008001169;//0x004000da;
    unsigned long long int data = ptrace(PTRACE_PEEKTEXT,(void*)addr,NULL);
    procmsg("Original data at 0x%08x: 0x%08x\n",addr,data);

    //test
    unsigned long long int data_u = data;
    procmsg("test data_u: 0x%08x\n",data_u);

    /* Write the trap instruction 'int 3' into the address */
    unsigned long long int data_with_trap = (data & 0xFFFFFFFFFFFFFF00) | 0xCC;
    procmsg("Data with trap : 0x%016llx \n",data_with_trap);
    ptrace(PTRACE_POKETEXT,(void*)data_with_trap);

    /* See what's there again... */
    unsigned long long int readback_data = ptrace(PTRACE_PEEKTEXT,0);
    procmsg("After trap,set breakpoint,data at 0x%016llx: 0x%016llx\n",readback_data);

    /* Let the child run to the breakpoint and wait for it to
    ** reach it
    */
    ptrace(PTRACE_CONT,0);

    //wait to breakpoint
    wait(&wait_status);
    if (WIFSTOPPED(wait_status)) {
        procmsg("Child got a signal: %s\n",strsignal(WSTOPSIG(wait_status)));
    }
    else {
        perror("wait");
        return;
    }

    /* See where the child is Now */
    ptrace(PTRACE_GETREGS,&regs);
    procmsg("Child stopped at RIP = 0x%016x\n",regs.rip);

    /* Remove the breakpoint by restoring the prevIoUs data
    ** at the target address,and unwind the EIP back by 1 to
    ** let the cpu execute the original instruction that was
    ** there.
    */
    int result = ptrace(PTRACE_POKETEXT,(void*)data);
    procmsg("poketext origin  back result %d\n",result);
/* See what's there again... */
     readback_data = ptrace(PTRACE_PEEKTEXT,0);
     procmsg("After restore,data at 0x%llx: 0x%llx\n",readback_data);
     int offset = 0;
     for(offset = 1; offset < 25; offset++) {
       readback_data = ptrace(PTRACE_PEEKTEXT,(void*)(addr+offset),0);
       procmsg("After restore,addr+offset,readback_data);
     }




    regs.rip -= 1;
    ptrace(PTRACE_SETREGS,&regs);

    /* The child can continue running Now */
    ptrace(PTRACE_CONT,0);

    wait(&wait_status);
    if (WIFEXITED(wait_status)) {
        procmsg("Child exited\n");
    } else if(WIFSIGNALED(wait_status)) {
    procmsg("signal !!!\n");
    }
    else {
        procmsg("Unexpected signal. %s \n",strsignal(WSTOPSIG(wait_status)));
    }
 } 

int main(int argc,char** argv)
{
    pid_t child_pid;

    if (argc < 2) {
        fprintf(stderr,"Expected a program name as argument\n");
        return -1;
    }

    child_pid = fork();
    if (child_pid == 0)
        run_target(argv[1]);
    else if (child_pid > 0)
        run_debugger(child_pid);
    else {
        perror("fork");
        return -1;
    }

    return 0;
}

现在的问题是这一行:

[3220] debugger started
[3221] target started. will run 'Debugee1'
[3220] Child started. RIP = 0x0000000063fa1100
[3220] Original data at 0x08001169: 0xffffffff
[3220] test data_u: 0xffffffff
[3220] Data with trap : 0xffffffffffffffcc 
error : Bad address 
error : Bad address 
[3220] After trap,data at 0x0000000008001169: 0xffffffffffffffff
Debugee program waiting 
Debugee program exit 
wait: Bad address

当我去读并用 int3 指令(0xCC)写回数据并再次读回之后,结果始终是 0xffffffffffffffffff (又名-1,因此ptrace无法读取和写入) 我也知道地址是正确的,因为我使用objdump。 一些想法??

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)