How to trace a program from its very beginning without running it as root

前端 未结 7 1558
我在风中等你
我在风中等你 2021-02-04 09:44

I\'m writing a tool that calls through to DTrace to trace the program that the user specifies.

If my tool uses dtrace -c to run the program as a subprocess of DTrace, no

相关标签:
7条回答
  • 2021-02-04 09:55

    Create a launcher program that will wait for a signal of some sort (not necessarily a literal signal, just an indication that it's ready), then exec() your target. Now dtrace -p the launcher program, and once dtrace is up, let the launcher go.

    0 讨论(0)
  • 2021-02-04 09:57

    dtruss has the -n option where you can specify name of process you want to trace, without starting it (Credit to latter part of @kenorb's answer at https://stackoverflow.com/a/11706251/970301). So something like the following should do it:

    sudo dtruss -n "$program"
    $program
    
    0 讨论(0)
  • 2021-02-04 10:00

    If the other answer doesn't work for you, can you run the program in gdb, break in main (or even earlier), get the pid, and start the script? I've tried that in the past and it seemed to work.

    0 讨论(0)
  • 2021-02-04 10:07

    See my answer on related question "How can get dtrace to run the traced command with non-root priviledges?" [sic].

    Essentially, you can start a (non-root) background process which waits 1sec for DTrace to start up (sorry for race condition), and snoops the PID of that process.

    sudo true && \
    (sleep 1; cat /etc/hosts) &; \
    sudo dtrace -n 'syscall:::entry /pid == $1/ {@[probefunc] = count();}' $! \
    && kill $!
    

    Full explanation in linked answer.

    0 讨论(0)
  • 2021-02-04 10:09

    Well, this is a bit old, but why not :-)..

    I don't think there is a way to do this simply from command line, but as suggested, a simple launcher application, such as the following, would do it. The manual attaching could of course also be replaced with a few calls to libdtrace.

    int main(int argc, char *argv[]) {
        pid_t pid = fork();
        if(pid == 0) {
            setuid(123);
            seteuid(123);
            ptrace(PT_TRACE_ME, 0, NULL, 0);
            execl("/bin/ls", "/bin/ls", NULL);
        } else if(pid > 0) {
            int status;
            wait(&status);
    
            printf("Process %d started. Attach now, and click enter.\n", pid);
            getchar();
    
            ptrace(PT_CONTINUE, pid, (caddr_t) 1, 0);
        }
    
        return 0;
    }
    
    0 讨论(0)
  • 2021-02-04 10:10

    Something like sudo dtruss -f sudo -u <original username> <command> has worked for me, but I felt bad about it afterwards.

    I filed a Radar bug about it and had it closed as a duplicate of #5108629.

    0 讨论(0)
提交回复
热议问题