summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWe-unite <3205135446@qq.com>2024-07-23 19:32:09 +0800
committerWe-unite <3205135446@qq.com>2024-07-25 17:09:45 +0800
commitfc61a4a525846fa31ee2288df4e82f745bb39c95 (patch)
treee97c7b942c7e843782efbcc48882e6c0854df473
parentcf5618ff2e2a183c5bdf6444787dccdcbf26ce76 (diff)
downloadgodo-fc61a4a525846fa31ee2288df4e82f745bb39c95.tar.gz
godo-fc61a4a525846fa31ee2288df4e82f745bb39c95.zip
Try ot fix the out-of-order bug, add EXECVE to itthings_left
The Most important work during this time is to find out solution to the out-of-order bug. Discribe it here in detail: info from audit may be out of order, which means fork may comes after execve, even after exit. What an absurd penomenon to see a process not yet created to work or exit! To deal with this problem, I've tried several ways: - in the 2nd coroutine, when EOE msg comes, if it's a fork/clone event, send it immediately, otherwise wait for some time(such as 100 ms). But after all it delays longer, and has other problems. - the 2nd coroutine doesn't send directly, but record all the finished event id in a slice, and another thread checks once every one second, if there are sth in slice, send corresponding events in the order of event id. But: event that happens first doesn't always has lower id or time, for example, 1 forks 2, then 2 execve, the audit in kernel it self may gets execve before fork(maybe fork makes other settings), which means execve has earlier timestamp and lower event id. The out- of-order problem is not completely resolved. If we then add delays to non-clone event, a more serious problem happens: we must use mutex to lock the slice recording finished event id to prevent crush between send thread and wait thread, but the wait thread can't get the mutex again, because there are to much clone event and frequent send! - So I use no delay but mongodb, when an execve comes, if pid is not recorded, just insert it and wait for the fork. It does works, but some other works is still left to do: - what should i do if 2 forks 3 comes before 1 forks 2? Now I suggest it doesn't happen, but what if? - when execve comes before fork, i recorded it, but if this process has a parent i don't care, delete, or stays there? Also, as mentioned above, I've add EXECVE field in process into db, records all the execve(time, and args) from the same process. Besides, exit_timestamp and exit_code can be caught now, but too many process has no exit info. This is also to be fixed. Now, let's listen to the file changed by process. Don't forget the to-do works listed above!
-rw-r--r--src/basefunc.go40
-rw-r--r--src/deal.go173
-rw-r--r--src/global.go2
-rw-r--r--src/godo.go18
-rw-r--r--src/mongo.go79
-rw-r--r--src/organize.go79
6 files changed, 266 insertions, 125 deletions
diff --git a/src/basefunc.go b/src/basefunc.go
index 5fff3e8..2f39507 100644
--- a/src/basefunc.go
+++ b/src/basefunc.go
@@ -4,32 +4,46 @@ import (
4 "bufio" 4 "bufio"
5 "fmt" 5 "fmt"
6 "os" 6 "os"
7 "os/exec"
7 "path/filepath" 8 "path/filepath"
8 "regexp"
9 "strconv" 9 "strconv"
10 "strings" 10 "strings"
11 "time" 11 "time"
12) 12)
13 13
14func figureOutSyscalls() error { 14func figureOutSyscalls() error {
15 NRRegex := regexp.MustCompile(`#define __NR_(.*?) (\d+)$`) 15 cmd := exec.Command("ausyscall", "--dump")
16 file, err := os.Open("/usr/include/asm/unistd_64.h") 16 stdout, err := cmd.StdoutPipe()
17 if err != nil { 17 if err != nil {
18 return err 18 return err
19 } 19 }
20 defer file.Close()
21 20
22 scanner := bufio.NewScanner(file) 21 if err := cmd.Start(); err != nil {
23 for scanner.Scan() { 22 return err
23 }
24
25 scanner := bufio.NewScanner(stdout)
26 for i := 0; scanner.Scan(); i++ {
27 if i == 0 {
28 continue
29 }
24 line := scanner.Text() 30 line := scanner.Text()
25 if NRRegex.MatchString(line) { 31 parts := strings.Split(line, "\t")
26 match := NRRegex.FindStringSubmatch(line) 32 if len(parts) != 2 {
27 num, err := strconv.Atoi(match[2]) 33 return fmt.Errorf("invalid ausyscall format")
28 if err != nil {
29 return err
30 }
31 syscallTable[num] = match[1]
32 } 34 }
35 num, err := strconv.Atoi(parts[0])
36 if err != nil {
37 return err
38 }
39 syscallTable[num] = parts[1]
40 }
41
42 if err := scanner.Err(); err != nil {
43 return err
44 }
45 if err := cmd.Wait(); err != nil {
46 return err
33 } 47 }
34 return nil 48 return nil
35} 49}
diff --git a/src/deal.go b/src/deal.go
index 118d914..783dab8 100644
--- a/src/deal.go
+++ b/src/deal.go
@@ -1,51 +1,48 @@
1package main 1package main
2 2
3import ( 3import (
4 "context"
5 "fmt" 4 "fmt"
5 "sync"
6 "time" 6 "time"
7 7
8 "go.mongodb.org/mongo-driver/bson" 8 "go.mongodb.org/mongo-driver/bson"
9 "go.mongodb.org/mongo-driver/mongo"
10 "go.mongodb.org/mongo-driver/mongo/options"
11) 9)
12 10
13const ( 11const (
14 dbName string = "test" 12 dbName string = "test"
15 colName string = "pids" 13 pidColName string = "pids"
16) 14)
17 15
16var mongoMutex sync.Mutex
17var pidCol mongoClient
18
18func deal() { 19func deal() {
19 defer wg.Done() 20 defer wg.Done()
20 var cooked Event 21 var cooked Event
21 var ok bool 22 var ok bool
22 23
23 var err error 24 var err error
24 var mongo *mongo.Client
25 var res []bson.M 25 var res []bson.M
26 26
27 mongo, err = connect() 27 if err = pidCol.Connect(dbName, pidColName); err != nil {
28 if err != nil { 28 fmt.Printf("Error connecting the mongodb: %v\n", err)
29 fmt.Printf("Err connecting the mongodb: %v\n", err)
30 } 29 }
31 pidCol := mongo.Database(dbName).Collection(colName) 30 if err = pidCol.Drop(); err != nil {
32 31 fmt.Printf("Error drop the mongodb: %v\n", err)
33 err = pidCol.Drop(context.Background())
34 if err != nil {
35 fmt.Printf("Err drop: %v\n", err)
36 } 32 }
37 33
38 _, err = pidCol.InsertOne(context.Background(), bson.M{ 34 err = pidCol.InsertOne(bson.M{
39 "ppid": 1, 35 "ppid": 1,
40 "pid": containerdPid, 36 "pid": containerdPid,
41 "cwd": "/", 37 "cwd": "/",
38 "children": bson.M{},
42 }) 39 })
43 if err != nil { 40 if err != nil {
44 fmt.Printf("Err containerd: %v", err) 41 fmt.Printf("Err containerd: %v", err)
45 return 42 return
46 } 43 }
47
48 fmt.Printf("Containerd: %d\n", containerdPid) 44 fmt.Printf("Containerd: %d\n", containerdPid)
45 defer pidCol.Disconnect()
49 46
50 for { 47 for {
51 cooked, ok = <-cookedChan 48 cooked, ok = <-cookedChan
@@ -54,81 +51,115 @@ func deal() {
54 } 51 }
55 52
56 switch syscallTable[cooked.syscall] { 53 switch syscallTable[cooked.syscall] {
57 case "fork", "vfork", "clone": 54 case "clone":
58 // 有无父进程在观察中 55 // 有无父进程在观察中
59 res, err = findDocuments(mongo, "test", "pids", bson.M{"pid": cooked.ppid}) 56 res, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid})
60 if err != nil || len(res) != 1 { 57 if err != nil || len(res) != 1 {
61 break 58 break
62 } 59 }
63 60
64 // 自身是否已经记录 61 // 自身是否已经记录
65 res, err = findDocuments(mongo, "test", "pids", bson.M{"pid": cooked.pid}) 62 res, err = pidCol.Finddoc(bson.M{"pid": cooked.pid})
66 if err != nil { 63 if err != nil {
67 fmt.Printf("Err finding: %v\n", err) 64 fmt.Printf("Err finding: %v\n", err)
68 break 65 break
69 } else if len(res) != 0 {
70 fmt.Printf("Err inserting pid %v: already in db: %v\n", cooked.pid, res)
71 break
72 }
73
74 doc := []bson.A{}
75 for _, str := range cooked.argv {
76 doc = append(doc, bson.A{str})
77 } 66 }
78 _, err := pidCol.InsertOne(context.Background(), bson.M{ 67 mongoMutex.Lock()
79 "timestamp": cooked.timestamp, 68 if len(res) != 0 {
80 "ppid": cooked.ppid, 69 // 进程原本就存在,换言之别的消息先到了
81 "pid": cooked.pid, 70 // 所有先行抵达的消息必须保留execve/children字段
82 "cwd": cooked.cwd, 71 // 此处不再更新
83 "args": doc, 72 // 以防把原有信息更没了
84 "children": []bson.M{}, 73 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{
85 }) 74 "start_timestamp": cooked.timestamp,
86 if err != nil { 75 "ppid": cooked.ppid,
87 fmt.Printf("Err insert: %v\n", err) 76 "pid": cooked.pid,
77 "cwd": cooked.cwd,
78 // "execve": []bson.M{},
79 "args": cooked.argv,
80 // "children": []bson.M{},
81 })
82 } else {
83 // 这进程本是新修的
84 pidCol.InsertOne(bson.M{
85 "start_timestamp": cooked.timestamp,
86 "ppid": cooked.ppid,
87 "pid": cooked.pid,
88 "cwd": cooked.cwd,
89 "execve": []bson.M{},
90 "args": cooked.argv,
91 "children": []bson.M{},
92 })
88 } 93 }
89 94
90 _, err = pidCol.UpdateOne(context.Background(), bson.M{"pid": cooked.pid}, bson.M{ 95 pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{
91 "$push": bson.M{ 96 "$push": bson.M{
92 "children": cooked.pid, 97 "children": cooked.pid,
93 }, 98 },
94 }) 99 })
100 mongoMutex.Unlock()
101 case "execve":
102 // 父进程在不在?不在扔
103 res, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid})
104 if err != nil || len(res) != 1 {
105 break
106 }
107
108 // 首先检查进程是否存在,如不存在则为之创建
109 res, err = pidCol.Finddoc(bson.M{"pid": cooked.pid})
95 if err != nil { 110 if err != nil {
96 fmt.Printf("Err insert: %v\n", err) 111 break
112 }
113 mongoMutex.Lock()
114 if len(res) == 1 {
115 // 自身已在,直接记录
116 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{
117 "$push": bson.M{
118 "execve": bson.M{
119 "timestamp": cooked.timestamp,
120 "args": cooked.argv,
121 },
122 },
123 })
124 } else {
125 // 先fork抵达,插入
126 pidCol.InsertOne(bson.M{
127 "children": []bson.M{},
128 "execve": []bson.M{
129 {
130 "timestamp": cooked.timestamp,
131 "execve": cooked.argv,
132 },
133 },
134 })
97 } 135 }
136 mongoMutex.Unlock()
98 case "exit", "exit_group": 137 case "exit", "exit_group":
99 // TODO: 记得补全退出逻辑 138 go deletePid(cooked)
100 // 上哪找exit code呢?
101 } 139 }
102 } 140 }
103} 141}
104 142
105func connect() (*mongo.Client, error) { 143func deletePid(cooked Event) {
106 client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017")) 144 time.Sleep(1 * time.Second)
107 145 mongoMutex.Lock()
108 if err != nil { 146 // 先从老爹那里销户
109 return nil, err 147 pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{
110 } 148 "$pull": bson.M{
111 149 "children": cooked.pid,
112 ctx, _ := context.WithTimeout(context.Background(), 10*time.Second) 150 },
113 err = client.Connect(ctx) 151 })
114
115 if err != nil {
116 return nil, err
117 }
118
119 return client, nil
120}
121
122func findDocuments(client *mongo.Client, dbName, colName string, filter bson.M) ([]bson.M, error) {
123 collection := client.Database(dbName).Collection(colName)
124
125 cur, err := collection.Find(context.Background(), filter)
126 if err != nil {
127 return nil, err
128 }
129 152
130 var results []bson.M 153 // 孩子们需要收容
131 err = cur.All(context.Background(), &results) 154 // 不必到children里一个个找,直接看ppid即可
155 pidCol.UpdateMany(bson.M{"ppid": cooked.pid}, bson.M{"ppid": 1})
132 156
133 return results, err 157 // 可以去死了
158 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{
159 "$set": bson.M{
160 "exit_timestamp": cooked.timestamp,
161 "exit_code": cooked.exit_code,
162 },
163 })
164 mongoMutex.Unlock()
134} 165}
diff --git a/src/global.go b/src/global.go
index 0439df6..c3001ab 100644
--- a/src/global.go
+++ b/src/global.go
@@ -9,6 +9,7 @@ type Event struct {
9 timestamp time.Time 9 timestamp time.Time
10 pid, ppid int 10 pid, ppid int
11 syscall int 11 syscall int
12 exit_code uint64
12 argc int 13 argc int
13 argv []string 14 argv []string
14 cwd string 15 cwd string
@@ -23,7 +24,6 @@ type process struct {
23 children []int 24 children []int
24} 25}
25 26
26var pids sync.Map // 古希腊掌管进程的神,int->*process
27var wg sync.WaitGroup // 掌管协程 27var wg sync.WaitGroup // 掌管协程
28var rawChan chan interface{} // 从接收到整理的管道 28var rawChan chan interface{} // 从接收到整理的管道
29var cookedChan chan Event // 整理好的信息的管道 29var cookedChan chan Event // 整理好的信息的管道
diff --git a/src/godo.go b/src/godo.go
index 72f68c0..cc29a01 100644
--- a/src/godo.go
+++ b/src/godo.go
@@ -51,26 +51,8 @@ func main() {
51 } 51 }
52 52
53 // 创世之神,1号进程 53 // 创世之神,1号进程
54 // pids[1] = &process{rootfs: "/", children: make([]int, 0)}
55 // pids[1].children = append(pids[1].children, containerdPid)
56 // 1号进程还是不要在进程树上直接出现了,不然它的小儿子们都会出现 54 // 1号进程还是不要在进程树上直接出现了,不然它的小儿子们都会出现
57
58 // /usr/bin/containerd,也就是我们最关注的进程 55 // /usr/bin/containerd,也就是我们最关注的进程
59 // pids[containerdPid] = &process{rootfs: "/", children: make([]int, 0)}
60 pids.Store(containerdPid, &process{
61 ppid: 1,
62 pid: containerdPid,
63 argv: make([]string, 0),
64 cwd: "/",
65 rootfs: "/",
66 children: make([]int, 0),
67 })
68 p, ok := pids.Load(containerdPid)
69 if !ok {
70 fmt.Printf("???\n")
71 return
72 }
73 p.(*process).argv = append(p.(*process).argv, "/usr/bin/containerd")
74 56
75 // 开始运行,解析命令行参数后监听 57 // 开始运行,解析命令行参数后监听
76 if err := fs.Parse(os.Args[1:]); err != nil { 58 if err := fs.Parse(os.Args[1:]); err != nil {
diff --git a/src/mongo.go b/src/mongo.go
new file mode 100644
index 0000000..d00abd2
--- /dev/null
+++ b/src/mongo.go
@@ -0,0 +1,79 @@
1package main
2
3import (
4 "context"
5 "time"
6
7 "go.mongodb.org/mongo-driver/bson"
8 "go.mongodb.org/mongo-driver/mongo"
9 "go.mongodb.org/mongo-driver/mongo/options"
10)
11
12type mongoClient struct {
13 dbName, colName string
14 client *mongo.Client
15 col *mongo.Collection
16}
17
18func (mc *mongoClient) Connect(dbName, colName string) error {
19 var err error
20 mc.client, err = mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017"))
21
22 if err != nil {
23 return err
24 }
25
26 ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
27 err = mc.client.Connect(ctx)
28 if err != nil {
29 return err
30 }
31
32 mc.col = mc.client.Database(dbName).Collection(colName)
33 mc.dbName = dbName
34 mc.colName = colName
35 return nil
36}
37
38func (mc *mongoClient) InsertOne(document interface{}) error {
39 _, err := mc.col.InsertOne(context.Background(), document)
40 return err
41}
42
43func (mc *mongoClient) UpdateOne(filter, update interface{}) error {
44 _, err := mc.col.UpdateOne(context.Background(), filter, update)
45 return err
46}
47
48func (mc *mongoClient) UpdateMany(filter, update interface{}) error {
49 _, err := mc.col.UpdateMany(context.Background(), filter, update)
50 return err
51}
52
53func (mc *mongoClient) Finddoc(filter bson.M) ([]bson.M, error) {
54 cur, err := mc.col.Find(context.Background(), filter)
55 if err != nil {
56 return nil, err
57 }
58
59 var results []bson.M
60 err = cur.All(context.Background(), &results)
61
62 return results, err
63}
64
65func (mc *mongoClient) Drop() error {
66 return mc.col.Drop(context.Background())
67}
68
69func (mc *mongoClient) Disconnect() error {
70 err := mc.client.Disconnect(context.Background())
71 if err != nil {
72 return err
73 }
74 mc.col = nil
75 mc.client = nil
76 mc.dbName = ""
77 mc.colName = ""
78 return nil
79}
diff --git a/src/organize.go b/src/organize.go
index bb6736a..d963288 100644
--- a/src/organize.go
+++ b/src/organize.go
@@ -1,9 +1,11 @@
1package main 1package main
2 2
3import ( 3import (
4 "fmt"
4 "regexp" 5 "regexp"
5 "strconv" 6 "strconv"
6 "strings" 7 "strings"
8 "sync"
7 9
8 "github.com/elastic/go-libaudit/v2" 10 "github.com/elastic/go-libaudit/v2"
9 "github.com/elastic/go-libaudit/v2/auparse" 11 "github.com/elastic/go-libaudit/v2/auparse"
@@ -19,16 +21,20 @@ func orgnaze() {
19 // 事件信息 21 // 事件信息
20 var eventId, argc int 22 var eventId, argc int
21 var err [6]error 23 var err [6]error
22 var event, cooked Event 24 var event Event
25 var pEvent *Event
26 var tmp any
23 // 为每个事务id存储其信息,事务id在操作系统运行期间是唯一的 27 // 为每个事务id存储其信息,事务id在操作系统运行期间是唯一的
24 eventTable := make(map[int]*Event) 28 var eventTable sync.Map
29
25 // 要用的正则匹配列表 30 // 要用的正则匹配列表
26 syscallRegex := regexp.MustCompile(`audit\((\d+\.\d+):(\d+)\).*?syscall=(\d+).*?(exit=([-+]?\d+).*?)?ppid=(\d+) pid=(\d+).*?$`) 31 syscallRegex := regexp.MustCompile(`audit\((\d+\.\d+):(\d+)\).*?syscall=(\d+).*?(exit=([-+]?\d+))? a0=([0-9a-fA-F]+).*?ppid=(\d+) pid=(\d+).*?$`)
27 execveRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): argc=(\d+)`) 32 execveRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): argc=(\d+)`)
28 argsRegex := regexp.MustCompile(`a\d+=("(.*?)"|([0-9a-fA-F]+))`) 33 argsRegex := regexp.MustCompile(`a\d+=("(.*?)"|([0-9a-fA-F]+))`)
29 cwdRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): cwd="(.*?)"`) 34 cwdRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): cwd="(.*?)"`)
30 proctitleRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): proctitle=("(.*?)"|([0-9a-fA-F]+))$`) 35 proctitleRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): proctitle=("(.*?)"|([0-9a-fA-F]+))$`)
31 eoeRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\)`) 36 eoeRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\)`)
37
32 for { 38 for {
33 raw, ok = <-rawChan 39 raw, ok = <-rawChan
34 if !ok { 40 if !ok {
@@ -44,39 +50,53 @@ func orgnaze() {
44 eventId, err[1] = strconv.Atoi(string(match[2])) 50 eventId, err[1] = strconv.Atoi(string(match[2]))
45 event.syscall, err[2] = strconv.Atoi(string(match[3])) 51 event.syscall, err[2] = strconv.Atoi(string(match[3]))
46 var exit int 52 var exit int
47 // exit, err[3] = strconv.Atoi(string(match[4])) 53 var a0 uint64
48 if string(match[5]) == "" { 54 if string(match[5]) == "" {
49 // exit没捕获到 55 // exit没捕获到
50 exit = 0 56 exit = 0
51 } else { 57 } else {
52 exit, err[3] = strconv.Atoi(string(match[5])) 58 exit, err[3] = strconv.Atoi(string(match[5]))
53 } 59 }
54 event.ppid, err[4] = strconv.Atoi(string(match[5])) 60 if string(match[6]) == "" {
55 event.pid, err[5] = strconv.Atoi(string(match[6])) 61 a0 = 0
62 } else {
63 // 系统调用的第一个参数
64 // exit和exit_group都是syscall_define1,只有一个参数
65 // fork没参数,clone几个参数不重要
66 // execve三个参数咱也不关心
67 // 所以看第一个就够了
68 a0, err[4] = strconv.ParseUint(string(match[6]), 16, 64)
69 }
70 event.ppid, err[4] = strconv.Atoi(string(match[7]))
71 event.pid, err[5] = strconv.Atoi(string(match[8]))
56 if syscallTable[event.syscall] == "clone" { 72 if syscallTable[event.syscall] == "clone" {
57 if exit == 0 { 73 if exit == 0 || event.pid > exit {
74 // exit=0是给新进程的返回,没用
75 // pid>exit,证明有问题,抛弃
58 break 76 break
59 } else { 77 } else {
60 eventTable[eventId] = &Event{ 78 eventTable.Store(eventId, &Event{
61 timestamp: event.timestamp, 79 timestamp: event.timestamp,
62 syscall: event.syscall, 80 syscall: event.syscall,
81 exit_code: 0,
63 ppid: event.pid, 82 ppid: event.pid,
64 pid: exit, 83 pid: exit,
65 argc: 0, 84 argc: 0,
66 argv: make([]string, 0), 85 argv: make([]string, 0),
67 cwd: "", 86 cwd: "",
68 } 87 })
69 } 88 }
70 } else { 89 } else {
71 eventTable[eventId] = &Event{ 90 eventTable.Store(eventId, &Event{
72 timestamp: event.timestamp, 91 timestamp: event.timestamp,
73 syscall: event.syscall, 92 syscall: event.syscall,
93 exit_code: a0,
74 ppid: event.ppid, 94 ppid: event.ppid,
75 pid: event.pid, 95 pid: event.pid,
76 argc: 0, 96 argc: 0,
77 argv: make([]string, 0), 97 argv: make([]string, 0),
78 cwd: "", 98 cwd: "",
79 } 99 })
80 } 100 }
81 } 101 }
82 case auparse.AUDIT_EXECVE: 102 case auparse.AUDIT_EXECVE:
@@ -84,34 +104,45 @@ func orgnaze() {
84 match := execveRegex.FindSubmatch(rawEvent.Data) 104 match := execveRegex.FindSubmatch(rawEvent.Data)
85 eventId, err[0] = strconv.Atoi(string(match[1])) 105 eventId, err[0] = strconv.Atoi(string(match[1]))
86 argc, err[1] = strconv.Atoi(string(match[2])) 106 argc, err[1] = strconv.Atoi(string(match[2]))
107 tmp, ok = eventTable.Load(eventId)
108 if !ok {
109 break
110 }
111 pEvent = tmp.(*Event)
87 if err[0] == nil && err[1] == nil && argsRegex.Match(rawEvent.Data) { 112 if err[0] == nil && err[1] == nil && argsRegex.Match(rawEvent.Data) {
88 match := argsRegex.FindAllSubmatch(rawEvent.Data, -1) 113 match := argsRegex.FindAllSubmatch(rawEvent.Data, -1)
89 for i := 0; i < argc; i++ { 114 for i := 0; i < argc; i++ {
90 if len(match[i][2]) == 0 { 115 if len(match[i][2]) == 0 {
91 // 代表着匹配到的是十六进制数 116 // 代表着匹配到的是十六进制数
92 str := hexToAscii(string(match[i][3])) 117 str := hexToAscii(string(match[i][3]))
93 eventTable[eventId].argv = append(eventTable[eventId].argv, str) 118 pEvent.argv = append(pEvent.argv, str)
94 } else { 119 } else {
95 eventTable[eventId].argv = append(eventTable[eventId].argv, string(match[i][2])) 120 pEvent.argv = append(pEvent.argv, string(match[i][2]))
96 } 121 }
97 } 122 }
98 eventTable[eventId].argc = argc 123 pEvent.argc = argc
99 } 124 }
100 } 125 }
101 // case auparse.AUDIT_PATH:
102 case auparse.AUDIT_CWD: 126 case auparse.AUDIT_CWD:
103 if cwdRegex.Match(rawEvent.Data) { 127 if cwdRegex.Match(rawEvent.Data) {
104 match := cwdRegex.FindSubmatch(rawEvent.Data) 128 match := cwdRegex.FindSubmatch(rawEvent.Data)
105 eventId, err[0] = strconv.Atoi(string(match[1])) 129 eventId, err[0] = strconv.Atoi(string(match[1]))
106 eventTable[eventId].cwd = string(match[2]) 130 tmp, ok = eventTable.Load(eventId)
131 if !ok {
132 break
133 }
134 tmp.(*Event).cwd = string(match[2])
107 } 135 }
108 case auparse.AUDIT_PROCTITLE: 136 case auparse.AUDIT_PROCTITLE:
109 if proctitleRegex.Match(rawEvent.Data) { 137 if proctitleRegex.Match(rawEvent.Data) {
110 var cmdline string 138 var cmdline string
111 var pEvent *Event
112 match := proctitleRegex.FindSubmatch(rawEvent.Data) 139 match := proctitleRegex.FindSubmatch(rawEvent.Data)
113 eventId, err[0] = strconv.Atoi(string(match[1])) 140 eventId, err[0] = strconv.Atoi(string(match[1]))
114 pEvent = eventTable[eventId] 141 tmp, ok = eventTable.Load(eventId)
142 if !ok {
143 break
144 }
145 pEvent = tmp.(*Event)
115 if pEvent.argc == 0 { 146 if pEvent.argc == 0 {
116 // 只有等于0,才证明没经过EXECVE提取参数,才允许使用PROCTITLE提取参数 147 // 只有等于0,才证明没经过EXECVE提取参数,才允许使用PROCTITLE提取参数
117 if match[3] == nil { 148 if match[3] == nil {
@@ -121,17 +152,21 @@ func orgnaze() {
121 cmdline = string(match[3]) 152 cmdline = string(match[3])
122 } 153 }
123 pEvent.argv = strings.Split(cmdline, " ") 154 pEvent.argv = strings.Split(cmdline, " ")
124 pEvent.argc = len(eventTable[eventId].argv) 155 pEvent.argc = len(pEvent.argv)
125 } 156 }
126 } 157 }
127 case auparse.AUDIT_EOE: 158 case auparse.AUDIT_EOE:
128 if eoeRegex.Match(rawEvent.Data) { 159 if eoeRegex.Match(rawEvent.Data) {
129 match := eoeRegex.FindSubmatch(rawEvent.Data) 160 match := eoeRegex.FindSubmatch(rawEvent.Data)
130 eventId, err[0] = strconv.Atoi(string(match[1])) 161 eventId, err[0] = strconv.Atoi(string(match[1]))
131 // ATTENTION: 事件整理完毕,即刻发出,是否合理呢? 162 tmp, ok = eventTable.Load(eventId)
132 cooked = *eventTable[eventId] // 应当采用深拷贝吗?有待实验 163 if !ok {
164 break
165 }
166 cooked := *(tmp.(*Event))
133 cookedChan <- cooked 167 cookedChan <- cooked
134 delete(eventTable, eventId) //发出之后就从信息表扔掉,死人别占地 168 eventTable.Delete(eventId) // 死人别占地
169 fmt.Printf("%d: %3d %6d %6d\n", eventId, cooked.syscall, cooked.ppid, cooked.pid)
135 } 170 }
136 default: 171 default:
137 // ATTENTION: 这里也需要做防护 172 // ATTENTION: 这里也需要做防护