I can't figure out why the function returns an "No such process" error message every time I run it, but simply using the same instructions inline produces the required output.
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/user.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
void getregs(pid_t proc, struct user_regs_struct *regs);
int main() {
pid_t proc = fork();
if(proc == 0) {
if(ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1) {
perror("traceme");
exit(0);
}
if(execl("child", "child", NULL) == -1) {
perror("execl");
exit(0);
}
} else {
wait(&proc);
struct user_regs_struct regs;
ptrace(PTRACE_GETREGS, proc, NULL, ®s);
printf("eax: %08x\n", (unsigned int)regs.eax);
getregs(proc, ®s);
ptrace(PTRACE_CONT, proc, NULL, NULL);
}
return 0;
}
void getregs(pid_t proc, struct user_regs_struct *regs) {
if(ptrace(PTRACE_GETREGS, proc, NULL, ®s) == -1) {
perror("GETREGS");
exit(1);
}
printf("eax: %08x\n", (unsigned int)regs->eax);
}
When I run this I get
~$ ./tracer
eax: 0000002f
GETREGS: No such process
I don't get why getregs()
returns that error. It's almost like it is outside scope of something?
Also, something a little unrelated: EAX is always set to 0000002f
no matter what process I try to execl()
. Is this natural? I don't know if i'm forking the child process properly or not. Would I need to make a new question on SO for this?
You hit this error because you are modifying the value of the process identifier (PID) contained in the variable proc
by passing its address to the wait(2)
syscall.
The wait
syscall will change the value of proc
with the return status of your child process upon its termination. So when you reference your child process in ptrace
using proc
, its value will likely be invalid and referencing no existing processes.
And as @lornix noticed, make sure that you pass the right pointer to ptrace
in the getregs
function.