Пример #1
0
def main():
    parser = YaffsParser.get_argparser()
    parser.add_argument("--fraction",
                        help='The file size of the sampled file as a fraction of the original.',
                        type=float, default=0.01, dest="sample_fraction")

    args = parser.parse_args()

    image_size = os.path.getsize(args.imagefile)
    #We use ceiling so that we always have at least one block to grab, even
    #if the fraction is 0.000000000001
    total_num_blocks = image_size / (args.blocksize * (args.chunksize + args.oobsize))
    num_blocks = math.ceil(total_num_blocks * args.sample_fraction)
    num_blocks = int(num_blocks)

    blocks = YaffsParser.extract_ordered_blocks(args.imagefile,
                                                args.chunksize,
                                                args.oobsize,
                                                args.blocksize,
                                                args.tag_offset)

    sampled_blocks = random.sample(blocks, num_blocks)

    root, ext = os.path.splitext(args.imagefile)
    outfile = "%s_sampled_%s%s" % (root, str(args.sample_fraction).replace('.', "d"), ext)
    print 'Outfile: %s' % outfile

    with open(args.imagefile, 'rb') as f:
        with open(outfile, 'wb') as out:
            for sblock in sampled_blocks:
                f.seek(sblock.chunk_pairs[0][1].offset)
                out.write(f.read((args.chunksize + args.oobsize) * args.blocksize))
Пример #2
0
def guess_block_size(image, chunk_size, oob_size, oob_offset):
    chunk_pairs = YaffsParser.extract_chunks(image, chunk_size, oob_size)
    chunks = [c for c, o in chunk_pairs[:1024]]

    oobs_bytes = YaffsParser.get_oob_bytes(image, chunks, oob_size)

    oobs = [YaffsOobTag(b, oob_offset) for b in oobs_bytes]

    prev = -1
    counts = []
    count = 0

    for oob in oobs:
        if oob.block_seq != prev:
            if count > 0:
                counts.append(count)
            count = 1
            prev = oob.block_seq
        else:
            count += 1

    import collections
    size, freq = collections.Counter(counts).most_common(1)[0]

    if freq == 1:
        print "Unable to determine block size."
        return None

    print "Most likely block size: %d" % size
    return size
Пример #3
0
def main():
    parser = YaffsParser.get_argparser()
    args = parser.parse_args()

    #read in and order all of the blocks, by reverse order of sequence number
    sorted_blocks = YaffsParser.extract_ordered_blocks(args.imagefile,
                                                       args.chunksize,
                                                       args.oobsize,
                                                       args.blocksize,
                                                       args.tag_offset)

    objects = YaffsParser.extract_objects(sorted_blocks)

    current_objects = [o for o in objects if not o.is_deleted]

    current_file_objects = []

    for obj in current_objects:
        #check the object type from the first header chunk.
        if len(obj.versions) > 0 and obj.versions[0][0][1].obj_type == 1:
            current_file_objects.append(obj)

    print "object_id,name,time_diff,expected,actual"

    for obj in current_file_objects:
        missing = get_missing_chunks_by_version(obj)

        for expected, actual, time_diff, name in missing:
            if time_diff < 0:
                pass

            print "%d\t%s\t%s\t%d\t%d" % (obj.object_id, name, time_diff, expected, actual)
Пример #4
0
def main():
    parser = YaffsParser.get_argparser()
    args = parser.parse_args()

    #read in and order all of the blocks, by reverse order of sequence number
    sorted_blocks = YaffsParser.extract_ordered_blocks(args.imagefile,
                                                       args.chunksize,
                                                       args.oobsize,
                                                       args.blocksize,
                                                       args.tag_offset)

    objects = YaffsParser.extract_objects(sorted_blocks)
    current_objects = [o for o in objects if not o.is_deleted]
    current_file_objects = []

    for obj in current_objects:
        #check the object type from the first header chunk.
        if len(obj.versions) > 0 and obj.versions[0][0][1].obj_type == 1:
            current_file_objects.append(obj)

    print "object_id,name,chunk_id,count"

    for obj in current_file_objects:
        count = 0
        name = obj.versions[0][0][1].name

        for id in obj.chunkDict:
            if id == 0:
                continue
            if len(obj.chunkDict[id]) > 1:
                print "%d\t%s\t%d\t%d" % (obj.object_id, name, id, len(obj.chunkDict[id]))
Пример #5
0
def extract_files(image, filenames, chunksize, oobsize, blocksize, oob_tag_offset, versions):
    """
    Extracts the most recent version of every file in the filenames
    list.
    """
    blocks = YaffsParser.extract_ordered_blocks(image, chunksize, oobsize,
                                                blocksize, oob_tag_offset)
    objects = YaffsParser.extract_objects(blocks)

    destination = os.path.dirname(image)

    for name in filenames:
        extract_file(objects, name, destination, versions)
