def _dump_item(self, item, indent=""): if isBadItem(item): return v = item.value if v.vsHasField("children"): yield u"{indent:s}<{tag:s}>".format( indent=indent, tag=getTagName(item.header)) for _, c in v.children: if isBadItem(c): continue for l in self._dump_item(c, indent + " "): yield l yield u"{indent:s}</{tag:s}>".format( indent=indent, tag=getTagName(item.header)) else: yield u"{indent:s}<{tag:s} type='{type_:s}'>{data:s}</{tag:s}>".format( indent=indent, type_=formatValueType(item), data=self._formatValue(item), tag=getTagName(item.header))
def item_get_child(item, child_tag): v = item.value if not v.vsHasField("children"): raise RuntimeError("item doesnt have children") for _, c in v.children: if isBadItem(c): continue if c.header.tag == child_tag: return c raise IndexError("failed to find child with tag %s", hex(child_tag))
def _build_string_index(self): self._strindex = {} children = self._sdb.strtab_root.value.children # len(strtab) - len(strtab value) == 6 # 01 78 ?? ?? ?? ?? (children_size:uint32) offset = 0x6 for fieldname, field in children.vsGetFields(): if isBadItem(field): continue self._strindex[offset] = field offset += len(field)
def _dump_item(self, item, indent=""): if isBadItem(item): return v = item.value if v.vsHasField("children"): yield u"{indent:s}<{tag:s}>".format(indent=indent, tag=getTagName(item.header)) for _, c in v.children: if isBadItem(c): continue for l in self._dump_item(c, indent + " "): yield l yield u"{indent:s}</{tag:s}>".format(indent=indent, tag=getTagName(item.header)) else: yield u"{indent:s}<{tag:s} type='{type_:s}'>{data:s}</{tag:s}>".format( indent=indent, type_=formatValueType(item), data=self._formatValue(item), tag=getTagName(item.header))
def _itemindex_item(self, offset, item): value = item.value # some items may have the same starting offset, so we take the first one # eg. given an item array, and the first item in the array, we want the array if offset not in self._itemindex: self._itemindex[offset] = item if value.vsHasField("children"): offset += value.vsGetOffset("children") children = value.children self._itemindex[offset] = children for child_id, child in children: if isBadItem(child): offset += len(child) continue # you might be tempted to use vsGetOffset(child_id)... don't. # internally it has to iterate all fields and do a __len__ on them, # so this ends up taking quadratic time. # instead, we track the offset ourselves. self._itemindex_item(offset, child) offset += len(child)
def index_sdb(self, db): o = len(db.header) indexes_root = db.indexes_root self._itemindex_item(o, indexes_root) o += len(indexes_root) database_root = db.database_root self._itemindex_item(o, database_root) o += len(database_root) strtab_root = db.strtab_root self._itemindex_item(o, strtab_root) o += len(strtab_root) # len(strtab) - len(strtab value) == 6 # 01 78 ?? ?? ?? ?? (children_size:uint32) offset = 0x6 for fieldname, field in db.strtab_root.value.children.vsGetFields(): if isBadItem(field): offset += len(field) continue self._strindex[offset] = field.value.value offset += len(field)
def dump_item(self, item, indent=""): if isBadItem(item): return v = item.value # TODO: need to also support the following reftypes # - PATCH_REF # - MSI_TRANSFORM_REF # - FLAG_REF if item.header.tag == SDB_TAGS.TAG_SHIM_REF: ref_item = item_get_child(item, SDB_TAGS.TAG_SHIM_TAGID) name_item = item_get_child(item, SDB_TAGS.TAG_NAME) name_ref = name_item.value if not isinstance(name_ref, sdb.SDBValueStringRef): raise RuntimeError("unexpected TAG_NAME value type") name = self._index.get_string(name_ref.reference) shim_ref = ref_item.value if not isinstance(shim_ref, sdb.SDBValueDword): raise RuntimeError("unexpected SHIM_TAGID value type") shim_item = self._index.get_item(shim_ref.value) # have to hardcode the parent tag name, since the ref may point # within the SHIM node yield u"{indent:s}<{tag:s}>".format( indent=indent, tag="SHIM") yield u"{indent:s}<!-- SHIM_REF name:'{name:s}' offset:{offset:s} -->".format( indent=indent + " ", name=name, offset=hex(shim_ref.value)) if shim_ref.value in self._item_txt_cache: for l in self._item_txt_cache[shim_ref.value]: yield l else: txt = [] for l in self.dump_item_array(shim_item, indent=indent + " "): yield l txt.append(l) self._item_txt_cache[shim_ref.value] = txt # have to hardcode the parent tag name, since the ref may point # within the SHIM node yield u"{indent:s}</{tag:s}>".format( indent=indent, tag="SHIM") elif v.vsHasField("children"): yield u"{indent:s}<{tag:s}>".format( indent=indent, tag=getTagName(item.header)) for l in self.dump_item_array(v.children, indent=indent+" "): yield l yield u"{indent:s}</{tag:s}>".format( indent=indent, tag=getTagName(item.header)) else: yield u"{indent:s}<{tag:s} type='{type_:s}'>{data:s}</{tag:s}>".format( indent=indent, type_=formatValueType(item), data=self._formatValue(item), tag=getTagName(item.header))
def dump_item_array(self, items, indent=""): for _, c in items: if isBadItem(c): continue for l in self.dump_item(c, indent): yield l
def dump_item(self, item, indent=""): if isBadItem(item): return v = item.value # TODO: need to also support the following reftypes # - PATCH_REF # - MSI_TRANSFORM_REF # - FLAG_REF if item.header.tag == SDB_TAGS.TAG_SHIM_REF: # have to hardcode the parent tag name, since the ref may point # within the SHIM node yield u"{indent:s}<{tag:s}>".format(indent=indent, tag="SHIM") ref_item = None name_item = None try: ref_item = item_get_child(item, SDB_TAGS.TAG_SHIM_TAGID) except IndexError: yield u"{indent:s}<!-- SHIM_REF missing SHIM_TAGID -->".format( indent=indent + " ") g_logger.debug("SHIM_REF mssing SHIM_TAGID") try: name_item = item_get_child(item, SDB_TAGS.TAG_NAME) except IndexError: yield u"{indent:s}<!-- SHIM_REF missing NAME -->".format( indent=indent + " ") g_logger.debug("SHIM_REF mssing NAME") if ref_item and name_item: name_ref = name_item.value if not isinstance(name_ref, sdb.SDBValueStringRef): raise RuntimeError("unexpected TAG_NAME value type") name = self._index.get_string(name_ref.reference) shim_ref = ref_item.value if not isinstance(shim_ref, sdb.SDBValueDword): raise RuntimeError("unexpected SHIM_TAGID value type") shim_item = self._index.get_item(shim_ref.value) yield u"{indent:s}<!-- SHIM_REF name:'{name:s}' offset:{offset:s} -->".format( indent=indent + " ", name=name, offset=hex(shim_ref.value)) for l in self.dump_item_array(shim_item, indent=indent + " "): yield l else: yield u"{indent:s}<!-- unresolved SHIM_REF -->".format( indent=indent + " ") g_logger.debug("unresolved SHIM_REF") if name_item: name_ref = name_item.value if not isinstance(name_ref, sdb.SDBValueStringRef): raise RuntimeError("unexpected TAG_NAME value type") name = self._index.get_string(name_ref.reference) yield u"{indent:s}<!-- SHIM_REF name:'{name:s}' -->".format( indent=indent + " ", name=name) if ref_item: shim_ref = ref_item.value if not isinstance(shim_ref, sdb.SDBValueDword): raise RuntimeError("unexpected SHIM_TAGID value type") shim_item = self._index.get_item(shim_ref.value) yield u"{indent:s}<!-- SHIM_REF offset:'{offset:s}' -->".format( indent=indent + " ", offset=hex(shim_ref.value)) # have to hardcode the parent tag name, since the ref may point # within the SHIM node yield u"{indent:s}</{tag:s}>".format(indent=indent, tag="SHIM") elif v.vsHasField("children"): yield u"{indent:s}<{tag:s}>".format(indent=indent, tag=getTagName(item.header)) for l in self.dump_item_array(v.children, indent=indent + " "): yield l yield u"{indent:s}</{tag:s}>".format(indent=indent, tag=getTagName(item.header)) else: yield u"{indent:s}<{tag:s} type='{type_:s}'>{data:s}</{tag:s}>".format( indent=indent, type_=formatValueType(item), data=self._formatValue(item), tag=getTagName(item.header))
def dump_item_array(self, items, indent=""): for _, c in items: if isBadItem(c): continue for l in self.dump_item(c, indent): yield l
def dump_item(self, item, indent=""): if isBadItem(item): return v = item.value # TODO: need to also support the following reftypes # - PATCH_REF # - MSI_TRANSFORM_REF # - FLAG_REF if item.header.tag == SDB_TAGS.TAG_SHIM_REF: # have to hardcode the parent tag name, since the ref may point # within the SHIM node yield u"{indent:s}<{tag:s}>".format( indent=indent, tag="SHIM") ref_item = None name_item = None try: ref_item = item_get_child(item, SDB_TAGS.TAG_SHIM_TAGID) except IndexError: yield u"{indent:s}<!-- SHIM_REF missing SHIM_TAGID -->".format( indent=indent + " ") g_logger.debug("SHIM_REF mssing SHIM_TAGID") try: name_item = item_get_child(item, SDB_TAGS.TAG_NAME) except IndexError: yield u"{indent:s}<!-- SHIM_REF missing NAME -->".format( indent=indent + " ") g_logger.debug("SHIM_REF mssing NAME") if ref_item and name_item: name_ref = name_item.value if not isinstance(name_ref, sdb.SDBValueStringRef): raise RuntimeError("unexpected TAG_NAME value type") name = self._index.get_string(name_ref.reference) shim_ref = ref_item.value if not isinstance(shim_ref, sdb.SDBValueDword): raise RuntimeError("unexpected SHIM_TAGID value type") shim_item = self._index.get_item(shim_ref.value) yield u"{indent:s}<!-- SHIM_REF name:'{name:s}' offset:{offset:s} -->".format( indent=indent + " ", name=name, offset=hex(shim_ref.value)) for l in self.dump_item_array(shim_item, indent=indent + " "): yield l else: yield u"{indent:s}<!-- unresolved SHIM_REF -->".format( indent=indent + " ") g_logger.debug("unresolved SHIM_REF") if name_item: name_ref = name_item.value if not isinstance(name_ref, sdb.SDBValueStringRef): raise RuntimeError("unexpected TAG_NAME value type") name = self._index.get_string(name_ref.reference) yield u"{indent:s}<!-- SHIM_REF name:'{name:s}' -->".format( indent=indent + " ", name=name) if ref_item: shim_ref = ref_item.value if not isinstance(shim_ref, sdb.SDBValueDword): raise RuntimeError("unexpected SHIM_TAGID value type") shim_item = self._index.get_item(shim_ref.value) yield u"{indent:s}<!-- SHIM_REF offset:'{offset:s}' -->".format( indent=indent + " ", offset=hex(shim_ref.value)) # have to hardcode the parent tag name, since the ref may point # within the SHIM node yield u"{indent:s}</{tag:s}>".format( indent=indent, tag="SHIM") elif v.vsHasField("children"): yield u"{indent:s}<{tag:s}>".format( indent=indent, tag=getTagName(item.header)) for l in self.dump_item_array(v.children, indent=indent+" "): yield l yield u"{indent:s}</{tag:s}>".format( indent=indent, tag=getTagName(item.header)) else: yield u"{indent:s}<{tag:s} type='{type_:s}'>{data:s}</{tag:s}>".format( indent=indent, type_=formatValueType(item), data=self._formatValue(item), tag=getTagName(item.header))