def add_template(self, offset, parent=None): """ @param offset An integer which contains the chunk-relative offset to a template to load into this Chunk. @param parent (Optional) The parent of the newly created TemplateNode instance. (Default: this chunk). @return Newly added TemplateNode instance. """ if self._templates is None: self._load_templates() node = TemplateNode(self._buf, self._offset + offset, self, parent or self) self._templates[offset] = node return node
def _make_template_xml_view(root_node, cache=None): """ Given a RootNode, parse only the template/children and not the substitutions. Note, the cache should be local to the Evtx.Chunk. Do not share caches across Chunks. @type root_node: Nodes.RootNode @type cache: dict of {int: TemplateNode} @rtype: str """ if cache is None: cache = {} def escape_format_chars(s): return s.replace("{", "{{").replace("}", "}}") def rec(node, acc): if isinstance(node, EndOfStreamNode): pass # intended elif isinstance(node, OpenStartElementNode): acc.append("<") acc.append(node.tag_name()) for child in node.children(): if isinstance(child, AttributeNode): acc.append(" ") acc.append(child.attribute_name().string()) acc.append("=\"") rec(child.attribute_value(), acc) acc.append("\"") acc.append(">") for child in node.children(): rec(child, acc) acc.append("</") acc.append(node.tag_name()) acc.append(">\n") elif isinstance(node, CloseStartElementNode): pass # intended elif isinstance(node, CloseEmptyElementNode): pass # intended elif isinstance(node, CloseElementNode): pass # intended elif isinstance(node, ValueNode): acc.append(escape_format_chars(node.children()[0].string())) elif isinstance(node, AttributeNode): pass # intended elif isinstance(node, CDataSectionNode): acc.append("<![CDATA[") acc.append(node.cdata()) acc.append("]]>") elif isinstance(node, EntityReferenceNode): acc.append(node.entity_reference()) elif isinstance(node, ProcessingInstructionTargetNode): acc.append(node.processing_instruction_target()) elif isinstance(node, ProcessingInstructionDataNode): acc.append(node.string()) elif isinstance(node, TemplateInstanceNode): raise UnexpectedElementException("TemplateInstanceNode") elif isinstance(node, NormalSubstitutionNode): acc.append("{") acc.append("%d" % (node.index())) acc.append("}") elif isinstance(node, ConditionalSubstitutionNode): acc.append("{") acc.append("%d" % (node.index())) acc.append("}") elif isinstance(node, StreamStartNode): pass # intended acc = [] template_instance = root_node.fast_template_instance() templ_off = template_instance.template_offset() + \ template_instance._chunk.offset() if templ_off in cache: acc.append(cache[templ_off]) else: node = TemplateNode(template_instance._buf, templ_off, template_instance._chunk, template_instance) sub_acc = [] for c in node.children(): rec(c, sub_acc) sub_templ = "".join(sub_acc) cache[templ_off] = sub_templ acc.append(sub_templ) return "".join(acc)
def evtx_template_readable_view(root_node, cache=None): """ """ if cache is None: cache = {} def rec(node, acc): if isinstance(node, EndOfStreamNode): pass # intended elif isinstance(node, OpenStartElementNode): acc.append("<") acc.append(node.tag_name()) for child in node.children(): if isinstance(child, AttributeNode): acc.append(" ") acc.append(child.attribute_name().string()) acc.append("=\"") rec(child.attribute_value(), acc) acc.append("\"") acc.append(">") for child in node.children(): rec(child, acc) acc.append("</") acc.append(node.tag_name()) acc.append(">\n") elif isinstance(node, CloseStartElementNode): pass # intended elif isinstance(node, CloseEmptyElementNode): pass # intended elif isinstance(node, CloseElementNode): pass # intended elif isinstance(node, ValueNode): acc.append(node.children()[0].string()) elif isinstance(node, AttributeNode): pass # intended elif isinstance(node, CDataSectionNode): acc.append("<![CDATA[") acc.append(node.cdata()) acc.append("]]>") elif isinstance(node, EntityReferenceNode): acc.append(node.entity_reference()) elif isinstance(node, ProcessingInstructionTargetNode): acc.append(node.processing_instruction_target()) elif isinstance(node, ProcessingInstructionDataNode): acc.append(node.string()) elif isinstance(node, TemplateInstanceNode): raise UnexpectedElementException("TemplateInstanceNode") elif isinstance(node, NormalSubstitutionNode): acc.append("[Normal Substitution(index=%d, type=%d)]" % \ (node.index(), node.type())) elif isinstance(node, ConditionalSubstitutionNode): acc.append("[Conditional Substitution(index=%d, type=%d)]" % \ (node.index(), node.type())) elif isinstance(node, StreamStartNode): pass # intended acc = [] template_instance = root_node.fast_template_instance() templ_off = template_instance.template_offset() + \ template_instance._chunk.offset() if templ_off in cache: acc.append(cache[templ_off]) else: node = TemplateNode(template_instance._buf, templ_off, template_instance._chunk, template_instance) sub_acc = [] for c in node.children(): rec(c, sub_acc) sub_templ = "".join(sub_acc) cache[templ_off] = sub_templ acc.append(sub_templ) return "".join(acc)