Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ PTRACE_TRACEME的范围是多少?_C++_Linux_Ptrace - Fatal编程技术网

C++ PTRACE_TRACEME的范围是多少?

C++ PTRACE_TRACEME的范围是多少?,c++,linux,ptrace,C++,Linux,Ptrace,如果我有这样的代码: void child() { do_something(); ptrace(PTRACE_TRACEME, 0, 0, 0); do_some_other_things(); } 那么家长是否会跟踪dou\u something() 我在linux文档中发现,没有这样的东西。它只说这应该在tracee中调用 PTRACE_TRACEME 指示此进程将由其父进程跟踪。A. 如果进程的父进程 不希望跟踪它。(pid、addr和数据为 忽略。) 请参阅以

如果我有这样的代码:

void child() {
    do_something();
    ptrace(PTRACE_TRACEME, 0, 0, 0);
    do_some_other_things();
}
那么家长是否会跟踪
dou\u something()

我在linux文档中发现,没有这样的东西。它只说这应该在tracee中调用

PTRACE_TRACEME

指示此进程将由其父进程跟踪。A. 如果进程的父进程 不希望跟踪它。(pid、addr和数据为 忽略。)

请参阅以获得更好的解释,但总而言之,不,在tracee收到信号之前,它不会跟踪do_something()函数

在您引用的同一个人ptrace对ptrace调用的描述中:

进程可以通过调用fork(2)和 生成的子对象执行以下操作: PTRACE_TRACEME,后面(通常)跟一个execve(2)。或者,可以开始一个过程 使用PTRACE_ATTACH或PTRACE_jack跟踪另一个进程

在跟踪过程中,跟踪对象将在每次发送信号时停止,即使该信号 正在被忽视。(SIGKILL是一个例外,它具有通常的效果。)跟踪程序将 在下次调用waitpid(2)(或一个相关的“等待”系统调用)时通知;那个电话 将返回一个状态值,其中包含指示停止原因的信息 特雷西

当tracee调用exec时,它收到一个信号,这就是它停止的原因

要进行illustrace,跟踪程序mainer.c不带铃铛或口哨:

//mainer.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <sys/user.h>
#include <unistd.h>

int main(int argc, char ** argv)
{
        pid_t child_pid;
        char * programname = argv[1];

        child_pid = fork();
        if (child_pid == 0)
        {
                ptrace(PTRACE_TRACEME, 0, 0, 0);
                execl(programname, programname, NULL);
        }

        else if (child_pid > 0) 
        {
            int status;

            wait(&status);

            while (WIFSTOPPED(status))
            {
                    struct user_regs_struct regs;
                    ptrace(PTRACE_GETREGS, child_pid, 0, &regs);
                    unsigned instr = ptrace(PTRACE_PEEKTEXT, child_pid, regs.eip, 0);
                    printf("EIP = 0x%08x, instr = 0x%08x\n", regs.eip, instr);

                    ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0);

                    wait(&status);
            }

        }
}  
运行此命令,
/mainer hello

EIP = 0x08048080, instr = 0x00000000
EIP = 0x08048085, instr = 0x00000000
EIP = 0x0804808a, instr = 0x00000000
EIP = 0x0804808f, instr = 0x00000000
EIP = 0x08048094, instr = 0x00000000
Hello
EIP = 0x08048096, instr = 0x00000000
EIP = 0x0804809b, instr = 0x00000000
EIP = 0x080480a0, instr = 0x00000000
EIP = 0x080480a5, instr = 0x00000000
EIP = 0x080480aa, instr = 0x00000000
World
EIP = 0x080480ac, instr = 0x00000000
EIP = 0x080480b1, instr = 0x00000000
如果我们修改mainer.c,使子进程在执行之前调用do_something(),则跟踪的结果是完全相同的。这就是我修改它的方式,你可以确认你自己,如果你喜欢,结果是一样的

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

int do_something(void)        //added this function
{
        printf("Doing something");
        return 0;
}


int main(int argc, char ** argv)
{
        pid_t child_pid;
        char * programname = argv[1];

        child_pid = fork();
        if (child_pid == 0)
        {
                ptrace(PTRACE_TRACEME, 0, 0, 0);
                do_something();      //added this function call
                execl(programname, programname, NULL);
        }

        else if (child_pid > 0) 
        {
            int status;

            wait(&status);

            while (WIFSTOPPED(status))
            {
                    struct user_regs_struct regs;
                    ptrace(PTRACE_GETREGS, child_pid, 0, &regs);
                    unsigned instr = ptrace(PTRACE_PEEKTEXT, child_pid, regs.eip, 0);
                    printf("EIP = 0x%08x, instr = 0x%08x\n", regs.eip, instr);

                    ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0);

                    wait(&status);
            }

        }
}   
#包括
#包括
#包括
#包括
#包括
#包括
int do_something(void)//添加了此函数
{
printf(“做某事”);
返回0;
}
int main(int argc,字符**argv)
{
pid_t child_pid;
char*programname=argv[1];
child_pid=fork();
如果(子项pid==0)
{
ptrace(ptrace_TRACEME,0,0,0);
do_something();//添加了此函数调用
execl(程序名,程序名,NULL);
}
否则如果(子项pid>0)
{
智力状态;
等待(&状态);
while(WIFSTOPPED(状态))
{
结构用户\u注册表\u结构注册表;
ptrace(ptrace_GETREGS、child_pid、0和regs);
无符号instr=ptrace(ptrace_peek text,child_pid,regs.eip,0);
printf(“EIP=0x%08x,instr=0x%08x\n”,regs.EIP,instr);
ptrace(ptrace_SINGLESTEP,child_pid,0,0);
等待(&状态);
}
}
}   
因此,tracee在收到信号之前不会停止,这是它调用exec时发生的情况,调用函数不会为tracee生成信号,但是还有其他方法可以向tracee发送信号并开始跟踪,尽管它们不像exec和wait那样整洁

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

int do_something(void)        //added this function
{
        printf("Doing something");
        return 0;
}


int main(int argc, char ** argv)
{
        pid_t child_pid;
        char * programname = argv[1];

        child_pid = fork();
        if (child_pid == 0)
        {
                ptrace(PTRACE_TRACEME, 0, 0, 0);
                do_something();      //added this function call
                execl(programname, programname, NULL);
        }

        else if (child_pid > 0) 
        {
            int status;

            wait(&status);

            while (WIFSTOPPED(status))
            {
                    struct user_regs_struct regs;
                    ptrace(PTRACE_GETREGS, child_pid, 0, &regs);
                    unsigned instr = ptrace(PTRACE_PEEKTEXT, child_pid, regs.eip, 0);
                    printf("EIP = 0x%08x, instr = 0x%08x\n", regs.eip, instr);

                    ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0);

                    wait(&status);
            }

        }
}