# Linux ## apt_package_manager_persistence ![](/api/file/getImage?fileId=6068599a83f5f2000d000003) ### 源码位置 https://github.com/rapid7/metasploit-framework/blob/04e8752b9b74cbaad7cb0ea6129c90e3172
# gcc 编译四步骤 ![](/api/file/getImage?fileId=604e0db3c9095f000e000023) # gcc 编译参数 gcc编译: ``` 4步骤: 预处理、编译、汇编、连接。 -I: 指定头文件所在目录位置。 -c: 只做预处理、编译、汇编。得到 二进制 文件!!! -g: 编译时添加调试语句。 主要支持 gdb 调试。 -Wal
# 系统调用 lseek函数: ```c off_t lseek(int fd, off_t offset, int whence); ``` 参数: - fd:文件描述符 - offset: 偏移量,就是将读写指针从whence指定位置向后偏移offset个单位 - whence:起始偏移位置: SEEK_SET/SEEK_CUR/SEEK_END 返回值: - 成功:较起始位置
# 系统调用 系统调用 内核提供的函数 库调用 程序库中的函数 ## open函数 manpage 第二卷,open函数如下,有两个版本的 ![](/api/file/getImage?fileId=6050d17bc9095f000d00000e) 返回一个文件描述符,理解为整数,出错返回-1 - pathname 文件路径 - flags 权限控制,只读,只写,读写

最近看了emytymonkey大佬的项目,感觉有很多有意思的项目,都基于了同一个Linux系统调用---ptrace,让我来详细看看这个神秘而强大的ptrace是什么.

本篇文章基于大佬的详细解析
https://recursiveg.me/2014/04/programming-with-ptrace-part1/

fork(), vfork() 与 clone()

我们知道,在linux中每个进程都有唯一的编号:pid,进程都是由父进程产生的,不会存在没有父进程的进程.所以进程是如何产生的呢?

fork()

  一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。
    一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。
   
原文链接:https://blog.csdn.net/jason314/article/details/5640969

?为什么只 print 了一次?应该是这个在线运行的问题

正常返回是这样的

print被调用了两次,说明在fork后整个程序被执行了两次,一次父进程,一次子进程,那么作为当前执行进程的进程本身,怎样自己确认是子进程还是主进程呢?


看函数返回值,当在子进程时,fork函数返回值为0,父进程中子进程的返回值为子进程的pid

vfork()

可以观察一下 vfork 换成 fork 输出结果
简单来说,vfork()保存父进程fork钱变量,fork()不保存

clone 待填

用户态?内核态?

https://zhuanlan.zhihu.com/p/69554144

从图上我们可以看出来通过系统调用将Linux整个

还是从大佬的代码开始学起

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <sys/ptrace.h>
  4. #include <sys/wait.h>
  5. #include <sys/resource.h>
  6. #include <sys/reg.h>
  7. int main(){
  8. puts("Parent started");
  9. pid_t pid;
  10. pid=fork();
  11. if (pid<0){
  12. puts("fork() failed");
  13. return(-1);
  14. }
  15. if (pid==0){
  16. ptrace(PTRACE_TRACEME,0,0,0);
  17. puts("Child sleeping...");
  18. sleep(1);
  19. puts("Child exec...");
  20. execlp("./target","target",NULL);
  21. }else{
  22. printf("Child PiD == %d\n",pid);
  23. int sta=0;
  24. struct rusage ru;
  25. wait4(pid,&sta,0,&ru);
  26. long rax_rt=ptrace(PTRACE_PEEKUSER,pid,8*RAX,0);
  27. printf("Child execve() returned with %ld\n",rax_rt);
  28. ptrace(PTRACE_SYSCALL,pid,0,0);
  29. int intocall=1;
  30. while(1){
  31. wait4(pid,&sta,0,&ru);
  32. if (WIFEXITED(sta)){
  33. puts("Child Exited");
  34. break;
  35. }
  36. long _ORIG_RAX=ptrace(PTRACE_PEEKUSER,pid,8*ORIG_RAX,0);
  37. long _RAX=ptrace(PTRACE_PEEKUSER,pid,8*RAX,0);
  38. if (intocall){
  39. p