예제 #1
0
def main(argv=None):
    pdumps, ndump = process_command_line(argv)

    dtype = False

    pos_dumps = [reader.read_memory_dump(f) for f in pdumps]
    if not dtype:
        for md in pos_dumps:
            md.build_memory_graph()

        intersec1 = diff_memory_graphs(pos_dumps)

        if ndump is not None:
            neg_dump = reader.read_memory_dump(ndump)
            neg_dump.build_memory_graph()
            intersec2 = diff_memory_graphs([pos_dumps[-1], neg_dump])
            intersec1 = substract_intersections(pos_dumps, neg_dump,
                                                        intersec1, intersec2)

            extract_diff_graph(pos_dumps[-1], intersec1)
            print('Changed:', len(intersec1[0]))
            services.print_collection(intersec1[2])
            services.print_collection(intersec1[0])
            print('Removed:', len(intersec1[1]))
            services.print_collection(intersec1[1])
            print('Added:', len(intersec1[2]))
    else:
        pass
예제 #2
0
def main(argv=None):
    from extras import reader
    dump, offset, address = process_command_line(argv)

    md = reader.read_memory_dump(dump)
    md.build_memory_graph()
    services.export_memory_graph(md)

    if offset is not None:
        print("offset {} corresponds to v-address 0x{:x}".format(
            offset, afo(md, int(offset, 0))))
    if address is not None:
        print("address {} corresponds to offset {}".format(
            address, ofa(md, int(address, 16))))
예제 #3
0
def main(argv=None):
    from extras import reader
    dump, offset, address = process_command_line(argv)

    md = reader.read_memory_dump(dump)
    md.build_memory_graph()
    services.export_memory_graph(md)

    if offset is not None:
        print("offset {} corresponds to v-address 0x{:x}".format(offset,
                                                     afo(md, int(offset, 0))))
    if address is not None:
        print("address {} corresponds to offset {}".format(address, ofa(md,
                                                            int(address, 16))))
예제 #4
0
		for (md, v) in zip(pos_dumps, values):
			if b in KeyedSet(md.memory_graph.nodes(), key=lambda seg: seg.address):
				ob[b] = offsets_in_node(b, enc_type, v)
				break

	return ob


if __name__ == '__main__':
	parser = argparse.ArgumentParser(description='Search for values in a memory\
		graph or the intersection of memory graphs.')
	parser.add_argument('-d', required=True, dest='dumps' , nargs='+',
					metavar='dumps', help='memory dump files.')
	parser.add_argument('-v', required=True, dest='values', nargs='+',
					metavar='values',
					help='value corresponding to each memory dump.')
	args = parser.parse_args()

	pos_dumps = [reader.read_memory_dump(f) for f in args.dumps]

	if len(pos_dumps) == 1:
		offsets = number_offset(pos_dumps[0], args.values[0])
		print('Number of candidate offsets:', len(offsets))

		for (o, t) in offsets:
			print('0x{:x}'.format(services.address_from_offset(pos_dumps[0], o)), t)
	else:
		intersection = diffing.diff_memory_segments(pos_dumps)

		print('TODO: finish intersection by value')