def main():
    parser = YaffsParser.get_argparser()

    args = parser.parse_args()

    #read in and order all of the blocks
    sorted_blocks = YaffsParser.extract_ordered_blocks(args.imagefile,
                                                       args.pagesize,
                                                       args.oobsize,
                                                       args.blocksize,
                                                       tag_offset=args.tag_offset)

    missing_set = get_missing_block_numbers(sorted_blocks)
Пример #7
0
def guess_oob_offset(image, headers, oob_size):
    oobs_bytes = YaffsParser.get_oob_bytes(image, headers, oob_size)

    best_parsed = []

    # We use -16 because we are looking for 16 bytes in the tag
    # for parsing
    for offset in xrange(0, oob_size-16):
        parsed = []

        for bytes in oobs_bytes:
            parsed_oob = YaffsOobTag(bytes, offset)
            if not parsed_oob.isHeaderTag:
                continue
            else:
                parsed.append(parsed_oob)

        if len(parsed) > len(best_parsed):
            best_offset = offset
            best_parsed = parsed

    object_ids = set([o.object_id for o in best_parsed])

    if len(object_ids) > 0:
        print "OOB tag offset is %d" % best_offset
        print "with %d valid header tags" % len(best_parsed)
        print "Object id: %s" % str(object_ids)
        return best_offset

    print "Unable to determine OOB tag offset."
    return None
Пример #8
0
def main():
    """
    Assume we pass this script the image file path as an argument on the
    command line.
    """
    DEFAULT_ANCHORS = ['contacts2.db']
    DEFAULT_CHUNK_SIZES = [1024, 2048, 4096]
    DEFAULT_OOB_SIZES = [0, 32, 64, 128]

    parser = YaffsParser.get_argparser()
    parser.add_argument("--anchors",
                        help="The filenames to use for anchoring the search. Default: %s" % DEFAULT_ANCHORS,
                        nargs='*', default=DEFAULT_ANCHORS, dest="anchors")
    parser.add_argument("--chunksizes",
                        help="The chunk sizes to test for. Default: %s" % DEFAULT_CHUNK_SIZES,
                        nargs='*', default=DEFAULT_CHUNK_SIZES, dest="chunk_sizes", type=int)
    parser.add_argument("--oobsizes",
                        help="The oob sizes to test for. Default: %s" % DEFAULT_OOB_SIZES,
                        nargs='*', default=DEFAULT_OOB_SIZES, dest="oob_sizes", type=int)
    args = parser.parse_args()

    print args.imagefile

    for anchor in args.anchors:
        print 'Scanning for %s' % anchor
        scan_file(args.imagefile, anchor, args.chunk_sizes, args.oob_sizes)
    pass
def main():
    """
    Assume we pass this script the image file path as an argument on the
    command line.
    """

    usage = 'usage: %prog [options] imagefile'

    parser = OptionParser(usage=usage)
    parser.add_option('--chunksize', action='store', type='int',
                      dest='chunk_size', default=2048)
    parser.add_option('--oobsize', action='store', type='int',
                      dest='oob_size', default=64)

    options, args = parser.parse_args()

    if len(args) != 1:
        print "Incorrect command line arguments. Missing (or too many) image files"
        return 1

    image = args[0]

    headers = Scanner.get_anchor_headers(image, options.chunk_size,
                                         options.oob_size, 'contacts2.db')

    oobs = YaffsParser.get_oob_bytes(image, headers, options.oob_size)

    for oob in oobs:
        sys.stdout.write(oob)

        #Separate each oob with 16 'X' Bytes.
        sys.stdout.write('X'*16)
Пример #10
0
def count_constant_oobs(image, chunks, oobsize):
    oobs = YaffsParser.get_oob_bytes(image, chunks, oobsize)
    constants_count = 0
    constant = '\xff' * oobsize

    for oob in oobs:
        if oob == constant:
            constants_count += 1

    return constants_count
Пример #11
0
def main():
    parser = YaffsParser.get_argparser()

    args = parser.parse_args()

    blocks = YaffsParser.extract_ordered_blocks(args.imagefile,
                                                args.chunksize,
                                                args.oobsize,
                                                args.blocksize,
                                                args.tag_offset)

    objects = YaffsParser.extract_objects(blocks)

    tuple_set = set()

    for object in objects:
        for version in object.versions:
            tuple_set.add((object.object_id, version[0][1].name))

    for tuple in tuple_set:
        print tuple
