1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 from Nodes import RootNode
21 from Nodes import TemplateNode
22 from Nodes import EndOfStreamNode
23 from Nodes import OpenStartElementNode
24 from Nodes import CloseStartElementNode
25 from Nodes import CloseEmptyElementNode
26 from Nodes import CloseElementNode
27 from Nodes import ValueNode
28 from Nodes import AttributeNode
29 from Nodes import CDataSectionNode
30 from Nodes import EntityReferenceNode
31 from Nodes import ProcessingInstructionTargetNode
32 from Nodes import ProcessingInstructionDataNode
33 from Nodes import TemplateInstanceNode
34 from Nodes import NormalSubstitutionNode
35 from Nodes import ConditionalSubstitutionNode
36 from Nodes import StreamStartNode
37
38
42
43
45 """
46 Given a RootNode, parse only the template/children
47 and not the substitutions.
48
49 Note, the cache should be local to the Evtx.Chunk.
50 Do not share caches across Chunks.
51
52 @type root_node: Nodes.RootNode
53 @type cache: dict of {int: TemplateNode}
54 @rtype: str
55 """
56 if cache is None:
57 cache = {}
58
59 def escape_format_chars(s):
60 return s.replace("{", "{{").replace("}", "}}")
61
62 def rec(node, acc):
63 if isinstance(node, EndOfStreamNode):
64 pass
65 elif isinstance(node, OpenStartElementNode):
66 acc.append("<")
67 acc.append(node.tag_name())
68 for child in node.children():
69 if isinstance(child, AttributeNode):
70 acc.append(" ")
71 acc.append(child.attribute_name().string())
72 acc.append("=\"")
73 rec(child.attribute_value(), acc)
74 acc.append("\"")
75 acc.append(">")
76 for child in node.children():
77 rec(child, acc)
78 acc.append("</")
79 acc.append(node.tag_name())
80 acc.append(">\n")
81 elif isinstance(node, CloseStartElementNode):
82 pass
83 elif isinstance(node, CloseEmptyElementNode):
84 pass
85 elif isinstance(node, CloseElementNode):
86 pass
87 elif isinstance(node, ValueNode):
88 acc.append(escape_format_chars(node.children()[0].string()))
89 elif isinstance(node, AttributeNode):
90 pass
91 elif isinstance(node, CDataSectionNode):
92 acc.append("<![CDATA[")
93 acc.append(node.cdata())
94 acc.append("]]>")
95 elif isinstance(node, EntityReferenceNode):
96 acc.append(node.entity_reference())
97 elif isinstance(node, ProcessingInstructionTargetNode):
98 acc.append(node.processing_instruction_target())
99 elif isinstance(node, ProcessingInstructionDataNode):
100 acc.append(node.string())
101 elif isinstance(node, TemplateInstanceNode):
102 raise UnexpectedElementException("TemplateInstanceNode")
103 elif isinstance(node, NormalSubstitutionNode):
104 acc.append("{")
105 acc.append("%d" % (node.index()))
106 acc.append("}")
107 elif isinstance(node, ConditionalSubstitutionNode):
108 acc.append("{")
109 acc.append("%d" % (node.index()))
110 acc.append("}")
111 elif isinstance(node, StreamStartNode):
112 pass
113
114 acc = []
115 template_instance = root_node.fast_template_instance()
116 templ_off = template_instance.template_offset() + \
117 template_instance._chunk.offset()
118 if templ_off in cache:
119 acc.append(cache[templ_off])
120 else:
121 node = TemplateNode(template_instance._buf, templ_off,
122 template_instance._chunk, template_instance)
123 sub_acc = []
124 for c in node.children():
125 rec(c, sub_acc)
126 sub_templ = "".join(sub_acc)
127 cache[templ_off] = sub_templ
128 acc.append(sub_templ)
129 return "".join(acc)
130
131
133 """
134 Note, the cache should be local to the Evtx.Chunk.
135 Do not share caches across Chunks.
136
137 @type record: Evtx.Record
138 @type cache: dict of {int: TemplateNode}
139 @rtype: str
140 """
141 if cache is None:
142 cache = {}
143
144 def rec(root_node):
145 f = _make_template_xml_view(root_node, cache=cache)
146 subs_strs = []
147 for sub in root_node.fast_substitutions():
148 if isinstance(sub, basestring):
149 subs_strs.append(sub.encode("ascii", "xmlcharrefreplace"))
150 elif isinstance(sub, RootNode):
151 subs_strs.append(rec(sub))
152 elif sub is None:
153 subs_strs.append("")
154 else:
155 subs_strs.append(str(sub))
156 return f.format(*subs_strs)
157 xml = rec(record.root())
158 xml = xml.replace("&", "&")
159 return xml
160
161
163 """
164 Generate an UTF-8 XML representation of an EVTX record.
165
166 Note, the cache should be local to the Evtx.Chunk.
167 Do not share caches across Chunks.
168
169 @type record: Evtx.Record
170 @type cache: dict of {int: TemplateNode}
171 @rtype: str
172 """
173 if cache is None:
174 cache = {}
175 return _build_record_xml(record, cache=cache).encode("utf8", "xmlcharrefreplace")
176
177
179 """
180 Generate UTF-8 XML representations of the records in an EVTX chunk.
181
182 Does not include the XML <?xml... header.
183 Records are ordered by chunk.records()
184
185 @type chunk: Evtx.Chunk
186 @rtype: generator of str, Evtx.Record
187 """
188 cache = {}
189 for record in chunk.records():
190 record_str = _build_record_xml(record, cache=cache)
191 yield record_str.encode("utf8", "xmlcharrefreplace"), record
192
193
195 """
196 Generate UTF-8 XML representations of the records in an EVTX file.
197
198 Does not include the XML <?xml... header.
199 Records are ordered by file_header.chunks(), and then by chunk.records()
200
201 @type file_header: Evtx.FileHeader
202 @rtype: generator of str, Evtx.Record
203 """
204 for chunk in file_header.chunks():
205 cache = {}
206 for record in chunk.records():
207 record_str = _build_record_xml(record, cache=cache)
208 yield record_str.encode("utf8", "xmlcharrefreplace"), record
209
210
212 """
213 """
214 def rec(node, acc):
215 if isinstance(node, EndOfStreamNode):
216 pass
217 elif isinstance(node, OpenStartElementNode):
218 acc.append("<")
219 acc.append(node.tag_name())
220 for child in node.children():
221 if isinstance(child, AttributeNode):
222 acc.append(" ")
223 acc.append(child.attribute_name().string())
224 acc.append("=\"")
225 rec(child.attribute_value(), acc)
226 acc.append("\"")
227 acc.append(">")
228 for child in node.children():
229 rec(child, acc)
230 acc.append("</")
231 acc.append(node.tag_name())
232 acc.append(">\n")
233 elif isinstance(node, CloseStartElementNode):
234 pass
235 elif isinstance(node, CloseEmptyElementNode):
236 pass
237 elif isinstance(node, CloseElementNode):
238 pass
239 elif isinstance(node, ValueNode):
240 acc.append(node.children()[0].string())
241 elif isinstance(node, AttributeNode):
242 pass
243 elif isinstance(node, CDataSectionNode):
244 acc.append("<![CDATA[")
245 acc.append(node.cdata())
246 acc.append("]]>")
247 elif isinstance(node, EntityReferenceNode):
248 acc.append(node.entity_reference())
249 elif isinstance(node, ProcessingInstructionTargetNode):
250 acc.append(node.processing_instruction_target())
251 elif isinstance(node, ProcessingInstructionDataNode):
252 acc.append(node.string())
253 elif isinstance(node, TemplateInstanceNode):
254 raise UnexpectedElementException("TemplateInstanceNode")
255 elif isinstance(node, NormalSubstitutionNode):
256 acc.append("[Normal Substitution(index=%d, type=%d)]" % \
257 (node.index(), node.type()))
258 elif isinstance(node, ConditionalSubstitutionNode):
259 acc.append("[Condititional Substitution(index=%d, type=%d)]" % \
260 (node.index(), node.type()))
261 elif isinstance(node, StreamStartNode):
262 pass
263
264 sub_acc = []
265 for c in template_node.children():
266 rec(c, sub_acc)
267 return "".join(sub_acc)
268