I would like to make my hypervisor on linux for detecting and surveillance target process like a malware.
To achieve this, the hypervisor need to detect processes that is created or terminated or task switched.
On intel CPU, I knew that cr3 register indicate those roles.
for example, when cr3 register value is changed, vmexit
caused. And it means executed process will be changed (task switch or create process).
To achieve my goal, I thought this mechanism is very userful.
However, to detect created process and terminated process, it needs to scan task_struct when vmexit
due to changed cr3 value.
Especially, compare task_struct with target process lists to detect and remove terminated process from target process lists.
Could you tell me the best practice or teach me OSS like mine.
On Windows, I would be able to use PsSetCreateProcessNotifyRoutine
API….
Advertisement
Answer
This is exactly what linux perf does on linux, you could enable the two trace points which will be called upon process start and exit:
# perf list sched:sched_process_exec [Tracepoint event] sched:sched_process_exit [Tracepoint event] sched:sched_process_fork [Tracepoint event] ....
You can play with tracepoint by enable it with debugfs:
cd /sys/kernel/debug/tracing echo sched:sched_process_fork >> set_event echo sched:sched_process_exit >> set_event echo 1 > tracing_on cat trace_pipe
You will get output like this:
<...>-115924 [001] .... 1853164.915266: sched_process_fork: comm=bash pid=115924 child_comm=bash child_pid=115970 <...>-115970 [002] .... 1853164.915864: sched_process_exit: comm=bash pid=115970 prio=120 <...>-115924 [001] .... 1853164.916147: sched_process_fork: comm=bash pid=115924 child_comm=bash child_pid=115971 <...>-115971 [003] .... 1853164.916655: sched_process_exit: comm=bash pid=115971 prio=120 <...>-115924 [001] .... 1853165.502237: sched_process_fork: comm=bash pid=115924 child_comm=bash child_pid=115972 <...>-115972 [003] .... 1853165.503027: sched_process_exit: comm=cat pid=115972 prio=120 <...>-115924 [001] .... 1853176.627842: sched_process_fork: comm=bash pid=115924 child_comm=bash child_pid=115973 <...>-115973 [003] .... 1853176.628515: sched_process_exit: comm=cat pid=115973 prio=120 <...>-115924 [001] .... 1853184.520488: sched_process_fork: comm=bash pid=115924 child_comm=bash child_pid=115974
As you can see, each time a process is forked or terminated, the event is displayed. Also the trace_pipe
is a pipe, so that you can wait on and read it in your program.