Exemplo n.º 1
0
def main(args):
    enable_trace = args.output != 'off'

    # Listify extra modules.
    if args.extra_modules is None:
        extra_modules = []

    ql = Qiling(extra_modules + [args.target],
                ".",                                        # rootfs
                console=True if enable_trace else False,
                stdout=1 if enable_trace else None,
                stderr=1 if enable_trace else None,
                output=args.output,
                profile="smm/smm.ini")

    ql.os.after_module_execution_callbacks = []
    ql.os.notify_after_module_execution = after_module_execution_callback

    # Load NVRAM environment.
    if args.nvram_file:
        with open(args.nvram_file, 'rb') as f:
            ql.env = pickle.load(f)

    # The last loaded image is the main module we're interested in fuzzing
    pe = pefile.PE(args.target, fast_load=True)
    image_base = ql.loader.images[-1].base
    entry_point = image_base + pe.OPTIONAL_HEADER.AddressOfEntryPoint

    # Not passing the fuzzing mode argument results in a dry run, without AFL's involvement.
    if args.mode:
        # We want AFL's forkserver to spawn new copies starting from the main module's entrypoint.
        ql.hook_address(callback=start_afl, address=entry_point, user_data=args)

    if args.taint:
        taint.tracker.enable(ql, args.taint)

    # Init SMM related protocols
    smm.init(ql, args.mode == 'swsmi')

    # Run custom initialization script.
    if args.load_package:
        mod = importlib.import_module(args.load_package)
        if hasattr(mod, 'run'):
            mod.run(ql)

    # Enable sanitizers.
    if args.sanitize:
        for name in args.sanitize:
            sanitizers.get(name)(ql).enable()

    # okay, ready to roll.
    try:
        ql.run(end=args.end, timeout=args.timeout)
    except Exception as ex:
        # Probable Unicorn memory error. Treat as crash.
        verbose_abort(ql)

    os._exit(0)  # that's a looot faster than tidying up.
Exemplo n.º 2
0
def main(target_binary, nvram_file, var_name, input_file, output, end, timeout,
         sanitize, track_uninitialized, extra_modules):
    enable_trace = output != 'off'

    # Listify extra modules.
    if extra_modules is None:
        extra_modules = []

    ql = Qiling(
        extra_modules + [target_binary],
        ".",  # rootfs
        console=True if enable_trace else False,
        stdout=1 if enable_trace else None,
        stderr=1 if enable_trace else None,
        output=output)

    # Load NVRAM environment.
    with open(nvram_file, 'rb') as f:
        ql.env = pickle.load(f)

    # The last loaded image is the main module we're interested in fuzzing
    pe = pefile.PE(target_binary, fast_load=True)
    image_base = ql.loader.images[-1].base
    entry_point = image_base + pe.OPTIONAL_HEADER.AddressOfEntryPoint

    # We want AFL's forkserver to spawn new copies starting from the main module's entrypoint.
    ql.hook_address(callback=start_afl,
                    address=entry_point,
                    user_data=(input_file, var_name, sanitize))

    if sanitize:
        enable_sanitized_heap(ql)
        enable_sanitized_CopyMem(ql)
        enable_sanitized_SetMem(ql)

    if track_uninitialized:
        enable_uninitialized_memory_tracker(ql)

    # okay, ready to roll.
    try:
        ql.run(end=end, timeout=timeout)
    except Exception as ex:
        # Probable Unicorn memory error. Treat as crash.
        verbose_abort(ql)

    os._exit(0)  # that's a looot faster than tidying up.
Exemplo n.º 3
0
def test_uninitialized_memory_tracker():
    enable_trace = True
    ql = Qiling(
        ['./bin/UninitializedMemoryTrackerTest.efi'],
        ".",  # rootfs
        console=True if enable_trace else False,
        stdout=1 if enable_trace else None,
        stderr=1 if enable_trace else None,
        output='debug')

    # NVRAM environment.
    ql.env = {'foo': b'\xde\xad\xbe\xef'}

    def validate_taint_set_variable(ql, address, params):
        assert params['VariableName'] == 'bar' and params['DataSize'] == 0x14
        begin = params['Data']
        end = params['Data'] + params['DataSize']
        tainted_bytes = ql.tainters['uninitialized'].get_taint_range(
            begin, end)
        assert tainted_bytes == [
            True, True, True, True, True, True, False, False, False, False,
            True, True, True, True, True, True, True, False, True, True
        ]
        # Un-taint to avoid crashing the process.
        ql.tainters['uninitialized'].set_taint_range(begin, end, False)
        return (address, params)

    # Hook SetVariable() to check the taint on the buffer.
    set_variable_spy = mockito.spy(validate_taint_set_variable)
    ql.set_api("SetVariable", set_variable_spy, QL_INTERCEPT.ENTER)

    # okay, ready to roll.
    enable_uninitialized_memory_tracker(ql)
    ql.run()

    # Make sure that SetVariable() was intercepted once.
    mockito.verify(set_variable_spy, times=1).__call__(*mockito.ARGS)