How to detect the launching of programs on Linux?

2020-01-24 11:29发布

I wrote a simple daemon. This daemon should respond when I run any program. How to do this? In a big daemon loop:

while(1)
{
   /* function which catches new programm running */
}

What functions to call in linux, when i'm running a new program (create new process)?

标签: c linux pid
8条回答
Summer. ? 凉城
2楼-- · 2020-01-24 11:35

Have a look at this little program by Sebastian Krahmer it does exactly what you are asking in a resource efficient way and pretty simple code.

It does require that your kernel has CONFIG_PROC_EVENTS enabled, which is not the case on the latest Amazon Linux Image (2012.09) for example.

UPDATE: Following a request to Amazon the Amazon Linux Image kernels now support PROC_EVENTS

查看更多
唯我独甜
3楼-- · 2020-01-24 11:36

I don't know if there exists a better way, but you could periodically scan the /proc filesystem.

For example, /proc/<pid>/exe is a symlink to the process's executable.

On my systems (Ubuntu/RedHat), /proc/loadavg contains the number of running processes (the number after the forward slash) as well as the pid of the most recently started process. If your daemon polls the file, any change to either of the two numbers will tell it when it needs to re-scan /proc looking for new processes.

This is by no means bullet-proof, but is the most suitable mechanism I can think of.

查看更多
手持菜刀,她持情操
4楼-- · 2020-01-24 11:36

You can either scan the operating system for programs that match your criterion or you can wait for a program to report itself to your daemon. Which technique you choose will depend heavily on how much control you have over your non-daemon programs.

Scanning can be accomplished by kernel system call, or by reading the user space advertised kernel details (as with the /proc file system). Note that scanning is not a guarantee that you will find any particular program, as if the program manages to launch and terminate between scan cycles, it will not be detected at all.

More complicated techniques of process detection are possible, but they also require more complicated implementations. It is important to know what is truly needed before you start reaching for solutions that are exotic (inserting kernel drivers, etc.), as everything you do is not independent of the system you are monitoring; you actually change the environment by watching it, and some methods of watching the environment might change it inappropriately.

查看更多
在下西门庆
5楼-- · 2020-01-24 11:37

Use forkstat, it's the most complete client for proc events:

sudo forkstat -e exec,comm,core

Packaged in Ubuntu, Debian and the AUR.


Before that, there was cn_proc:

 bzr branch lp:~kees/+junk/cn_proc

The Makefile needs a small change (LDLIBS instead of LDFLAGS).

cn_proc and exec-notify.c (which Arnaud posted) share a common ancestor; cn_proc handles a few more events and has cleaner output, but isn't resilient when processes exit quickly.


Ooh, found another fork of exec-notify, extrace. This one indents child processes below their parent (using a pid_depth heuristic).

查看更多
乱世女痞
6楼-- · 2020-01-24 11:38

CONFIG_FTRACE and CONFIG_KPROBES through brendangregg/perf-tools

git clone https://github.com/brendangregg/perf-tools.git
cd perf-tools
git checkout 98d42a2a1493d2d1c651a5c396e015d4f082eb20
sudo ./execsnoop

On another shell:

while true; do sleep 1; date; done

First shell shows data of format:

Tracing exec()s. Ctrl-C to end.                                                        
Instrumenting sys_execve                                                               
   PID   PPID ARGS 
 20109   4336 date                                                                                       
 20110   4336 sleep 1                                                                                    
 20111   4336 date                                                                                                                                                                                                 
 20112   4336 sleep 1                                                                                    
 20113   4336 date                                                                                       
 20114   4336 sleep 1                                                                                    
 20115   4336 date                                                                                       
 20116   4336 sleep 1
查看更多
Fickle 薄情
7楼-- · 2020-01-24 11:50

I was interested in trying to figure out how to do this without polling. inotify() does not seem to work on /proc, so that idea is out.

However, any program which is dynamically linked is going to access certain files on startup, such as the dynamic linker. This would be useless for security purposes since it won't trigger on a statically linked program, but might still be of interest:

#include <stdio.h>
#include <sys/inotify.h>
#include <assert.h>
int main(int argc, char **argv) {
    char buf[256];
    struct inotify_event *event;
    int fd, wd;
    fd=inotify_init();
    assert(fd > -1);
    assert((wd=inotify_add_watch(fd, "/lib/ld-linux.so.2", IN_OPEN)) > 0);
    printf("Watching for events, wd is %x\n", wd);
    while (read(fd, buf, sizeof(buf))) {
      event = (void *) buf;
      printf("watch %d mask %x name(len %d)=\"%s\"\n",
         event->wd, event->mask, event->len, event->name);
    }
    inotify_rm_watch(fd, wd);
    return 0;
}

The events this prints out don't contain any interesting information - the pid of the triggering process doesn't seem to be provided by inotify. However it could be used to wake up and trigger a rescan of /proc

Also be aware that short-lived programs might vanish again before this thing wakes up and finishes scanning /proc - presumably you would learn that they had existed, but not be able to learn what they were. And of course anybody could just keep opening and closing an fd to the dyanmic linker to drown you in noise.

查看更多
登录 后发表回答