Example #1
0
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
Example #2
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
Example #3
0
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
Example #4
0
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
Example #5
0
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)]
Example #6
0
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')