summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWe-unite <3205135446@qq.com>2024-07-30 19:37:48 +0800
committerWe-unite <3205135446@qq.com>2024-07-30 19:37:48 +0800
commitd6c6e13796435f9e1e59fec891aa53680748a2d7 (patch)
tree8a43fc36ec69a67dd5fd9809ac4588b5fbbac61c
parent5d244e33672d0dd29a10c40c923c1decd645a1f7 (diff)
downloadgodo-d6c6e13796435f9e1e59fec891aa53680748a2d7.tar.gz
godo-d6c6e13796435f9e1e59fec891aa53680748a2d7.zip
Try to use kernel connector
-rw-r--r--connector/hello.c162
-rwxr-xr-xconnector/proc_collector_linux.cpp618
-rwxr-xr-xconnector/proc_mon_linux.cpp487
-rw-r--r--connector/test.c64
-rw-r--r--src/deal.go57
-rw-r--r--src/global.go48
6 files changed, 1417 insertions, 19 deletions
diff --git a/connector/hello.c b/connector/hello.c
new file mode 100644
index 0000000..5240c15
--- /dev/null
+++ b/connector/hello.c
@@ -0,0 +1,162 @@
1#include <stdio.h>
2#include <poll.h>
3#include <stdlib.h>
4#include <sys/types.h>
5#include <sys/socket.h>
6#include <sys/time.h>
7#include <sys/select.h>
8#include <signal.h>
9#include <linux/netlink.h>
10#include <linux/connector.h>
11// #include <linux/cn_proc.h>
12#include <unistd.h>
13#include <errno.h>
14#include <time.h>
15#include "cn_proc.h"
16
17typedef struct __attribute__((aligned(NLMSG_ALIGNTO)))
18{
19 struct nlmsghdr nl_hdr;
20 struct __attribute__((__packed__))
21 {
22 struct cn_msg cn_msg;
23 enum proc_cn_mcast_op cn_mcast;
24 };
25} register_msg_t;
26
27typedef struct __attribute__((aligned(NLMSG_ALIGNTO)))
28{
29 struct nlmsghdr nl_hdr;
30 struct __attribute__((__packed__))
31 {
32 struct cn_msg cn_msg;
33 struct proc_event proc_ev;
34 };
35} event_msg_t;
36
37event_msg_t proc_msg;
38
39void Now()
40{
41 struct timespec ts;
42 struct tm *tm_info;
43 char buffer[64];
44
45 if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
46 {
47 perror("clock_gettime");
48 return;
49 }
50
51 tm_info = localtime(&ts.tv_sec);
52 strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", tm_info);
53 printf("Localtime %s.%03ld ", buffer, ts.tv_nsec / 1000000);
54}
55
56void printEvent()
57{
58 union unnamed *procEvent = &proc_msg.proc_ev.event_data;
59 switch (proc_msg.proc_ev.what)
60 {
61 case PROC_EVENT_FORK:
62 Now();
63 printf("Fork\t%6d\t%6d\t%6d\t%6d\n", procEvent->fork.parent_pid, procEvent->fork.parent_tgid, procEvent->fork.child_pid, procEvent->fork.child_tgid);
64 break;
65 case PROC_EVENT_EXIT:
66 Now();
67 printf("Exit\t%6d\t%6d\t%6d\t%6d\n", procEvent->exit.process_pid, procEvent->exit.process_tgid, procEvent->exit.exit_code, procEvent->exit.exit_signal);
68 break;
69 case PROC_EVENT_EXEC:
70 default:
71 break;
72 }
73}
74
75int main()
76{
77 int s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
78
79 register_msg_t nlcn_msg;
80 struct sockaddr_nl l_local;
81 l_local.nl_family = AF_NETLINK;
82 l_local.nl_groups = 12345;
83 l_local.nl_pid = 0;
84
85 if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1)
86 {
87 perror(bind);
88 close(s);
89 return -1;
90 }
91
92 // int on = l_local.nl_groups;
93 // setsockopt(s,270,1,&on,sizeof(on));
94 memset(&nlcn_msg, 0, sizeof(nlcn_msg));
95 nlcn_msg.nl_hdr.nlmsg_len = sizeof(nlcn_msg);
96 nlcn_msg.nl_hdr.nlmsg_pid = getpid();
97 nlcn_msg.nl_hdr.nlmsg_type = NLMSG_DONE;
98
99 nlcn_msg.cn_msg.id.idx = CN_IDX_PROC;
100 nlcn_msg.cn_msg.id.val = CN_VAL_PROC;
101 nlcn_msg.cn_msg.len = sizeof(enum proc_cn_mcast_op);
102
103 nlcn_msg.cn_mcast = PROC_CN_MCAST_LISTEN;
104
105 if (send(s, &nlcn_msg, sizeof(nlcn_msg), 0) == -1)
106 {
107 perror("can't register to netlink");
108 close(s);
109 return -1;
110 }
111
112 // 震惊,拿到socket了,开听!
113 printf("Hello, kernel-connector!\n");
114 // fd_set readfds;
115 // struct timeval tv = {
116 // .tv_sec = 5,
117 // .tv_usec = 0};
118 struct pollfd fds;
119
120 fds.fd = s;
121 fds.events = POLLIN;
122 int rc;
123
124 while (1)
125 {
126 // FD_ZERO(&readfds);
127 // FD_SET(s, &readfds);
128
129 // int rc = select(s + 1, &readfds, NULL, NULL, &tv);
130 rc = poll(&fds, 1, 5000);
131
132 if (rc == -1)
133 {
134 if (errno == EINTR)
135 {
136 continue;
137 }
138 fprintf(stderr, "Failed to listen to netlink socket: %s\n", strerror(errno));
139 return -1;
140 }
141 else if (rc == 0)
142 {
143 printf("No message in 5s...\n");
144 }
145 else
146 {
147 rc = recv(s, &proc_msg, sizeof(proc_msg), 0);
148 if (rc == -1)
149 {
150 if (errno == EINTR)
151 {
152 continue;
153 }
154 fprintf(stderr, "Failed to listen to netlink socket: %s\n", strerror(errno));
155 }
156 else
157 {
158 printEvent();
159 }
160 }
161 }
162} \ No newline at end of file
diff --git a/connector/proc_collector_linux.cpp b/connector/proc_collector_linux.cpp
new file mode 100755
index 0000000..478ac2b
--- /dev/null
+++ b/connector/proc_collector_linux.cpp
@@ -0,0 +1,618 @@
1#ifndef WIN32
2#include <sys/socket.h>
3#include <linux/netlink.h>
4#include <linux/connector.h>
5#include <linux/cn_proc.h>
6#include <errno.h>
7#include <sys/select.h>
8#include <sys/types.h>
9#include <sys/time.h>
10#include <unistd.h>
11
12#include "os_crypto/md5/md5_op.h"
13#include "external/procps/readproc.h"
14#include "proc_collector.h"
15
16static struct
17{
18 int queue_fd;
19 int proc_fd;
20} proc_monitor =
21{
22 .queue_fd = -1,
23 .proc_fd = -1
24};
25
26typedef struct __attribute__((aligned(NLMSG_ALIGNTO)))
27{
28 struct nlmsghdr nl_hdr;
29 struct __attribute__((__packed__))
30 {
31 struct cn_msg cn_msg;
32 enum proc_cn_mcast_op cn_mcast;
33 };
34} register_msg_t;
35
36typedef struct __attribute__((aligned(NLMSG_ALIGNTO)))
37{
38 struct nlmsghdr nl_hdr;
39 struct __attribute__((__packed__))
40 {
41 struct cn_msg cn_msg;
42 struct proc_event proc_ev;
43 };
44} event_msg_t;
45
46#define MAX_TEMP_PROCESS 5000
47#define TEMP_WAIT_TIME 1
48#define PROCESS_SLOT_EMPTY 0
49#define MAX_PATH_NAME 4096
50#define MAX_PIPE_WAIT_USECOND 100
51
52
53typedef struct
54{
55 pid_t pid;
56 pid_t ppid;
57 time_t fork_time;
58 int status;
59 char path[MAX_PATH_NAME];
60 os_md5 md5;
61 char parent_path[MAX_PATH_NAME];
62 os_md5 parent_md5;
63} process_parent_child_pair_t;
64static process_parent_child_pair_t temp_processes[ MAX_TEMP_PROCESS ];
65
66
67/*
68typedef struct
69{
70 pid_t pid; // process id
71 char *name; // process name
72 char *state; //program running state
73 pid_t ppid; // parent process id
74 char *pname; // parent process name
75 ulong utime; // process time in user mode
76 ulong stime; // process time in kernel mode
77 char **cmd_line; // command line
78 char *real_user; //
79 char *effective_user;
80 char *saved_user;
81 char *fs_user;
82 char *real_group;
83 char *effective_group;
84 char *saved_group;
85 char *fs_group;
86 int priority; // process priority
87 int nice; // nice value
88 long size; // the toal memory
89 long vm_size; // virtual memory
90 long resident; // occupied physical memory
91 long share; // shared memory
92 time_t start_time; // process startup time
93 int pgrp; /// process group
94 int session; // session id
95 long nlwp; // number of thread
96 int tgid; // task group id
97 int tty; // control terminal
98 int processor; // cpu number last executed on
99} proc_info_t;
100*/
101
102
103static void wm_proc_cleanup()
104{
105 if ( proc_monitor.proc_fd > 0 )
106 {
107 close( proc_monitor.proc_fd );
108 proc_monitor.proc_fd = -1;
109 }
110
111 if ( proc_monitor.queue_fd > 0 )
112 {
113 close( proc_monitor.queue_fd );
114 proc_monitor.queue_fd = -1;
115 }
116}
117
118
119static int wm_setup_netlink( )
120{
121 int rc;
122 int nl_sock;
123 struct sockaddr_nl sa_nl;
124 register_msg_t nlcn_msg;
125
126 nl_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
127 if (nl_sock == -1)
128 {
129 mterror( WM_PROC_LOGTAG, "Can't open netlink socket");
130 return -1;
131 }
132
133 sa_nl.nl_family = AF_NETLINK;
134 sa_nl.nl_groups = CN_IDX_PROC;
135 sa_nl.nl_pid = getpid(); // 向内核注册
136
137 rc = bind(nl_sock, (struct sockaddr *)&sa_nl, sizeof(sa_nl));
138 if (rc == -1)
139 {
140 mterror( WM_PROC_LOGTAG, "Can't bind netlink socket");
141 close(nl_sock);
142 return -1;
143 }
144
145 // create listener
146 memset(&nlcn_msg, 0, sizeof(nlcn_msg));
147 nlcn_msg.nl_hdr.nlmsg_len = sizeof(nlcn_msg);
148 nlcn_msg.nl_hdr.nlmsg_pid = getpid();
149 nlcn_msg.nl_hdr.nlmsg_type = NLMSG_DONE;
150
151 nlcn_msg.cn_msg.id.idx = CN_IDX_PROC;
152 nlcn_msg.cn_msg.id.val = CN_VAL_PROC;
153 nlcn_msg.cn_msg.len = sizeof(enum proc_cn_mcast_op);
154
155 nlcn_msg.cn_mcast = PROC_CN_MCAST_LISTEN ;
156
157 rc = send(nl_sock, &nlcn_msg, sizeof(nlcn_msg), 0);
158 if (rc == -1)
159 {
160 mterror(WM_PROC_LOGTAG, "can't register to netlink");
161 close( nl_sock );
162 return -1;
163 }
164
165 proc_monitor.proc_fd = nl_sock;
166 return 0;
167}
168
169static int wm_setup_mq( wm_proc_t *proc )
170{
171 unsigned int indx;
172 // Connect to socket
173 for (indx = 0; indx < WM_MAX_ATTEMPTS; indx++)
174 {
175 proc_monitor.queue_fd = StartMQ(DEFAULTQPATH, WRITE);
176 if ( proc_monitor.queue_fd > 0 )
177 {
178 break;
179 }
180 wm_delay(1000 * WM_MAX_WAIT);
181 }
182
183 if (indx == WM_MAX_ATTEMPTS)
184 {
185 mterror(WM_PROC_LOGTAG, "Can't connect to queue.");
186 pthread_exit(NULL);
187 }
188
189 // Cleanup exiting
190 atexit(wm_proc_cleanup);
191
192 return 0;
193}
194
195 int wm_proc_linux_setup( wm_proc_t *proc )
196 {
197 memset( temp_processes, 0, sizeof( temp_processes ) );
198 if ( wm_setup_netlink() < 0 )
199 {
200 return -1;
201 }
202 return wm_setup_mq(proc);
203 }
204
205static void get_path_and_md5( pid_t pid, char *path, char *md5 )
206{
207 char pid_path[MAX_PATH_NAME];
208 struct stat dir_stat;
209
210 memset( pid_path, 0, MAX_PATH_NAME);
211 snprintf( pid_path, MAX_PATH_NAME-1, "/proc/%d", pid );
212 if ( stat( pid_path, &dir_stat ) < 0 )
213 {
214 //mterror(WM_PROC_LOGTAG, "failed to open directory %s, errno=(%d:%m)", pid_path, errno );
215 return;
216 }
217
218 memset( pid_path, 0, MAX_PATH_NAME);
219 snprintf( pid_path, MAX_PATH_NAME-1, "/proc/%d/exe", pid );
220 memset( path, 0, MAX_PATH_NAME );
221 memset( md5, 0, sizeof(os_md5));
222 if ( readlink( pid_path, path, MAX_PATH_NAME ) < 0 )
223 {
224 memset(pid_path, 0, MAX_PATH_NAME);
225 snprintf(pid_path, MAX_PATH_NAME - 1, "/proc/%d/comm", pid);
226 memset(path, 0, MAX_PATH_NAME);
227 FILE* fp = fopen(pid_path, "rb");
228 if ( NULL == fp )
229 {
230 return;
231 }
232 fread( path, MAX_PATH_NAME, 1, fp );
233 if ( strlen( path ) > 0 )
234 {
235 path[strlen(path)-1] = '\0';
236 }
237 fclose( fp );
238 return;
239 }
240
241 OS_MD5_File(path, md5, OS_BINARY);
242
243 return;
244}
245
246
247
248static void get_process_baseinfo( const process_parent_child_pair_t *pair, const char *location )
249{
250 proc_t curr_proc;
251
252 memset( &curr_proc, 0, sizeof( proc_t ));
253
254 cJSON *process = cJSON_CreateObject();
255 if( NULL == process)
256 {
257 return;
258 }
259 cJSON_AddStringToObject(process, "type", "new process");
260 cJSON_AddNumberToObject(process, "pid", pair->pid);
261 cJSON_AddNumberToObject(process, "eventTime", pair->fork_time);
262 cJSON_AddNumberToObject(process, "ppid", pair->ppid);
263 if (strlen(pair->path) > 0)
264 {
265 cJSON_AddStringToObject(process, "exe", pair->path);
266 }
267 if (strlen(pair->md5) > 0)
268 {
269 cJSON_AddStringToObject(process, "md5", pair->md5);
270 }
271 if (strlen(pair->parent_path) > 0)
272 {
273 cJSON_AddStringToObject(process, "parent_exe", pair->parent_path);
274 }
275 if (strlen(pair->parent_md5) > 0)
276 {
277 cJSON_AddStringToObject(process, "parent_md5", pair->parent_md5);
278 }
279
280 // get process information
281 if (NULL != get_proc_stats(pair->pid, &curr_proc))
282 {
283 cJSON_AddStringToObject(process, "state", &curr_proc.state);
284 cJSON_AddNumberToObject(process, "utime", curr_proc.utime);
285 cJSON_AddNumberToObject(process, "stime", curr_proc.stime);
286 if (curr_proc.cmdline && curr_proc.cmdline[0])
287 {
288 cJSON *argvs = cJSON_CreateArray();
289 cJSON_AddStringToObject(process, "cmd", curr_proc.cmdline[0]);
290 for (int i = 1; curr_proc.cmdline[i]; i++)
291 {
292 if (!strlen(curr_proc.cmdline[i]) == 0)
293 {
294 cJSON_AddItemToArray(argvs, cJSON_CreateString(curr_proc.cmdline[i]));
295 }
296 }
297 if (cJSON_GetArraySize(argvs) > 0)
298 {
299 cJSON_AddItemToObject(process, "argvs", argvs);
300 }
301 else
302 {
303 cJSON_Delete(argvs);
304 }
305 }
306 cJSON_AddStringToObject(process, "euser", curr_proc.euser);
307 cJSON_AddStringToObject(process, "egroup", curr_proc.egroup);
308 cJSON_AddNumberToObject(process, "resident", curr_proc.resident);
309 cJSON_AddNumberToObject(process, "nlwp", curr_proc.nlwp);
310 cJSON_AddNumberToObject(process, "tty", curr_proc.tty);
311 cJSON_AddNumberToObject(process, "processor", curr_proc.processor);
312 /*
313 cJSON_AddStringToObject(process, "ruser", curr_proc.ruser);
314 cJSON_AddStringToObject(process, "suser", curr_proc.suser);
315 cJSON_AddStringToObject(process, "rgroup", curr_proc.rgroup);
316 cJSON_AddStringToObject(process, "sgroup", curr_proc.sgroup);
317 cJSON_AddStringToObject(process, "fgroup", curr_proc.fgroup);
318 cJSON_AddNumberToObject(process, "priority", curr_proc.priority);
319 cJSON_AddNumberToObject(process, "nice", curr_proc.nice);
320 cJSON_AddNumberToObject(process, "size", curr_proc.size);
321 cJSON_AddNumberToObject(process, "vm_size", curr_proc.vm_size);
322 cJSON_AddNumberToObject(process, "share", curr_proc.share);
323 cJSON_AddNumberToObject(process, "pgrp", curr_proc.pgrp);
324 cJSON_AddNumberToObject(process, "session", curr_proc.session);
325 cJSON_AddNumberToObject(process, "tgid", curr_proc.tgid);
326 */
327 }
328
329 char *msg = cJSON_PrintUnformatted(process);
330 wm_sendmsg( MAX_PIPE_WAIT_USECOND, proc_monitor.queue_fd, msg, location, PROC_COLLECTOR_MQ );
331 free(msg);
332 cJSON_Delete( process );
333
334 return;
335}
336
337 static void get_process_info( const process_parent_child_pair_t *pair, const char *location )
338 {
339 // get process base info
340 get_process_baseinfo( pair, location );
341
342 // get process library info
343
344 // find rootkit in user mode
345
346 // check process is a malware
347 }
348
349static void handle_temp_process( const char *location )
350{
351 int i = 0;
352 for ( i = 0; i < MAX_TEMP_PROCESS; i++ )
353 {
354 if ( ( temp_processes[i].status != PROCESS_SLOT_EMPTY ) && ( temp_processes[i].ppid != 0 ) )
355 {
356 mtdebug1(WM_PROC_LOGTAG, "handle process: %d, parent process:%d", temp_processes[i].pid, temp_processes[i].ppid );
357 get_process_info( &temp_processes[i], location );
358 temp_processes[i].status = PROCESS_SLOT_EMPTY;
359 }
360 }
361}
362
363static void handle_process_fork( const event_msg_t *proc_msg )
364{
365 int i = 0;
366 for ( i = 0; i < MAX_TEMP_PROCESS; i++ )
367 {
368 if ( temp_processes[i].status == PROCESS_SLOT_EMPTY )
369 {
370 get_path_and_md5( proc_msg->proc_ev.event_data.fork.child_pid, temp_processes[i].path, temp_processes[i].md5 );
371 get_path_and_md5( proc_msg->proc_ev.event_data.fork.parent_pid, temp_processes[i].parent_path, temp_processes[i].parent_md5);
372 temp_processes[i].pid = proc_msg->proc_ev.event_data.fork.child_pid;
373 temp_processes[i].ppid = proc_msg->proc_ev.event_data.fork.parent_pid;
374 temp_processes[i].fork_time = time(0);
375 temp_processes[i].status = !PROCESS_SLOT_EMPTY;
376 mtdebug1(WM_PROC_LOGTAG, "fork process: %d, parent process:%d", temp_processes[i].pid, temp_processes[i].ppid );
377 break;
378 }
379 }
380}
381
382static void handle_process_exec( const event_msg_t *proc_msg, const char *location )
383{
384 int i = 0;
385 for ( i = 0; i < MAX_TEMP_PROCESS; i++ )
386 {
387 if (temp_processes[i].pid == proc_msg->proc_ev.event_data.exec.process_pid
388 && temp_processes[i].status != PROCESS_SLOT_EMPTY)
389 {
390 get_path_and_md5( proc_msg->proc_ev.event_data.exec.process_pid, temp_processes[i].path, temp_processes[i].md5 );
391 mtdebug1(WM_PROC_LOGTAG, "exec process: %d, parent process:%d", temp_processes[i].pid, temp_processes[i].ppid );
392 get_process_info( &temp_processes[i], location );
393 temp_processes[i].status = PROCESS_SLOT_EMPTY;
394 break;
395 }
396 }
397}
398
399static void handle_process_exit( const event_msg_t *proc_msg, const char* location )
400{
401 int i = 0;
402 for ( i = 0; i < MAX_TEMP_PROCESS; i++ )
403 {
404 if ( ( temp_processes[i].status != PROCESS_SLOT_EMPTY )
405 && ( proc_msg->proc_ev.event_data.exit.process_pid == temp_processes[i].pid )
406 && ( temp_processes[i].ppid == 0 ) )
407 {
408 temp_processes[i].status = PROCESS_SLOT_EMPTY;
409 return;
410 }
411 }
412
413 cJSON *process = cJSON_CreateObject();
414 cJSON_AddStringToObject(process, "type", "exit");
415 cJSON_AddNumberToObject( process, "pid", proc_msg->proc_ev.event_data.exit.process_pid );
416 cJSON_AddNumberToObject( process, "eventTime", time(0) );
417 cJSON_AddNumberToObject(process, "exitCode", proc_msg->proc_ev.event_data.exit.exit_code);
418 cJSON_AddNumberToObject(process, "exitSignal", (int)proc_msg->proc_ev.event_data.exit.exit_signal);
419
420 char *exit_msg = cJSON_PrintUnformatted( process );
421 wm_sendmsg( MAX_PIPE_WAIT_USECOND, proc_monitor.queue_fd, exit_msg, location, PROC_COLLECTOR_MQ );
422 free( exit_msg );
423 cJSON_Delete( process );
424}
425
426static time_t get_process_start_time( pid_t pid )
427{
428 char path[MAX_PATH_NAME];
429 memset( path, 0, MAX_PATH_NAME);
430
431 snprintf( path, MAX_PATH_NAME-1, "/proc/%d", pid );
432
433 struct stat dir_stat;
434
435 if ( stat( path, &dir_stat) < 0 )
436 {
437 return 0;
438 }
439
440 return dir_stat.st_mtime;
441}
442
443static void get_inventory_processes(const char *location)
444{
445 DIR *proc_dir = opendir( "/proc" );
446 if ( NULL == proc_dir )
447 {
448 mterror( WM_PROC_LOGTAG, "failed to open /proc, errno=(%d:%m)", errno );
449 return;
450 }
451
452 struct dirent *entry = NULL;
453 while ( NULL != ( entry = readdir( proc_dir )))
454 {
455 if ( !strcmp( entry->d_name, "." ) || !strcmp( entry->d_name, ".." ) )
456 {
457 continue;
458 }
459 int pid = atoi( entry->d_name );
460 if ( 0 == pid )
461 {
462 continue;
463 }
464
465 char pid_path[MAX_PATH_NAME];
466 os_md5 md5;
467 memset( pid_path, 0, sizeof( MAX_PATH_NAME));
468 memset( md5, 0, sizeof( os_md5 ) );
469 get_path_and_md5( pid, pid_path, md5 );
470
471 cJSON *process = cJSON_CreateObject();
472 cJSON_AddStringToObject(process, "type", "new process");
473 cJSON_AddNumberToObject(process, "eventTime", time(0));
474 cJSON_AddNumberToObject(process, "pid", pid);
475 cJSON_AddNumberToObject(process, "startTime", get_process_start_time(pid));
476 if (strlen(pid_path) > 0)
477 {
478 cJSON_AddStringToObject(process, "exe", pid_path);
479 }
480 if (strlen(md5) > 0)
481 {
482 cJSON_AddStringToObject(process, "md5", md5);
483 }
484
485 proc_t curr_proc;
486 memset( &curr_proc, 0, sizeof( proc_t ));
487 if ( NULL != get_proc_stats(pid, &curr_proc ))
488 {
489 cJSON_AddStringToObject(process, "state", &curr_proc.state);
490 cJSON_AddNumberToObject(process, "utime", curr_proc.utime);
491 cJSON_AddNumberToObject(process, "stime", curr_proc.stime);
492 cJSON_AddStringToObject(process, "euser", curr_proc.euser);
493 cJSON_AddStringToObject(process, "egroup", curr_proc.egroup);
494 cJSON_AddNumberToObject(process, "resident", curr_proc.resident);
495 cJSON_AddNumberToObject(process, "nlwp", curr_proc.nlwp);
496 cJSON_AddNumberToObject(process, "tty", curr_proc.tty);
497 cJSON_AddNumberToObject(process, "processor", curr_proc.processor);
498 /*
499 cJSON_AddStringToObject(process, "ruser", curr_proc.ruser);
500 cJSON_AddStringToObject(process, "suser", curr_proc.suser);
501 cJSON_AddStringToObject(process, "rgroup", curr_proc.rgroup);
502 cJSON_AddStringToObject(process, "sgroup", curr_proc.sgroup);
503 cJSON_AddStringToObject(process, "fgroup", curr_proc.fgroup);
504
505 cJSON_AddNumberToObject(process, "priority", curr_proc.priority);
506 cJSON_AddNumberToObject(process, "nice", curr_proc.nice);
507 cJSON_AddNumberToObject(process, "size", curr_proc.size);
508 cJSON_AddNumberToObject(process, "vm_size", curr_proc.vm_size);
509 cJSON_AddNumberToObject(process, "share", curr_proc.share);
510 cJSON_AddNumberToObject(process, "pgrp", curr_proc.pgrp);
511 cJSON_AddNumberToObject(process, "session", curr_proc.session);
512 cJSON_AddNumberToObject(process, "tgid", curr_proc.tgid);
513 */
514
515 memset(pid_path, 0, sizeof(MAX_PATH_NAME));
516 memset(md5, 0, sizeof(os_md5));
517 get_path_and_md5(curr_proc.ppid, pid_path, md5);
518 if (strlen(pid_path) > 0)
519 {
520 cJSON_AddStringToObject(process, "parent_exe", pid_path);
521 }
522 if (strlen(md5) > 0)
523 {
524 cJSON_AddStringToObject(process, "parent_md5", md5);
525 }
526 }
527
528 char *msg = cJSON_PrintUnformatted(process);
529 wm_sendmsg(MAX_PIPE_WAIT_USECOND, proc_monitor.queue_fd, msg, location, PROC_COLLECTOR_MQ);
530 free(msg);
531 cJSON_Delete(process);
532 }
533
534 closedir( proc_dir);
535}
536
537int wm_proc_linux_process(wm_proc_t *proc, const char *location)
538{
539 int rc;
540 event_msg_t proc_msg;
541 fd_set readfds;
542 int max_fd = proc_monitor.proc_fd + 1;
543 struct timeval tv;
544
545 if (proc->flags.enabled == 0)
546 {
547 return 0;
548 merror("process collector disabled, let us rest.");
549 }
550
551
552 merror("process collector enabled, let us work.");
553
554 get_inventory_processes(location);
555
556 tv.tv_sec = 5;
557 tv.tv_usec = 0;
558
559 while (1)
560 {
561 FD_ZERO(&readfds);
562 FD_SET(proc_monitor.proc_fd, &readfds);
563
564 rc = select(max_fd, &readfds, NULL, NULL, &tv);
565 if (0 == rc)
566 {
567 handle_temp_process(location);
568 tv.tv_sec = 5;
569 tv.tv_usec = 0;
570 continue;
571 }
572 if (-1 == rc)
573 {
574 if (errno == EINTR)
575 {
576 continue;
577 }
578 mterror(WM_PROC_LOGTAG, "failed to listen to netlink socket, errno=(%d:%m)", errno);
579 return rc;
580 }
581 if (FD_ISSET(proc_monitor.proc_fd, &readfds))
582 {
583 rc = recv(proc_monitor.proc_fd, &proc_msg, sizeof(proc_msg), 0);
584 if (rc > 0)
585 {
586 switch (proc_msg.proc_ev.what)
587 {
588 case proc_event::PROC_EVENT_FORK:
589 handle_process_fork(&proc_msg);
590 tv.tv_sec = 1;
591 tv.tv_usec = 1000;
592 break;
593 case proc_event::PROC_EVENT_EXEC:
594 handle_process_exec(&proc_msg, location);
595 break;
596 case proc_event::PROC_EVENT_COMM:
597 break;
598 case proc_event::PROC_EVENT_EXIT:
599 handle_process_exit(&proc_msg, location);
600 break;
601 default:
602 break;
603 }
604 }
605 else if (rc == -1)
606 {
607 if (errno == EINTR)
608 {
609 continue;
610 }
611 mterror(WM_PROC_LOGTAG, "failed to received from netlink socket, errno=(%d:%m)", errno);
612 }
613 }
614 }
615
616 return 0;
617}
618#endif \ No newline at end of file
diff --git a/connector/proc_mon_linux.cpp b/connector/proc_mon_linux.cpp
new file mode 100755
index 0000000..16dd51c
--- /dev/null
+++ b/connector/proc_mon_linux.cpp
@@ -0,0 +1,487 @@
1#ifndef WIN32
2#include <unistd.h>
3#include <sys/socket.h>
4#include <algorithm>
5#include "shared.h"
6#include "proc_mon_linux.h"
7#include <malloc.h>
8#include "linux_proc_baseline.h"
9
10
11#define MAX_PIPE_WAIT_USECOND 100
12#define PROCESS_SCAN_ITERTIME 10
13const char *WM_PROC_LOCATION = "proc_collector";
14
15ProcMon* ProcMon::m_instance = NULL;
16
17ProcMon& ProcMon::instance()
18{
19 if ( m_instance == NULL )
20 {
21 m_instance = new ProcMon;
22 }
23
24 return *m_instance;
25}
26
27void ProcMon::destroy()
28{
29 delete m_instance;
30 m_instance = NULL;
31}
32
33int ProcMon::init( const wm_proc_t* config )
34{
35 pthread_mutex_init(&m_mutex, NULL);
36 setConfig( config );
37
38 int ret = setupNetlink();
39 if (ret != 0 )
40 {
41 fini();
42 return -1;
43 }
44
45 ret = setupMQ();
46 if (ret != 0 )
47 {
48 fini();
49 return -1;
50 }
51
52 return 0;
53}
54
55int ProcMon::working()
56{
57 int rc;
58 event_msg_t procMsg;
59 fd_set readfds;
60 int maxfd = m_procFd + 1;
61 struct timeval tv;
62 time_t last = time(0);
63
64 if ( m_config.flags.enabled == 0 )
65 {
66 return 0;
67 }
68
69 getInventoryProcesses();
70
71
72 while ( 1 )
73 {
74 FD_ZERO(&readfds);
75 FD_SET( m_procFd, &readfds );
76 tv.tv_sec = 1;
77 tv.tv_usec = 0;
78
79 if ( time(0) - last > PROCESS_SCAN_ITERTIME )
80 {
81 // scan processes
82 scanProcesses(last);
83 last = time(0);
84 }
85
86 rc = select( maxfd, &readfds, NULL, NULL, &tv );
87 if ( 0 == rc )
88 {
89 continue;
90 }
91
92 if ( -1 == rc )
93 {
94 if ( errno == EINTR )
95 {
96 continue;
97 }
98
99 mterror(WM_PROC_LOGTAG, "failed to listen to netlink socket, errno=(%d:%m)", errno);
100 return rc;
101 }
102
103 if ( FD_ISSET( m_procFd, &readfds ) )
104 {
105 rc = recv( m_procFd, &procMsg, sizeof(procMsg), 0 );
106 if( rc > 0 )
107 {
108 switch (procMsg.proc_ev.what)
109 {
110 case proc_event::PROC_EVENT_FORK:
111 handleForkMsg(procMsg);
112 break;
113 case proc_event::PROC_EVENT_EXEC:
114 handleExecMsg(procMsg);
115 break;
116 case proc_event::PROC_EVENT_COMM:
117 break;
118 case proc_event::PROC_EVENT_EXIT:
119 handleExitMsg(procMsg);
120 break;
121 default:
122 break;
123 }
124 }
125 else if (rc == -1)
126 {
127 if (errno == EINTR)
128 {
129 continue;
130 }
131 mterror(WM_PROC_LOGTAG, "failed to received from netlink socket, errno=(%d:%m)", errno);
132 }
133 }
134
135 malloc_trim(0);
136 }
137}
138
139ProcMon::ProcMon()
140{
141 m_mutex = PTHREAD_MUTEX_INITIALIZER;
142 m_processes.clear();
143 m_pidCache.clear();
144 m_procFd = -1;
145 m_queueFd = -1;
146}
147
148ProcMon::~ProcMon()
149{
150 fini();
151}
152
153void ProcMon::setConfig( const wm_proc_t* config )
154{
155 m_config.flags.enabled = config->flags.enabled;
156 m_config.flags.rootcheck = config->flags.rootcheck;
157 m_config.flags.limitcheck = config->flags.limitcheck;
158 m_config.flags.environcheck = config->flags.environcheck;
159 m_config.flags.statuscheck = config->flags.statuscheck;
160 m_config.flags.threadcheck = config->flags.threadcheck;
161 m_config.flags.cgroupcheck = config->flags.cgroupcheck;
162 m_config.flags.libcheck = config->flags.libcheck;
163 m_config.flags.malwarecheck = config->flags.malwarecheck;
164 m_config.interval = config->interval;
165}
166
167int ProcMon::setupNetlink()
168{
169 int rc;
170 int nl_sock;
171 struct sockaddr_nl sa_nl;
172 register_msg_t nlcn_msg;
173
174 nl_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
175 if (nl_sock == -1)
176 {
177 mterror(WM_PROC_LOGTAG, "Can't open netlink socket");
178 return -1;
179 }
180
181 sa_nl.nl_family = AF_NETLINK;
182 sa_nl.nl_groups = CN_IDX_PROC;
183 sa_nl.nl_pid = getpid();
184
185 rc = bind(nl_sock, (struct sockaddr *)&sa_nl, sizeof(sa_nl));
186 if (rc == -1)
187 {
188 mterror(WM_PROC_LOGTAG, "Can't bind netlink socket");
189 close(nl_sock);
190 return -1;
191 }
192
193 // create listener
194 memset(&nlcn_msg, 0, sizeof(nlcn_msg));
195 nlcn_msg.nl_hdr.nlmsg_len = sizeof(nlcn_msg);
196 nlcn_msg.nl_hdr.nlmsg_pid = getpid();
197 nlcn_msg.nl_hdr.nlmsg_type = NLMSG_DONE;
198
199 nlcn_msg.cn_msg.id.idx = CN_IDX_PROC;
200 nlcn_msg.cn_msg.id.val = CN_VAL_PROC;
201 nlcn_msg.cn_msg.len = sizeof(enum proc_cn_mcast_op);
202
203 nlcn_msg.cn_mcast = PROC_CN_MCAST_LISTEN;
204
205 rc = send(nl_sock, &nlcn_msg, sizeof(nlcn_msg), 0);
206 if (rc == -1)
207 {
208 mterror(WM_PROC_LOGTAG, "can't register to netlink");
209 close(nl_sock);
210 return -1;
211 }
212
213 m_procFd = nl_sock;
214 return 0;
215}
216
217int ProcMon::setupMQ()
218{
219 unsigned int indx;
220 // Connect to socket
221 for (indx = 0; indx < WM_MAX_ATTEMPTS; indx++)
222 {
223 m_queueFd = StartMQ(DEFAULTQPATH, WRITE);
224 if (m_queueFd > 0)
225 {
226 break;
227 }
228 wm_delay(1000 * WM_MAX_WAIT);
229 }
230
231 if (indx == WM_MAX_ATTEMPTS)
232 {
233 mterror(WM_PROC_LOGTAG, "Can't connect to queue.");
234 pthread_exit(NULL);
235 }
236
237 return 0;
238}
239
240
241void ProcMon::fini()
242{
243 m_processes.clear();
244 m_pidCache.clear();
245 if (m_procFd != -1 )
246 {
247 close( m_procFd);
248 m_procFd = -1;
249 }
250
251 if (m_queueFd != -1 )
252 {
253 close( m_queueFd);
254 m_queueFd = -1;
255 }
256}
257
258void ProcMon::getInventoryProcesses()
259{
260 DIR *procDir = opendir( "/proc" );
261 if ( NULL == procDir )
262 {
263 mterror(WM_PROC_LOGTAG, "failed to open /proc, errno=(%d:%m)", errno);
264 return;
265 }
266
267 struct dirent *entry = NULL;
268 while (NULL != (entry = readdir(procDir)))
269 {
270 if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
271 {
272 continue;
273 }
274 int pid = atoi(entry->d_name);
275 if (0 == pid)
276 {
277 continue;
278 }
279
280 Process *proc = new Process(pid);
281 if ( NULL == proc )
282 {
283 continue;
284 }
285 if(0 != proc->init())
286 {
287 delete proc;
288 proc = NULL;
289 continue;
290 }
291 std::pair<std::map<pid_t, Process*>::iterator,bool> ret = m_processes.insert(std::make_pair(pid, proc));
292 if(!ret.second)
293 {
294 delete proc;
295 proc = NULL;
296 continue;
297 }
298 std::vector<std::string> events = proc->getEvents();
299 if ( !events.empty() )
300 {
301 reportEvents(events);
302 }
303 usleep( 500 );
304 }
305
306 return;
307}
308
309void ProcMon::handleForkMsg( const event_msg_t& procMsg )
310{
311 pid_t pid = procMsg.proc_ev.event_data.fork.child_pid;
312 auto iter = m_pidCache.find( pid );
313 if ( iter != m_pidCache.end() )
314 {
315 m_pidCache.erase(iter);
316 return;
317 }
318
319 PidRelation relation;
320 relation.pid = pid;
321 relation.ppid = procMsg.proc_ev.event_data.fork.parent_pid;
322 relation.pidEvent = PidRelation::FORKEVENT;
323 relation.born = time(0);
324
325 m_pidCache.insert( std::make_pair(relation.pid, relation ));
326}
327
328void ProcMon::handleExecMsg( const event_msg_t& procMsg )
329{
330 pid_t pid = procMsg.proc_ev.event_data.exec.process_pid;
331 auto iter = m_pidCache.find( pid );
332 if ( iter == m_pidCache.end() )
333 {
334 return;
335 }
336
337 //mterror(WM_PROC_LOGTAG, "cache size:%lu", m_pidCache.size());
338 Process *proc = new Process( pid, iter->second.ppid, iter->second.born );
339 if ( NULL == proc )
340 {
341 return;
342 }
343 // check hidden process
344 if ( 0 != proc->init() )
345 {
346 return;
347 }
348 m_processes.insert( std::make_pair(pid, proc ));
349 std::vector<std::string> events = proc->getEvents();
350 if (!events.empty())
351 {
352 reportEvents(events);
353 }
354// m_pidCache.erase(iter);
355 //mterror(WM_PROC_LOGTAG, "exec process:%d exe:%s", pid, proc.exe().c_str());
356}
357
358void ProcMon::handleExitMsg( const event_msg_t& procMsg )
359{
360 pid_t pid = procMsg.proc_ev.event_data.exit.process_pid;
361 auto iter = m_pidCache.find( pid );
362 if ( iter != m_pidCache.end() )
363 {
364 m_pidCache.erase(iter);
365 }
366
367 auto procIter = m_processes.find(pid);
368 if ( procIter == m_processes.end() )
369 {
370 return;
371 }
372
373 std::vector<int> signals{ 3, 9, 10, 12, 15,16,17,30,31};
374
375 //if ( signals.end() == std::find( signals.begin(), signals.end(), procMsg.proc_ev.event_data.exit.exit_signal )
376 //|| (procMsg.proc_ev.event_data.exit.exit_code != 0))
377 {
378 // report abnormal events
379 cJSON *obj= cJSON_CreateObject();
380 cJSON_AddStringToObject(obj, "type", "exit");
381 cJSON_AddStringToObject(obj, "exe", procIter->second->exe().c_str());
382 cJSON_AddNumberToObject(obj, "pid", procIter->first);
383 cJSON_AddNumberToObject(obj, "event_time", time(0));
384 cJSON_AddNumberToObject(obj, "exit_signal", procMsg.proc_ev.event_data.exit.exit_signal);
385 cJSON_AddNumberToObject(obj, "exit_code", procMsg.proc_ev.event_data.exit.exit_code);
386 char *data = cJSON_PrintUnformatted( obj );
387 std::string msg(data);
388 free(data);
389 reportEvent( msg );
390 cJSON_Delete(obj);
391 //mterror(WM_PROC_LOGTAG, "%s", msg.c_str());
392 }
393
394 delete procIter->second;
395 m_processes.erase(procIter);
396 //mterror(WM_PROC_LOGTAG, "process collection:%d", m_processes.size());
397}
398
399void ProcMon::scanProcesses(time_t last)
400{
401 time_t now = time(0);
402// mterror(WM_PROC_LOGTAG, "pid cache size: %d , process collection size : %d", m_pidCache.size(), m_processes.size());
403 for (auto iter = m_pidCache.begin(); iter != m_pidCache.end(); )
404 {
405 if ( now - iter->second.born < 1 || m_processes.find(iter->second.pid) != m_processes.end())
406 {
407 iter++;
408 }
409 else
410 {
411 Process *proc = new Process( iter->second.pid, iter->second.ppid, iter->second.born);
412 if (NULL != proc )
413 {
414 if(0 != proc->init())
415 {
416 delete proc;
417 proc = NULL;
418 continue;
419 }
420 std::pair<std::map<pid_t, Process*>::iterator, bool> ret = m_processes.insert(std::make_pair(iter->first, proc));
421 if(!ret.second)
422 {
423 delete proc;
424 proc = NULL;
425 continue;
426 }
427 std::vector<std::string> events = proc->getEvents();
428 if (!events.empty())
429 {
430 reportEvents(events);
431 }
432
433 }
434 else
435 {
436 // hidden process found
437 cJSON *obj = cJSON_CreateObject();
438 cJSON_AddStringToObject(obj, "type", "rootkit");
439 cJSON_AddNumberToObject(obj, "pid", iter->first);
440 cJSON_AddNumberToObject(obj, "event_time", iter->second.born);
441 cJSON_AddNumberToObject(obj, "ppid", iter->second.ppid);
442 auto parent = m_processes.find(iter->second.ppid);
443 if (parent != m_processes.end())
444 {
445 cJSON_AddStringToObject(obj, "parent exe", parent->second->exe().c_str());
446 }
447 char *data = cJSON_PrintUnformatted(obj);
448 std::string msg(data);
449 free(data);
450 reportEvent(msg);
451 cJSON_Delete(obj);
452 }
453 iter = m_pidCache.erase(iter);
454 }
455 usleep( 500 );
456 }
457/*
458 if ( now - last < 60 )
459 {
460 return;
461 }
462*/
463 for (auto& procIter : m_processes )
464 {
465 procIter.second->scan();
466 std::vector<std::string> events = procIter.second->getEvents();
467 if (!events.empty())
468 {
469 reportEvents(events);
470 }
471 usleep( 5000 );
472 }
473}
474
475void ProcMon::reportEvent( const std::string& event )
476{
477 wm_sendmsg(MAX_PIPE_WAIT_USECOND, m_queueFd, event.c_str(), WM_PROC_LOCATION, PROC_COLLECTOR_MQ);
478}
479
480void ProcMon::reportEvents(const std::vector<std::string> &events)
481{
482 for (auto it : events)
483 {
484 wm_sendmsg(MAX_PIPE_WAIT_USECOND, m_queueFd, it.c_str(), WM_PROC_LOCATION, PROC_COLLECTOR_MQ);
485 }
486}
487#endif
diff --git a/connector/test.c b/connector/test.c
new file mode 100644
index 0000000..c12ad10
--- /dev/null
+++ b/connector/test.c
@@ -0,0 +1,64 @@
1#define _GNU_SOURCE
2#include <sched.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <sys/types.h>
6#include <sys/wait.h>
7#include <sys/syscall.h>
8#include <unistd.h>
9#include <pthread.h>
10
11#define STACK_SIZE (1024 * 1024) // 定义栈大小
12
13// 子任务的入口函数
14void *child_func(void *arg)
15{
16 printf("子任务: PID=%ld, PPID=%ld, TID=%ld\n", (long)getpid(),
17 (long)getppid(), (long)syscall(SYS_gettid));
18 sleep(3);
19}
20
21int main()
22{
23 char *stack; // 栈的指针
24 char *stack_top; // 栈顶的指针
25 pid_t child_tid;
26 pid_t forkPid;
27 pid_t threadPid;
28
29 printf("主任务:我是%d\n", getpid());
30 if ((forkPid = fork()) == 0)
31 {
32 sleep(3);
33 exit(0);
34 }
35 printf("主任务:fork子任务 %d\n", forkPid);
36
37 pthread_create(&threadPid, NULL, child_func, NULL);
38 printf("主任务:create新线程%d\n", threadPid);
39
40 // 使用 clone 创建子任务
41 child_tid = clone(child_func, stack_top, SIGCHLD, NULL);
42 if (child_tid == -1)
43 {
44 perror("clone");
45 free(stack);
46 exit(EXIT_FAILURE);
47 }
48
49 printf("主任务: 创建了子任务, TID=%ld\n", (long)child_tid);
50
51 // 等待子任务结束
52 if (waitpid(child_tid, NULL, 0) == -1)
53 {
54 perror("waitpid");
55 free(stack);
56 exit(EXIT_FAILURE);
57 }
58
59 // 释放分配的栈
60 // free(stack);
61
62 printf("主任务: 子任务结束\n");
63 return 0;
64}
diff --git a/src/deal.go b/src/deal.go
index aaac8c5..717344c 100644
--- a/src/deal.go
+++ b/src/deal.go
@@ -55,18 +55,25 @@ func deal() {
55 break 55 break
56 } 56 }
57 57
58 // fmt.Printf("%v\n", cooked)
59
58 switch cooked.tag { 60 switch cooked.tag {
59 case NEWPID: 61 case NEWPID:
60 dealNewPid(cooked) 62 dealNewPid(cooked)
61 case EXECVE: 63 case EXECVE:
64 check(cooked)
62 dealExecve(cooked) 65 dealExecve(cooked)
63 case PIDEXIT: 66 case PIDEXIT:
67 check(cooked)
64 deletePid(cooked) 68 deletePid(cooked)
65 case FILEOPEN: 69 case FILEOPEN:
70 check(cooked)
66 fileOpen(cooked) 71 fileOpen(cooked)
67 case FILEWRITE: 72 case FILEWRITE:
73 check(cooked)
68 fileWrite(cooked) 74 fileWrite(cooked)
69 case FILECLOSE: 75 case FILECLOSE:
76 check(cooked)
70 fileClose(cooked) 77 fileClose(cooked)
71 } 78 }
72 } 79 }
@@ -168,19 +175,19 @@ func dealExecve(cooked Event) {
168 }, 175 },
169 }, 176 },
170 }) 177 })
171 } else { 178 // } else {
172 // 先fork抵达,插入 179 // // 先fork抵达,插入
173 pidCol.InsertOne(bson.M{ 180 // pidCol.InsertOne(bson.M{
174 "ppid": cooked.ppid, 181 // "ppid": cooked.ppid,
175 "pid": cooked.pid, 182 // "pid": cooked.pid,
176 "children": []bson.M{}, 183 // "children": []bson.M{},
177 "execve": []bson.M{ 184 // "execve": []bson.M{
178 { 185 // {
179 "timestamp": cooked.timestamp, 186 // "timestamp": cooked.timestamp,
180 "execArgs": cooked.argv, 187 // "execArgs": cooked.argv,
181 }, 188 // },
182 }, 189 // },
183 }) 190 // })
184 } 191 }
185 mongoMutex.Unlock() 192 mongoMutex.Unlock()
186} 193}
@@ -255,3 +262,27 @@ func fileWrite(cooked Event) {
255 "close_timestamp": bson.M{"$exists": false}, 262 "close_timestamp": bson.M{"$exists": false},
256 }, bson.M{"$push": bson.M{"written": cooked.timestamp}}) 263 }, bson.M{"$push": bson.M{"written": cooked.timestamp}})
257} 264}
265
266func check(cooked Event) {
267 // 检查进程是否需要记录
268 // 有无父进程在观察中
269 docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid})
270 if err != nil || len(docRes) != 1 {
271 return
272 }
273
274 // 自身是否已经记录
275 docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.pid})
276 if err != nil {
277 fmt.Printf("Err finding: %v\n", err)
278 return
279 }
280 if len(docRes) == 0 {
281 pidCol.InsertOne(bson.M{
282 "ppid": cooked.ppid,
283 "pid": cooked.pid,
284 "children": []bson.M{},
285 "start_timestamp": cooked.timestamp,
286 })
287 }
288}
diff --git a/src/global.go b/src/global.go
index d1c5c0f..f0f909c 100644
--- a/src/global.go
+++ b/src/global.go
@@ -1,8 +1,11 @@
1package main 1package main
2 2
3import ( 3import (
4 "fmt"
4 "sync" 5 "sync"
5 "time" 6 "time"
7
8 "go.mongodb.org/mongo-driver/bson/primitive"
6) 9)
7 10
8type eventType int 11type eventType int
@@ -12,11 +15,19 @@ const (
12 PIDEXIT 15 PIDEXIT
13 EXECVE 16 EXECVE
14 FILEOPEN 17 FILEOPEN
15 FILEWRITE
16 FILECLOSE 18 FILECLOSE
19 FILEWRITE
17 TYPENUM 20 TYPENUM
18) 21)
19 22
23func (et eventType) String() string {
24 names := []string{"NEWPID", "PIDEXIT", "EXECVE", "FILEOPEN", "FILECLOSE", "FILEWRITE", "TYPENUM"}
25 if et < NEWPID || et > TYPENUM {
26 return "Unknown"
27 }
28 return names[et]
29}
30
20type Event struct { 31type Event struct {
21 tag eventType 32 tag eventType
22 timestamp time.Time 33 timestamp time.Time
@@ -30,12 +41,37 @@ type Event struct {
30 pathName string 41 pathName string
31} 42}
32 43
33func (et eventType) String() string { 44func (event Event) String() string {
34 names := []string{"NEWPID", "PIDEXIT", "EXECVE", "FILEOPEN", "FILEWRITE", "TYPENUM"} 45 var res string
35 if et < NEWPID || et > TYPENUM { 46 res = fmt.Sprintf("tag: %v\ntimestamp: %v\nppid: %d\npid: %d\n", event.tag, event.timestamp.Local(), event.ppid, event.pid)
36 return "Unknown" 47 res += fmt.Sprintf("syscall: %s\nexit_code: %d\nargs: \n", syscallTable[event.syscall], event.exit_code)
48 for i := 0; i < len(event.argv); i++ {
49 res += fmt.Sprintf("\t\"%s\"\n", event.argv[i])
37 } 50 }
38 return names[et] 51 res += "syscallParam: "
52 for i := 0; i < len(event.syscallParam); i++ {
53 res += fmt.Sprintf("\t\"%d\"\n", event.syscallParam[i])
54 }
55 res += "pathName: \"" + event.pathName + "\"\n------\n"
56 return res
57}
58
59type pidExec struct {
60 timestamp time.Time `bson:"timestamp"`
61 execArgs []string `bson:"execArgs"`
62}
63
64type pid struct {
65 ID primitive.ObjectID `bson:"_id,ometempty"`
66 start_timestamp time.Time `bson:"start_timestamp"`
67 ppid int `bson:"ppid"`
68 pid int `bson:"pid"`
69 cwd string `bson:"cwd"`
70 args []string `bson:"args"`
71 execve []pidExec `bson:"execve"`
72 children []int `bson:"children"`
73 exit_timestamp time.Time `bson:"exit_timestamp"`
74 exit_code uint64 `bson:"exit_code"`
39} 75}
40 76
41var wg sync.WaitGroup // 掌管协程 77var wg sync.WaitGroup // 掌管协程