forked from 0xrawsec/whids
-
Notifications
You must be signed in to change notification settings - Fork 0
/
hooks.go
119 lines (97 loc) · 2.53 KB
/
hooks.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package agent
import (
"sync"
"github.com/0xrawsec/whids/event"
)
// Hook structure definition
// hooking functions are supposed to run quickly since it is
// run synchronously with the Gene scanner. Likewise, the
// hooking functions should never panic the program.
type Hook func(*Agent, *event.EdrEvent)
type eventMap map[int64][]Hook
type hookCache struct {
c map[string]eventMap
}
func newHookCache() *hookCache {
return &hookCache{
c: make(map[string]eventMap),
}
}
func (h hookCache) get(e *event.EdrEvent) (hooks []Hook, ok bool) {
var eventIdsMap eventMap
if eventIdsMap, ok = h.c[e.Channel()]; !ok {
return
}
hooks, ok = eventIdsMap[e.EventID()]
return
}
func (h hookCache) cache(hk Hook, e *event.EdrEvent) {
// create eventMap if necessary
if _, ok := h.c[e.Channel()]; !ok {
h.c[e.Channel()] = make(eventMap)
}
// create Hook slice if necessary
em := h.c[e.Channel()]
if _, ok := em[e.EventID()]; !ok {
em[e.EventID()] = make([]Hook, 0, 1)
}
// append the hook to the list of hooks
if hk != nil {
em[e.EventID()] = append(em[e.EventID()], hk)
}
}
// HookManager structure definition to easier handle hooks
type HookManager struct {
sync.RWMutex
Filters []*Filter
Hooks []Hook
cache *hookCache
}
// NewHookMan creates a new HookManager structure
func NewHookMan() *HookManager {
return &HookManager{Filters: make([]*Filter, 0),
Hooks: make([]Hook, 0),
cache: newHookCache(),
}
}
// Hook register a hook for a given filter
func (hm *HookManager) Hook(h Hook, f *Filter) {
hm.Lock()
defer hm.Unlock()
hm.Hooks = append(hm.Hooks, h)
hm.Filters = append(hm.Filters, f)
}
// RunHooksOn runs the hook on a given event
func (hm *HookManager) RunHooksOn(h *Agent, e *event.EdrEvent) (ret bool) {
var ok bool
var hooks []Hook
hm.Lock()
defer hm.Unlock()
// Don't waste resources if nothing to do
if len(hm.Filters) == 0 {
return
}
// We have to check all the filters if we don't know yet
// which hooks should apply on this kind of event
if hooks, ok = hm.cache.get(e); !ok {
// we create an empty slice for e in order to return
// cache hooks for events with no filters
hm.cache.cache(nil, e)
// we go through all the filters
for i, f := range hm.Filters {
if f.Match(e) {
hm.cache.cache(hm.Hooks[i], e)
}
}
// we update the list of hooks to apply
hooks, _ = hm.cache.get(e)
}
for _, hook := range hooks {
// debug hooks
//log.Infof("Running hook: %s", getFunctionName(hook))
hook(h, e)
// We set return value to true if a hook has been applied
ret = true
}
return
}