守护程序
- 最近在做内网穿刺的时候,发现frps会因为终端关闭而退出,于是想是否能将frps的ppid设为1,这样就可以脱离终端而独立存在了。于是找到了守护程序
原理
- 守护程序是在后台运行的一类特殊进程,它独立于控制终端,并在系统启动时启动。守护程序通常用于执行系统任务、服务或周期性任务,它们在后台默默地运行,与用户的直接交互较少或没有。
以下是守护程序的一般原理:
-
创建子进程: 守护程序通常通过
fork
系统调用创建一个子进程。父进程负责启动守护进程,而子进程则成为实际的守护进程。 -
摆脱控制终端: 子进程调用
setsid
系统调用,创建一个新的会话并成为会话的领头进程。这有助于确保守护程序不受控制终端的影响,即使终端关闭,守护程序仍然可以继续运行。 -
改变工作目录: 通常,守护进程会将当前工作目录更改为根目录,以确保不会与文件系统关联。
-
关闭文件描述符: 守护程序会关闭其继承自父进程的所有文件描述符,以避免对终端和其他可能的文件描述符的依赖。
-
执行核心任务: 守护程序执行其特定的任务或服务。这可能涉及监听网络连接、定期执行某些操作、处理系统事件等。
实现
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <wait.h>
int main(){
pid_t pid;
int i;
long max;
pid=fork();
if(pid<0){
perror("fork error");
exit(-1);
}else if(pid>0){
printf("fork successful");
exit(0);
}
if(setsid()<0){
perror("setsid error");
exit(-1);
}
if(chdir("/")<0){
perror("chdir directory error");
exit(-1);
}
umask(0);
max=sysconf(_SC_OPEN_MAX);
for (size_t i = 0; i < max; i++)
{
close(i);
}
signal(SIGCHLD,SIG_DFL);
while(1){
pid_t child_pid=fork();
if(child_pid==-1){
perror("child_fork error");
exit(-1);
}
if(child_pid==0){
execl("/home/fangio/frp/frps","frps","-c","frps.ini",NULL);
perror("execl error");
}else{
int status;
waitpid(child_pid,&status,0);
if (WIFEXITED(status)) {
// frps exited normally
printf("frps exited with status %d\n", WEXITSTATUS(status));
} else {
// frps exited abnormally, handle as needed
printf("frps exited abnormally\n");
}
sleep(1);
}
}
return 0;
}