Пример #12
0
def get_headers(image, chunk_size, oob_size):
    chunk_pairs = YaffsParser.extract_chunks(image, chunk_size, oob_size)

    #First filter, The first byte should be 0x01
    #Litte endian
    header_chunks = [YaffsHeader(c) for c, obb in chunk_pairs
                     if c.get_bytes(4) == '\x01\00\00\00']

    #Now use the second, slower filter.
    header_chunks = [c for c in header_chunks
                     if YaffsHeader(c).is_valid()]

    return header_chunks
Пример #13
0
def main():
    """
    Assume we pass this scirpt the image file as an argument
    """
    DEFAULT_VERSIONS = [0]

    parser = YaffsParser.get_argparser()

    parser.add_argument("--files",
                    help="The files to extract.",
                    nargs='*', dest="files")

    parser.add_argument("--versions",
                        help="The version numbers to extract, 0 is newest, -1 is oldest",
                        type=int,
                        default=DEFAULT_VERSIONS,
                        nargs='*', dest='version_numbers')

    args = parser.parse_args()

    extract_files(args.imagefile, args.files, args.chunksize,
                  args.oobsize, args.blocksize, args.tag_offset, args.version_numbers)
Пример #14
0
"""
This is a quick script for trying to grab the start of the contacts2.db
file by making some assumptions about the format of the oob.'

The current numbers are hardcoded for the Via Forensics Droid Eris image.
"""

import Scanner, YaffsParser
import sys

# I found this manually
object_id = '\xb4\x02\x00\x00'

chunk_id = '\x01\x00\x00\00'

image = sys.argv[1]

print image

chunk_pairs = YaffsParser.extract_chunks(image, 2048, 64)

f = open(image, 'rb')

for (chunk, oob_offset) in chunk_pairs:
    f.seek(oob_offset+34)
    if object_id == f.read(4) and chunk_id == f.read(4):
        print 'Found chunk 1'
        print chunk.get_bytes(3)


f.close()
Пример #15
0
def main():
    parser = YaffsParser.get_argparser()
    args = parser.parse_args()

    print args.imagefile, args.chunksize, args.oobsize, args.blocksize, args.tag_offset
    print "Script started: ", datetime.datetime.now()
    print 'File size: ', os.path.getsize(args.imagefile)

    #read in and order all of the blocks, by reverse order of sequence number
    sorted_blocks = YaffsParser.extract_ordered_blocks(args.imagefile,
                                                       args.chunksize,
                                                       args.oobsize,
                                                       args.blocksize,
                                                       args.tag_offset)



    nonerased_blocks = [b for b in sorted_blocks if not b.is_erased]

    print '%d blocks' % len(sorted_blocks)
    print 'Sequence number range: %d -- %d' \
          % (nonerased_blocks[-1].sequence_num, nonerased_blocks[0].sequence_num)

    print 'Found %d erased blocks.' % (len(sorted_blocks) - len(nonerased_blocks))

    #This can happen if the phone is turned off while writing.
    print 'Found %d blocks with mismatched sequence numbers' \
          % len([block for block in sorted_blocks if block.possible_parse_error])

    missing_seq_nums = summarize_deleted_blocks.get_missing_block_numbers(sorted_blocks)

    objects = YaffsParser.extract_objects(sorted_blocks)

    print 'Found %d objects' % len(objects)
    print 'Found %d objects with a header.' % len([obj for obj in objects if 0 in obj.chunkDict])
    print 'Found %d deleted objects.' % len([obj for obj in objects if obj.is_deleted])

    recent_pairs = []
    total_pairs_count = 0
    for block in sorted_blocks:
        recent_pairs.extend([(tag, chunk) for tag, chunk in block.chunk_pairs if tag.is_most_recent])
        total_pairs_count += len(block.chunk_pairs)

    print 'Number of Recent chunks: %d' % len(recent_pairs)
    print 'Total number of chunks: %d' % total_pairs_count
    print 'Fraction recent: %0.2f' % (float(len(recent_pairs)) / total_pairs_count)

    last_time = None
    first_time = None

    for block in nonerased_blocks:
        for tag, chunk in block.chunk_pairs:
            if tag.isHeaderTag:
                print block.sequence_num
                last_time = time.ctime(YaffsHeader(chunk).mtime)
                break

        if last_time:
            break


    for x in xrange(len(nonerased_blocks)-1, 0, -1):
        block = nonerased_blocks[x]
        for y in xrange(len(block.chunk_pairs)-1, 0, -1):
            tag, chunk = block.chunk_pairs[y]
            if tag.isHeaderTag:
                print block.sequence_num
                first_time = time.ctime(YaffsHeader(chunk).mtime)
                break
        if first_time:
            break


    print 'Oldest object modification: %s' % first_time
    print 'Newest object modification: %s' % last_time