def main(argv=None): if argv is None: argv = sys.argv[1:] parser = argparse.ArgumentParser( description="Extract an object buffer from a WMI repository.") parser.add_argument("input", type=str, help="Path to input file") parser.add_argument("key", type=str, help="Key to object, like 889.1.43301") parser.add_argument("-v", "--verbose", action="store_true", help="Enable debug logging") parser.add_argument("-q", "--quiet", action="store_true", help="Disable all output but errors") args = parser.parse_args(args=argv) if args.verbose: logging.basicConfig(level=logging.DEBUG) logging.getLogger().setLevel(logging.DEBUG) elif args.quiet: logging.basicConfig(level=logging.ERROR) logging.getLogger().setLevel(logging.ERROR) else: logging.basicConfig(level=logging.INFO) logging.getLogger().setLevel(logging.INFO) repo = cim.CIM.from_path(args.input) key = cim.Key('__.' + args.key) os.write(sys.stdout.fileno(), repo.logical_data_store.get_object_buffer(key)) return 0
def test_index_references_are_valid(repo): """ demonstrate that all keys in the index reference valid TOC entries in data pages. this means: - all pages exist - all IDs exist - the reported size equals the allocated size Args: repo (cim.CIM): the deleted-instance repo Returns: None """ index = cim.Index(repo.cim_type, repo.logical_index_store) for key in index.lookup_keys(cim.Key('NS_')): if not key.is_data_reference: continue is_found = False entry_size = 0 page = repo.logical_data_store.get_page(key.data_page) for i in range(page.toc.count): entry = page.toc[i] if entry.record_id == key.data_id: is_found = True entry_size = entry.size break assert is_found is True assert key.data_length == entry_size
def test_object_resolver(repo): """ Args: repo (cim.CIM): the deleted-instance repo Returns: None """ resolver = cim.objects.ObjectResolver(repo) assert len(resolver.get_keys(cim.Key('NS_'))) == 47490 for key in resolver.get_keys(cim.Key('NS_')): if not key.is_data_reference: continue o = resolver.get_object(key) assert o is not None
def test_index_root(repo): """ make a prefix query against the index assert the number of expected results. Args: repo (cim.CIM): the deleted-instance repo Returns: None """ # collected empirically assert repo.logical_index_store.root_page_number == 60 index = cim.Index(repo.cim_type, repo.logical_index_store) # collected empirically # # this should be the number of all objects in the repository assert len(index.lookup_keys(cim.Key('NS_'))) == 47490
def test_find_unreferenced_objects(repo): """ find allocated TOC entries that are not referenced by the index. these are items that are inaccessible. Args: repo (cim.CIM): the deleted-instance repo Returns: None """ index = cim.Index(repo.cim_type, repo.logical_index_store) indexed_objects = set([]) for key in index.lookup_keys(cim.Key('NS_')): if not key.is_data_reference: continue indexed_objects.add((key.data_id, key.data_length)) unreferenced_objects = [] for i in range(repo.data_mapping.map.header.mapping_entry_count): if not repo.data_mapping.is_logical_page_mapped(i): continue page = repo.logical_data_store.get_page(i) for j in range(page.toc.count): entry = page.toc[j] if (entry.record_id, entry.size) not in indexed_objects: unreferenced_objects.append((i, entry.record_id, entry.size)) # collected empirically. # they all appear to be objects related to RSOP assert unreferenced_objects == [(0x674, 0x19ebb, 0x27c), (0x676, 0x1cc77, 0x274), (0x677, 0x1c273, 0x240), (0x677, 0x194dc, 0x240)]
def find_bytes(repo, needle): index = cim.Index(repo.cim_type, repo.logical_index_store) for i in range(repo.logical_data_store.page_count): buf = repo.logical_data_store.get_physical_page_buffer(i) if needle not in buf: continue offset = buf.index(needle) print('found hit on physical page %s at offset %s' % (hex(i), hex(offset))) try: lnum = repo.data_mapping.get_logical_page_number(i) except cim.UnmappedPage: print( ' this page not mapped to a logical page (unallocated page)') continue print(' mapped to logical page %s' % (hex(lnum))) try: page = repo.logical_data_store.get_page(lnum) except IndexError: print(' failed to fetch logical page') continue if len(page.toc) == 0: print(' page does not contain TOC, unknown contents') continue offset_found = False if 0 <= offset < len(page.toc): print(' hit in page TOC') offset_found = True for j in range(page.toc.count): entry = page.toc[j] if entry.offset <= offset < entry.offset + entry.size: print(' hit on object contents at entry index %s id %s' % (hex(j), hex(entry.record_id))) offset_found = True key_hits = set([]) for key in index.lookup_keys(cim.Key('NS_')): if not key.is_data_reference: continue if key.data_page != lnum: continue if key.data_id != entry.record_id: continue key = str(key) if key not in key_hits: print(' referred to by key %s' % (key)) key_hits.add(key) if not offset_found: print(' hit in page slack space')