-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathnormalize.go
121 lines (99 loc) · 2.5 KB
/
normalize.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
120
121
/*
Copyright 2018 Velocidex Innovations
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package evtx
import (
"github.com/Velocidex/ordereddict"
)
// EVTX is in XML but this is hard for us to query. So we try to
// normalize some common XML patterns into something which is easier
// to work with.
/* Sometimes the XML looks like:
<EventData>
<Data name="Thing1"> %Subst% </Data>
<Data name="Thing2"> %Subst% </Data>
<Data name="Thing3"> %Subst% </Data>
</Eventdata>
Which converts to json like this:
"Eventdata": {
"Data": [
{
"Name": "thing1",
"": %Subst%
},
{
"Name": "thing2",
"": %Subst%
},
{
"Name": "thing3",
"": %Subst%
},
]
}
But this is really hard to work with. To simplify processing we need
to convert it to:
"EventData": {
"Thing1": %Subst,
"Thing2": %Subst,
"Thing3": %Subst,
}
However we need to keep the order so we can properly interpolate it
into the message template. We use a very simple OrdereDict for
this. We rely on the MarshalJSON of the ordereddict to ensure the keys
in the JSON are ordered in Event order (otherwise interpolation into
the message will fail).
*/
func NormalizeEventData(expanded interface{}) {
data, ok := expanded.(*ordereddict.Dict)
if !ok {
return
}
event_data, pres := data.Get("EventData")
if !pres {
return
}
event_data_map, ok := event_data.(*ordereddict.Dict)
if !ok {
return
}
data_tag, pres := event_data_map.Get("Data")
if !pres {
return
}
data_array, ok := data_tag.([]interface{})
if !ok {
return
}
result := ordereddict.NewDict()
for _, item := range data_array {
item_map, ok := item.(*ordereddict.Dict)
if !ok {
return
}
// Look for name and "" pairs.
name_any, pres := item_map.Get("Name")
if !pres {
return
}
name, ok := name_any.(string)
if !ok {
return
}
value, pres := item_map.Get("Value")
if !pres {
return
}
result.Set(name, value)
}
data.Set("EventData", result)
}