def _main(sdb_path, patch_name): from sdb import SDB with open(sdb_path, "rb") as f: buf = f.read() g_logger.debug("loading database") s = SDB() s.vsParse(bytearray(buf)) g_logger.debug("done loading database") index = SdbIndex() g_logger.debug("indexing strings") index.index_sdb(s) g_logger.debug("done indexing strings") library = item_get_child(s.database_root, SDB_TAGS.TAG_LIBRARY) for shim_ref in item_get_children(library, SDB_TAGS.TAG_SHIM_REF): patch = item_get_child(shim_ref, SDB_TAGS.TAG_PATCH) name_ref = item_get_child(patch, SDB_TAGS.TAG_NAME) name = index.get_string(name_ref.value.reference) bits = item_get_child(patch, SDB_TAGS.TAG_PATCH_BITS) if name == patch_name: ps = GreedyVArray(sdb.PATCHBITS) ps.vsParse(bits.value.value) for i, _ in ps: p = ps[int(i)] print(p.tree()) print(" disassembly:") for l in disassemble(str(p.pattern), p.rva): print(" " + l) print("")
class SdbInfoDumper(object): def __init__(self, db): self._db = db self._index = SdbIndex() g_logger.debug("indexing strings") self._index.index_sdb(self._db) g_logger.debug("done indexing strings") def dump_info(self): name_ref = item_get_child(self._db.database_root, SDB_TAGS.TAG_NAME).value.reference name = self._index.get_string(name_ref) yield "name: %s" % name database_id = item_get_child(self._db.database_root, SDB_TAGS.TAG_DATABASE_ID).value.value database_id = formatGuid(database_id) yield "database id: %s" % database_id ts = item_get_child(self._db.database_root, SDB_TAGS.TAG_TIME).value.value ts = parse_windows_timestamp(ts) yield "timestamp: %s" % ts compiler_version_ref = item_get_child(self._db.database_root, SDB_TAGS.TAG_COMPILER_VERSION).value.reference compiler_version = self._index.get_string(compiler_version_ref) yield "compiler version: %s" % compiler_version os_platform = hex(item_get_child(self._db.database_root, SDB_TAGS.TAG_OS_PLATFORM).value.value) yield "os platform: %s" % os_platform
class SdbDatabaseDumper(object): def __init__(self, sdb): self._sdb = sdb self._strindex = SdbIndex() self._strindex.index_sdb(sdb) def _formatValue(self, item): m = (item.header.valuetype & 0xF0) << 8 if m == SDB_TAG_TYPES.TAG_TYPE_STRINGREF: ref = item.value.reference return self._strindex.get_string(ref) else: return formatValue(item) 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 dump(self): if self._strindex is None: self._build_string_index() for i in self._dump_item(self._sdb.database_root): yield i
class SdbDatabaseDumper(object): def __init__(self, sdb): self._sdb = sdb self._strindex = SdbIndex() self._strindex.index_sdb(sdb) def _formatValue(self, item): m = (item.header.valuetype & 0xF0) << 8 if m == SDB_TAG_TYPES.TAG_TYPE_STRINGREF: ref = item.value.reference return self._strindex.get_string(ref) else: return formatValue(item) 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 dump(self): if self._strindex is None: self._build_string_index() for i in self._dump_item(self._sdb.database_root): yield i
class SdbInfoDumper(object): def __init__(self, db): self._db = db self._index = SdbIndex() g_logger.debug("indexing strings") self._index.index_sdb(self._db) g_logger.debug("done indexing strings") def dump_info(self): name_ref = item_get_child(self._db.database_root, SDB_TAGS.TAG_NAME).value.reference name = self._index.get_string(name_ref) yield "name: %s" % name try: database_id = item_get_child(self._db.database_root, SDB_TAGS.TAG_DATABASE_ID).value.value database_id = formatGuid(database_id) yield "database id: %s" % database_id except KeyError: pass try: ts = item_get_child(self._db.database_root, SDB_TAGS.TAG_TIME).value.value ts = parse_windows_timestamp(ts) yield "timestamp: %s" % ts except KeyError: pass try: compiler_version_ref = item_get_child(self._db.database_root, SDB_TAGS.TAG_COMPILER_VERSION).value.reference compiler_version = self._index.get_string(compiler_version_ref) yield "compiler version: %s" % compiler_version except KeyError: pass try: os_platform = hex(item_get_child(self._db.database_root, SDB_TAGS.TAG_OS_PLATFORM).value.value) yield "os platform: %s" % os_platform except KeyError: pass
def _main(sdb_path, patch_name): from sdb import SDB with open(sdb_path, "rb") as f: buf = f.read() g_logger.debug("loading database") s = SDB() s.vsParse(bytearray(buf)) g_logger.debug("done loading database") index = SdbIndex() g_logger.debug("indexing strings") index.index_sdb(s) g_logger.debug("done indexing strings") try: library = item_get_child(s.database_root, SDB_TAGS.TAG_LIBRARY) except KeyError: pass else: for shim_ref in item_get_children(library, SDB_TAGS.TAG_SHIM_REF): patch = item_get_child(shim_ref, SDB_TAGS.TAG_PATCH) name_ref = item_get_child(patch, SDB_TAGS.TAG_NAME) name = index.get_string(name_ref.value.reference) if name != patch_name: continue bits = item_get_child(patch, SDB_TAGS.TAG_PATCH_BITS) dump_patch(bits, arch=ARCH_32) try: patch = item_get_child(s.database_root, SDB_TAGS.TAG_PATCH) except KeyError: pass else: name_ref = item_get_child(patch, SDB_TAGS.TAG_NAME) name = index.get_string(name_ref.value.reference) if name == patch_name: bits = item_get_child(patch, SDB_TAGS.TAG_PATCH_BITS) dump_patch(bits, arch=ARCH_32)
def __init__(self, sdb): self._sdb = sdb self._strindex = SdbIndex() self._strindex.index_sdb(sdb)
def __init__(self, db): self._db = db self._index = SdbIndex() g_logger.debug("indexing strings") self._index.index_sdb(self._db) g_logger.debug("done indexing strings")
def __init__(self, db): self._db = db self._index = SdbIndex() self._index.index_sdb(self._db)
class SdbShimDumper(object): def __init__(self, db): self._db = db self._index = SdbIndex() self._index.index_sdb(self._db) def _formatValue(self, item): m = (item.header.valuetype & 0xF0) << 8 if m == SDB_TAG_TYPES.TAG_TYPE_STRINGREF: ref = item.value.reference try: return self._index.get_string(ref) except IndexError: return "UNRESOLVED_STRINGREF:" + hex(ref) else: return formatValue(item) 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_database(self): yield '<?xml version="1.0" encoding="UTF-8"?>' for i in self.dump_item(self._db.database_root): yield i
class SdbShimDumper(object): def __init__(self, db): self._db = db self._index = SdbIndex() self._index.index_sdb(self._db) def _formatValue(self, item): m = (item.header.valuetype & 0xF0) << 8 if m == SDB_TAG_TYPES.TAG_TYPE_STRINGREF: ref = item.value.reference try: return self._index.get_string(ref) except IndexError: return "UNRESOLVED_STRINGREF:" + hex(ref) else: return formatValue(item) 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_database(self): yield '<?xml version="1.0" encoding="UTF-8"?>' for i in self.dump_item(self._db.database_root): yield i