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

/* 新版本没有linux/user.h头文件了，变为sys/user.h
 * ORIG_RAX 在sys/reg.h 中定义，也在asm/ptrace-abi头文件中定义
 * 可以通过这样的命令进行查找
 * find /usr/include/ -name *.h | xargs grep 'ORIG_RAX'
 * 因为64位寄存器，所以*8
 * 系统调用号在asm/unistd头文件中定义
 */

int main(void) {
    pid_t child;
    long orig_rax;
    child = fork();
    if (0 == child) {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        execl("/bin/ls", "ls", NULL);
    } else {
        wait(NULL);
        orig_rax = ptrace(PTRACE_PEEKUSER,
                          child, 8 * ORIG_RAX,
                          NULL);
        fprintf(stdout, "The child mode a system call %ld ", orig_rax);
        ptrace(PTRACE_CONT, child, NULL, NULL);
    }
    return 0;
}
diff --git a/test1.c b/test1.c
index 22c17f7..d322905 100644
--- a/test1.c
+++ b/test1.c
@@ -19,6 +19,7 @@ int main(void) {
     long orig_rax;
     child = fork();
     if (0 == child) {
+        /* PTRACE_TRACEME 告诉父进程去跟踪它，后面三个参数忽略 */
         ptrace(PTRACE_TRACEME, 0, NULL, NULL);
         execl("/bin/ls", "ls", NULL);
     } else {
diff --git a/test1.c b/test1.c
index d322905..953eaad 100644
--- a/test1.c
+++ b/test1.c
@@ -24,11 +24,13 @@ int main(void) {
         execl("/bin/ls", "ls", NULL);
     } else {
         wait(NULL);
-        orig_rax = ptrace(PTRACE_PEEKUSER,
+        orig_rax = ptrace(PTRACE_PEEKUSER, /* 读取偏移地址的值 */
                           child, 8 * ORIG_RAX,
                           NULL);
         fprintf(stdout, "The child mode a system call %ld ", orig_rax);
+        /* 让被监测进程继续执行 */
         ptrace(PTRACE_CONT, child, NULL, NULL);
     }
+
     return 0;
 }
diff --git a/test2.c b/test2.c
index e69de29..720ddfd 100644
--- a/test2.c
+++ b/test2.c
@@ -0,0 +1,62 @@
+#include <sys/reg.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <sys/user.h>
+#include <sys/syscall.h>
+#include <stdio.h>
+
+int main(void) {
+    pid_t child;
+    long orig_rax, rax;
+    long params[3];
+    int status = 0;
+    int insyscall = 0;
+    child = fork();
+    if (child == 0) {
+        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
+        execl("/bin/ls", "ls", NULL);
+    } else {
+        while (1) {
+            wait(&status);
+            /* WIFEXITED(status) 这个宏用来指出子进程是否为正常退出的，如果是，它会返回一个非零值。*/
+            if (WIFEXITED(status)) {
+                break;
+            }
+            orig_rax = ptrace(PTRACE_PEEKUSER,
+                              child, 8 * ORIG_RAX, NULL);
+
+            if (orig_rax == SYS_write) {
+                if (insyscall == 0) {
+                    insyscall = 1;
+                    /* 我觉得参数没有保存在这三个寄存器中 */
+                    params[0] = ptrace(PTRACE_PEEKUSER,
+                                       child, 8 * RBX,
+                                       NULL);
+                    params[1] = ptrace(PTRACE_PEEKUSER,
+                                       child, 8 * RCX,
+                                       NULL);
+                    params[2] = ptrace(PTRACE_PEEKUSER,
+                                       child, 8 * RDX,
+                                       NULL);
+                    fprintf(stdout, "Write caled with "
+                            "%ld, %ld, %ld \n",
+                            params[0], params[1],
+                            params[2]);
+                } else {
+                    rax = ptrace(PTRACE_PEEKUSER,
+                                 child, 8 * RAX, NULL);
+                    fprintf(stdout, "Write returned "
+                            "with %ld ", rax);
+                    insyscall = 0;
+                }
+            }
+            /* PTRACE_SYSCALL使内核在子进程做出系统调用或者准备退出的时候暂停它，
+             * 这种行为与使用PTRACE_CONT，然后在下个系统调用/进程退出时暂停它是等价的. */
+            ptrace(PTRACE_SYSCALL,
+                   child, NULL, NULL);
+        }
+    }
+    return 0;
+}
diff --git a/test3.c b/test3.c
index e69de29..f8f532a 100644
--- a/test3.c
+++ b/test3.c
@@ -0,0 +1,52 @@
+#include <sys/ptrace.h>
+#include <sys/reg.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <sys/user.h>
+#include <sys/syscall.h>
+#include <stdio.h>
+
+int main(void) {
+    pid_t child;
+    long orig_rax, rax;
+    int status;
+    int insyscall = 0;
+    struct user_regs_struct regs;
+    child = fork();
+    if (child == 0) {
+        ptrace(PTRACE_TRACEME, 0 ,NULL, NULL);
+        execl("/bin/ls", "ls", NULL);
+    } else {
+        while (1) {
+            wait(&status);
+            if (WIFEXITED(status)) {
+                break;
+            }
+            orig_rax = ptrace(PTRACE_PEEKUSER,
+                              child, 8 * ORIG_RAX,
+                              NULL);
+            if (orig_rax == SYS_write) {
+                if (insyscall == 0) {
+                    insyscall = 1;
+                    ptrace(PTRACE_GETREGS, child,
+                           NULL, regs);
+                    fprintf(stdout, "Write called with "
+                            "%llu, %llu, %llu ",
+                            regs.rbx, regs.rcx,
+                            regs.rdx);
+                } else {
+                    rax = ptrace(PTRACE_PEEKUSER,
+                                 child, 8 * RAX,
+                                 NULL);
+                    fprintf(stdout, "Write returned "
+                            "with %ld ", rax);
+                    insyscall = 0;
+                }
+            }
+            ptrace(PTRACE_SYSCALL, child,
+                   NULL, NULL);
+        }
+    }
+
+}