How to play with ptrace on x86-64?

I follow the tutorial here and changed a bit for x86-64 (basically replace eax with rax, etc.) so that it is:

 #include <sys/ptrace.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <sys/user.h> #include <sys/reg.h> #include <unistd.h> int main() { pid_t child; long orig_eax; child = fork(); if(child == 0) { ptrace(PTRACE_TRACEME, 0, NULL, NULL); execl("/bin/ls", "ls", NULL); } else { wait(NULL); orig_eax = ptrace(PTRACE_PEEKUSER, child, 4 * ORIG_RAX, NULL); printf("The child made a " "system call %ld\n", orig_eax); ptrace(PTRACE_CONT, child, NULL, NULL); } return 0; } 

But it does not work as expected, it always says:

 The child made a system call -1 

What is wrong with the code?

+7
source share
2 answers

ptrace returns -1 with errno EIO because what you are trying to read is incorrectly aligned. Taken from the ptrace man page:

  PTRACE_PEEKUSER Reads a word at offset addr in the child USER area, which holds the registers and other information about the process (see <sys/user.h>). The word is returned as the result of the ptrace() call. Typically the offset must be word-aligned, though this might vary by architecture. See NOTES. (data is ignored.) 

On my 64-bit system, 4 * ORIG_RAX does not equal 8 bytes each. Try with values ​​0 or 8 and they should work.

+6
source

64 bit = 8 * ORIG_RAX

8 = sizeof (long)

+6
source

All Articles