@author: David I. Urbina
'''
from __future__ import print_function
import argparse
import extras.reader as reader
import finding_doi.memory_diffing as diffing
import finding_doi.value_scanning as scanning

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Compares memory dumps data structures')
    parser.add_argument(dest='address' , metavar='address', help='address of the data structure to compare.')
    parser.add_argument(dest='dumps', nargs='+', metavar='dumps', help='memory dump files.')
    parser.add_argument('-r', dest='dump', metavar='dump', help='memory dump to remove.')
    args = parser.parse_args()

    memory_dumps = [reader.read_memory_dump(f) for f in args.dumps]

    for md in memory_dumps:
        md.build_memory_graph()

    dss = list()
    for md in memory_dumps:
        for m in md.modules:
            if m.address == int(args.address, 16):
                dss.append(m)
                break

    if len(dss) == 0:
        dss = [md.data_structures[int(args.address, 16)] for md in memory_dumps]

    offsets1 = diffing.diff_memory_segments(dss)
예제 #6
0
def main(argv=None):
    pdump, ndump, values, _type = process_command_line(argv)

    #==========================================================================
    # Memory Graph Generation
    #==========================================================================
    print('MEMORY GRAPH GENERATION')
    pos_dumps = [reader.read_memory_dump(f) for f in pdump]
    for md in pos_dumps:
        md.build_memory_graph()
    if ndump:
        neg_dump = reader.read_memory_dump(ndump)
        neg_dump.build_memory_graph()

    # If only one positive memory dump
    graph = pos_dumps[-1].memory_graph
    graph.roots = pos_dumps[-1].modules

    #==========================================================================
    # Finding Data of Interest
    #==========================================================================
    print('FINDING DATA OF INTEREST')
    obb = dict()  # Offsets by Buffer
    diffing = None  # (Different, Removed, Added) Buffers
    if len(pos_dumps) > 1:
    #-------------------------------------------- Memory Diffing at graph level
        services.start_op('\tDiffing memory graphs...')

        diffing = memory_diffing.diff_memory_graphs(pos_dumps)

        if ndump:
            neg_diffing = memory_diffing.diff_memory_graphs([pos_dumps[-1],
                                                            neg_dump])
            diffing = memory_diffing.substract_intersections(pos_dumps,
                             [pos_dumps[-1], neg_dump], diffing, neg_diffing)

        services.end_op()
    #------------------------------------------- Memory Diffing at buffer level
        services.start_op('\tDiffing buffers...')
        for b in diffing[0].copy():
            obb[b] = memory_diffing.diff_memory_segments_by_address(b.address,
                                                                     pos_dumps)
            # There is at least one common offset across dumps?
            if len(obb[b]) == 0:
                del obb[b]
                diffing[0].remove(b)
                continue

            if ndump:
                offsets = memory_diffing.diff_memory_segments_by_address(
                                        b.address, [pos_dumps[-1], neg_dump])
                obb[b] = obb[b] - offsets
# TODO: do we need ranges?
            # obb[b] = services.extract_ranges(list(obb[b]))

        services.end_op()

        if len(pos_dumps) > 1:
            print('Changed:', len(diffing[0]))
            for b in diffing[0]:
                print(repr(b), '#different offsets:', len(obb[b]))
            print('Removed:', len(diffing[1]))
            services.print_collection(diffing[1])
            print('Added:', len(diffing[2]))
            services.print_collection(diffing[2])

        # Adding the added buffers with offset 0
        for b in diffing[2]:
            obb[b] = {0}

        # The graph resulting from the memory diffing
        services.start_op('Extracting diff_graph...')
        graph = memory_diffing.extract_diff_graph(pos_dumps[-1], diffing)
        services.end_op()
#         for (b, o) in obb.items():
#             print(b, o)

# TODO: remove
#         return 1

    #----------------------------------------------------------- Value Scanning
    if values:
        services.start_op('\tValue Scanning...')
        obbbv = dict()  # Offsets by buffer by value
        # Only one memory dump?
        if diffing == None:  # Yes, use graph
            obbbv = value_scanning.offsets_in_graph(graph, _type,
                                                                values[0])
        else:  # No, use diffing
            obbbv = value_scanning.offsets_in_diffing(pos_dumps, values,
                                                            diffing, _type)
#         for (b, o) in obbbv.items():
#             print(b, o)
        services.end_op()
    #--------------------------- Intercepting Memory Diffing and Value Scanning

    fcob = dict()  # Final candidate offsets by buffer
    # Memory Diffing and Value Scanning
    if len(pos_dumps) > 1 and values:
        services.start_op('\tIntercepting Memory Diffing and Value \
                                                                Scanning...')
        for b in diffing[0]:  # Intercept changed with values
            offsets = obb[b] & {o[0] for o in obbbv[b]}
            if len(offsets) > 0:
                fcob[b] = offsets
        for b in diffing[2]:  # Intercept added with values
            offsets = {o[0] for o in obbbv[b]}
            if len(offsets) > 0:
                fcob[b] = offsets
        services.end_op()
    # Only Memory Diffing
    elif len(pos_dumps) > 1:
        fcob = obb
    # Only Value Scanning
    else:
        for (b, l) in obbbv.items():
            if len(l) > 0:
                of = {o[0] for o in l}
                fcob[b] = of

    print('\tFinal set of candidate offsets:', len(fcob))
    for (b, o) in fcob.items():
        print('\t\t', b, o)

    #==========================================================================
    # Signature Generation
    #==========================================================================
    print('SIGNATURE GENERATION')
    #------------------------------------------------------------ Extract Paths

    services.start_op('\tExtracting Paths...')
    pb = dict()  # Paths by buffer
    for b in fcob:
        pb[b] = extract_paths.by_buffer(graph, b)
    services.end_op()

    for (b, paths) in pb.items():
        print('\t', b)
        for (index, path) in enumerate(paths):
            n = path.normalize()
            nx.write_dot(n, str(b) + '-' + str(index) + '.dot')
            print('\t\t', index, '-', path)
#             print('\t\t', index, '-', str(n))
    return 0
예제 #7
0
    parser = argparse.ArgumentParser(description='List the possible \
        reference paths to the specified data structure in a memory \
        dump. The data structure may be specified by its value or by \
        its address. By default it search for shortest reference paths.')
    parser.add_argument(dest='dump', metavar='dump', help='memory dump file.')
    parser.add_argument('-a', dest='address', metavar='address',
                                        help='address of the data structure.')
    parser.add_argument('-s', dest='ascii', metavar='ascii',
                                            help='ASCII value to search for.')
    parser.add_argument('-u', dest='unicode', metavar='unicode',
                                    help='Unicode(UTF16) value to search for.')
    parser.add_argument('--All', dest='all', action='store_true',
                help='search for all simple paths. It may take a long time.')
    args = parser.parse_args()

    md = reader.read_memory_dump(args.dump)
    md.build_memory_graph()

    if args.all:
        search_paths = nx.all_simple_paths

    # Search by address
    if args.address != None:
        rps = by_address(md, int(args.address, 16))
        print('{} paths to data structure 0x{:x}'.format(len(rps),
                                                     int(args.address, 16)))
    # Search by ASCII
    elif args.ascii != None:
        rps = by_string(md, args.ascii)
        print('{} paths to the ASCII string {}'.format(len(rps), args.ascii))
    # Search by Unicode(UTF16)
예제 #8
0
def main(argv=None):
    pdump, ndump, values, _type = process_command_line(argv)

    #==========================================================================
    # Memory Graph Generation
    #==========================================================================
    print('MEMORY GRAPH GENERATION')
    pos_dumps = [reader.read_memory_dump(f) for f in pdump]
    for md in pos_dumps:
        md.build_memory_graph()
    if ndump:
        neg_dump = reader.read_memory_dump(ndump)
        neg_dump.build_memory_graph()

    # If only one positive memory dump
    graph = pos_dumps[-1].memory_graph
    graph.roots = pos_dumps[-1].modules

    #==========================================================================
    # Finding Data of Interest
    #==========================================================================
    print('FINDING DATA OF INTEREST')
    obb = dict()  # Offsets by Buffer
    diffing = None  # (Different, Removed, Added) Buffers
    if len(pos_dumps) > 1:
        #-------------------------------------------- Memory Diffing at graph level
        services.start_op('\tDiffing memory graphs...')

        diffing = memory_diffing.diff_memory_graphs(pos_dumps)

        if ndump:
            neg_diffing = memory_diffing.diff_memory_graphs(
                [pos_dumps[-1], neg_dump])
            diffing = memory_diffing.substract_intersections(
                pos_dumps, [pos_dumps[-1], neg_dump], diffing, neg_diffing)

        services.end_op()
        #------------------------------------------- Memory Diffing at buffer level
        services.start_op('\tDiffing buffers...')
        for b in diffing[0].copy():
            obb[b] = memory_diffing.diff_memory_segments_by_address(
                b.address, pos_dumps)
            # There is at least one common offset across dumps?
            if len(obb[b]) == 0:
                del obb[b]
                diffing[0].remove(b)
                continue

            if ndump:
                offsets = memory_diffing.diff_memory_segments_by_address(
                    b.address, [pos_dumps[-1], neg_dump])
                obb[b] = obb[b] - offsets
# TODO: do we need ranges?
# obb[b] = services.extract_ranges(list(obb[b]))

        services.end_op()

        if len(pos_dumps) > 1:
            print('Changed:', len(diffing[0]))
            for b in diffing[0]:
                print(repr(b), '#different offsets:', len(obb[b]))
            print('Removed:', len(diffing[1]))
            services.print_collection(diffing[1])
            print('Added:', len(diffing[2]))
            services.print_collection(diffing[2])

        # Adding the added buffers with offset 0
        for b in diffing[2]:
            obb[b] = {0}

        # The graph resulting from the memory diffing
        services.start_op('Extracting diff_graph...')
        graph = memory_diffing.extract_diff_graph(pos_dumps[-1], diffing)
        services.end_op()
#         for (b, o) in obb.items():
#             print(b, o)

# TODO: remove
#         return 1

#----------------------------------------------------------- Value Scanning
    if values:
        services.start_op('\tValue Scanning...')
        obbbv = dict()  # Offsets by buffer by value
        # Only one memory dump?
        if diffing == None:  # Yes, use graph
            obbbv = value_scanning.offsets_in_graph(graph, _type, values[0])
        else:  # No, use diffing
            obbbv = value_scanning.offsets_in_diffing(pos_dumps, values,
                                                      diffing, _type)
#         for (b, o) in obbbv.items():
#             print(b, o)
        services.end_op()
    #--------------------------- Intercepting Memory Diffing and Value Scanning

    fcob = dict()  # Final candidate offsets by buffer
    # Memory Diffing and Value Scanning
    if len(pos_dumps) > 1 and values:
        services.start_op('\tIntercepting Memory Diffing and Value \
                                                                Scanning...')
        for b in diffing[0]:  # Intercept changed with values
            offsets = obb[b] & {o[0] for o in obbbv[b]}
            if len(offsets) > 0:
                fcob[b] = offsets
        for b in diffing[2]:  # Intercept added with values
            offsets = {o[0] for o in obbbv[b]}
            if len(offsets) > 0:
                fcob[b] = offsets
        services.end_op()
    # Only Memory Diffing
    elif len(pos_dumps) > 1:
        fcob = obb
    # Only Value Scanning
    else:
        for (b, l) in obbbv.items():
            if len(l) > 0:
                of = {o[0] for o in l}
                fcob[b] = of

    print('\tFinal set of candidate offsets:', len(fcob))
    for (b, o) in fcob.items():
        print('\t\t', b, o)

    #==========================================================================
    # Signature Generation
    #==========================================================================
    print('SIGNATURE GENERATION')
    #------------------------------------------------------------ Extract Paths

    services.start_op('\tExtracting Paths...')
    pb = dict()  # Paths by buffer
    for b in fcob:
        pb[b] = extract_paths.by_buffer(graph, b)
    services.end_op()

    for (b, paths) in pb.items():
        print('\t', b)
        for (index, path) in enumerate(paths):
            n = path.normalize()
            nx.write_dot(n, str(b) + '-' + str(index) + '.dot')
            print('\t\t', index, '-', path)


#             print('\t\t', index, '-', str(n))
    return 0
    parser = argparse.ArgumentParser(
        description='Compares memory dumps data structures')
    parser.add_argument(dest='address',
                        metavar='address',
                        help='address of the data structure to compare.')
    parser.add_argument(dest='dumps',
                        nargs='+',
                        metavar='dumps',
                        help='memory dump files.')
    parser.add_argument('-r',
                        dest='dump',
                        metavar='dump',
                        help='memory dump to remove.')
    args = parser.parse_args()

    memory_dumps = [reader.read_memory_dump(f) for f in args.dumps]

    for md in memory_dumps:
        md.build_memory_graph()

    dss = list()
    for md in memory_dumps:
        for m in md.modules:
            if m.address == int(args.address, 16):
                dss.append(m)
                break

    if len(dss) == 0:
        dss = [
            md.data_structures[int(args.address, 16)] for md in memory_dumps
        ]
예제 #10
0
    parser.add_argument('-s',
                        dest='ascii',
                        metavar='ascii',
                        help='ASCII value to search for.')
    parser.add_argument('-u',
                        dest='unicode',
                        metavar='unicode',
                        help='Unicode(UTF16) value to search for.')
    parser.add_argument(
        '--All',
        dest='all',
        action='store_true',
        help='search for all simple paths. It may take a long time.')
    args = parser.parse_args()

    md = reader.read_memory_dump(args.dump)
    md.build_memory_graph()

    if args.all:
        search_paths = nx.all_simple_paths

    # Search by address
    if args.address != None:
        rps = by_address(md, int(args.address, 16))
        print('{} paths to data structure 0x{:x}'.format(
            len(rps), int(args.address, 16)))
    # Search by ASCII
    elif args.ascii != None:
        rps = by_string(md, args.ascii)
        print('{} paths to the ASCII string {}'.format(len(rps), args.ascii))
    # Search by Unicode(UTF16)