Exemplo n.º 1
0
    def _test_elf_linux_x86_snapshot_restore_common(self, reg=False, ctx=False):
        rootfs = "../examples/rootfs/x86_linux"
        cmdline = ["../examples/rootfs/x86_linux/bin/x86_hello"]
        snapshot = os.path.join(rootfs, 'snapshot_restore_reg_ctx.snapshot')

        ql = Qiling(cmdline, rootfs, verbose=QL_VERBOSE.DEBUG)

        X86BASE = int(ql.profile.get("OS32", "load_address"), 16)
        hook_address = X86BASE + 0x542 # call printf

        def dump(ql):
            nonlocal snapshot
            nonlocal reg
            nonlocal ctx
            ql.save(reg=reg, cpu_context=ctx, os=True, loader=True, snapshot=snapshot)
            ql.emu_stop()
        ql.hook_address(dump, hook_address)

        ql.run()

        # make sure that the ending PC is the same as the hook address because dump stops the emulater
        assert ql.arch.regs.arch_pc == hook_address, f"0x{ql.arch.regs.arch_pc:x} != 0x{hook_address:x}"
        del ql

        ql = Qiling(cmdline, rootfs, verbose=QL_VERBOSE.DEBUG)
        ql.restore(snapshot=snapshot)

        # ensure that the starting PC is same as the PC we stopped on when taking the snapshot
        assert ql.arch.regs.arch_pc == hook_address, f"0x{ql.arch.regs.arch_pc:x} != 0x{hook_address:x}"

        ql.run(begin=hook_address)
        del ql
Exemplo n.º 2
0
        def hook_StartServiceA(ql: Qiling, address: int, params):
            ql.test_set_api = True

            hService = params["hService"]
            service_handle = ql.os.handle_manager.get(hService)

            if service_handle.name != "amsint32":
                return 1

            if service_handle.name not in ql.os.services:
                return 0

            service_path = ql.os.services[service_handle.name]
            service_path = ql.os.path.transform_to_real_path(service_path)

            amsint32 = Qiling([service_path],
                              ql.rootfs,
                              verbose=QL_VERBOSE.DEBUG)
            ntoskrnl = amsint32.loader.get_image_by_name("ntoskrnl.exe")
            self.assertIsNotNone(ntoskrnl)

            init_unseen_symbols(amsint32, ntoskrnl.base + 0xb7695,
                                b"NtTerminateProcess", 0, "ntoskrnl.exe")
            amsint32.log.info('Loading amsint32 driver')

            setattr(ql, 'amsint32_driver', amsint32)

            try:
                amsint32.run()
            except UcError as e:
                print("Load driver error: ", e)
                return 0
            else:
                return 1
Exemplo n.º 3
0
        def _t():
            if 'QL_FAST_TEST' in os.environ:
                return
            ql = Qiling(["../examples/rootfs/x86_windows/bin/al-khaser.bin"],
                        "../examples/rootfs/x86_windows")

            # The hooks are to remove the prints to file. It crashes. will debug why in the future
            def results(ql):

                if ql.reg.ebx == 1:
                    print("BAD")
                else:
                    print("GOOD ")
                ql.reg.eip = 0x402ee4

            #ql.hook_address(results, 0x00402e66)
            # the program alloc 4 bytes and then tries to write 0x2cc bytes.
            # I have no idea of why this code should work without this patch
            ql.patch(0x00401984, b'\xb8\x04\x00\x00\x00')

            def end(ql):
                print("We are finally done")
                ql.emu_stop()

            ql.hook_address(end, 0x004016ae)

            ql.run()
            del ql
            return True
Exemplo n.º 4
0
 def _t():
     ql = Qiling(["../examples/rootfs/x8664_windows/bin/Fls.exe"],
                 "../examples/rootfs/x8664_windows",
                 verbose=QL_VERBOSE.DEFAULT)
     ql.run()
     del ql
     return True
Exemplo n.º 5
0
 def _t():
     ql = Qiling([
         "../examples/rootfs/x8664_windows/bin//x8664_clipboard_test.exe"
     ], "../examples/rootfs/x8664_windows")
     ql.run()
     del ql
     return True
Exemplo n.º 6
0
def our_sandbox(path, rootfs):
    stdin = StringBuffer()
    ql = Qiling(path, rootfs, stdin=stdin)

    stdin.write(b"Ea5yR3versing\n")
    ql.hook_address(force_call_dialog_func, 0x00401016)
    ql.run()
Exemplo n.º 7
0
 def test_elf_linux_x86(self):
     ql = Qiling(["../examples/rootfs/x86_linux/bin/x86_hello"],
                 "../examples/rootfs/x86_linux",
                 verbose=QL_VERBOSE.DEBUG,
                 log_file="test.qlog")
     ql.run()
     del ql
Exemplo n.º 8
0
    def test_elf_hijackapi_linux_x8664(self):
        def my_puts_enter(ql: Qiling):
            params = ql.os.resolve_fcall_params(ELFTest.PARAMS_PUTS)
            self.test_enter_str = params["s"]

        def my_puts_exit(ql):
            self.test_exit_rdi = ql.reg.rdi

        ql = Qiling(["../examples/rootfs/x8664_linux/bin/x8664_puts"],
                    "../examples/rootfs/x8664_linux",
                    verbose=QL_VERBOSE.DEBUG)
        ql.set_api('puts', my_puts_enter, QL_INTERCEPT.ENTER)
        ql.set_api('puts', my_puts_exit, QL_INTERCEPT.EXIT)

        ql.run()

        if self.test_exit_rdi == 140736282240864:
            self.test_exit_rdi = 0x1

        self.assertEqual(0x1, self.test_exit_rdi)
        self.assertEqual("CCCC", self.test_enter_str)

        del self.test_exit_rdi
        del self.test_enter_str
        del ql
Exemplo n.º 9
0
def hook_StartServiceA(ql: Qiling, address: int, params):
    try:
        hService = params["hService"]
        service_handle = ql.os.handle_manager.get(hService)
        if service_handle.name == "amsint32":
            if service_handle.name in ql.os.services:
                service_path = ql.os.services[service_handle.name]
                service_path = ql.os.path.transform_to_real_path(service_path)
                ql.amsint32_driver = Qiling([service_path],
                                            ql.rootfs,
                                            verbose=QL_VERBOSE.DEBUG)
                init_unseen_symbols(
                    ql.amsint32_driver,
                    ql.amsint32_driver.loader.dlls["ntoskrnl.exe"] + 0xb7695,
                    b"NtTerminateProcess", 0, "ntoskrnl.exe")
                #ql.amsint32_driver.debugger= ":9999"
                try:
                    ql.amsint32_driver.load()
                    return 1
                except UcError as e:
                    print("Load driver error: ", e)
                    return 0
            else:
                return 0
        else:
            return 1
    except Exception as e:
        ql.log.exception("")
        print(e)
Exemplo n.º 10
0
    def __init__(self, invalid: bytes):
        # create a silent qiling instance
        self.ql = Qiling([rf"{ROOTFS}/bin/crackme.exe"],
                         ROOTFS,
                         verbose=QL_VERBOSE.OFF)

        self.ql.os.stdin = pipe.SimpleInStream(sys.stdin.fileno(
        ))  # take over the input to the program using a fake stdin
        self.ql.os.stdout = pipe.NullOutStream(
            sys.stdout.fileno())  # disregard program output

        # execute program until it reaches the part that asks for input
        self.ql.run(end=0x401030)

        # record replay starting and ending points.
        #
        # since the emulation halted upon entering a function, its return address is there on
        # the stack. we use it to limit the emulation till function returns
        self.replay_starts = self.ql.arch.regs.arch_pc
        self.replay_ends = self.ql.stack_read(0)

        # instead of restarting the whole program every time a new flag character is guessed,
        # we will restore its state to the latest point possible, fast-forwarding a good
        # amount of start-up code that is not affected by the input.
        #
        # here we save the state just when the read input function is about to be called so we
        # could use it to jumpstart the initialization part and get to the read input immediately
        self.jumpstart = self.ql.save() or {}

        # calibrate the replay instruction count by running the code with an invalid input
        # first. the instruction count returned from the calibration process will be then
        # used as a baseline for consequent replays
        self.best_icount = self.__run(invalid)
Exemplo n.º 11
0
def my_sandbox(file, ql_os, ql_arch, shellcode=False, profile=None):
    result = {}
    args = {}
    if profile:
        args["profile"] = f"{BASE_PATH}/profiles/{profile}"
    if shellcode:
        with open(file, "br") as f:
            args["shellcoder"] = f.read()
        args["ostype"] = ql_os
        args["archtype"] = ql_arch
    args["rootfs"] = f"{BASE_PATH}/rootfs/{ql_arch}_{ql_os}"
    # Std output is done to block the emulated software to print to standard output
    try:
        ql = Qiling(
            [file], **args, output="default", console=False, stdout=StringBuffer()
        )
        try:
            ql.run()
        except Exception as e:
            result["execution_error"] = str(e)
    except Exception as e:
        result["setup_error"] = str(e)
    else:
        result.update(generate_report(ql))
    finally:
        print(json.dumps(result))
Exemplo n.º 12
0
def our_sandbox(path: str, rootfs: str):
    ql = Qiling([path], rootfs, verbose=QL_VERBOSE.DEFAULT)

    # this crackme's logic lies within the function passed to DialogBoxParamA through
    # the lpDialogFunc parameter. normally DialogBoxParamA would call the function
    # passed through that parameter, but Qiling's implementation for it doesn't do
    # that.
    #
    # to solve this crackme and force the "success" dialog to show, we will:
    #  1. set up a mock stdin and feed it with the correct flag
    #  1. hook DialogBoxParamA to see where its lpDialogFunc param points to
    #  2. set up a valid set of arguments DialogFunc expects to see
    #  3. call it and see it greets us with a "success" message

    # [step #1]
    # set up a mock stdin and feed it with mocked keystrokes
    ql.os.stdin = pipe.SimpleInStream(sys.stdin.fileno())
    ql.os.stdin.write(b'Ea5yR3versing\n')

    # [step #2]
    # intercept DialogBoxParamA on exit
    ql.os.set_api('DialogBoxParamA', hook_DialogBoxParamA_onexit,
                  QL_INTERCEPT.EXIT)

    ql.run()
Exemplo n.º 13
0
        def hook_StartServiceA(ql, address, params):
            # TODO: Still Fixing
            hService = params["hService"]
            service_handle = ql.os.handle_manager.get(hService)
            if service_handle.name == "amsint32":
                if service_handle.name in ql.os.services:
                    service_path = ql.os.services[service_handle.name]
                    service_path = ql.os.transform_to_real_path(service_path)
                    ql.amsint32_driver = Qiling([service_path],
                                                ql.rootfs,
                                                output="disasm")
                    init_unseen_symbols(
                        ql.amsint32_driver,
                        ql.amsint32_driver.loader.dlls["ntoskrnl.exe"] +
                        0xb7695, b"NtTerminateProcess", 0, "ntoskrnl.exe")
                    print("load amsint32_driver")

                    try:
                        ql.amsint32_driver.run()
                        return 1
                    except UcError as e:
                        print("Load driver error: ", e)
                        return 0
                else:
                    return 0
            else:
                return 1
Exemplo n.º 14
0
def sanitized_emulate(path, rootfs, fault_type, output="debug", enable_trace=False):
    ql = Qiling([path], rootfs, output=output)
    ql.env['FaultType'] = fault_type
    enable_sanitized_heap(ql)
    ql.run()
    if not ql.loader.heap.validate():
        my_abort("Canary corruption detected")
Exemplo n.º 15
0
def test_firmware_volume():
    TEST_NAME = b'FirmwareVolume'

    enable_trace = True
    ql = Qiling(
        ['./bin/EfiFuzzTests.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.update({'TestName': TEST_NAME})

    rom.install(ql, "./res/$0AGD000.FL1")

    def validate_read_section(ql, address, params):
        buffer_size = read_int64(ql, params['BufferSize'])
        buffer = ql.mem.read(read_int64(ql, params['Buffer']), buffer_size)
        assert buffer.decode('utf-16').strip('\x00') == 'DxeMain.efi'
        return (address, params)

    # Hook ReadSection() to check the taint on the buffer.
    read_section_spy = mockito.spy(validate_read_section)
    ql.set_api("ReadSection", read_section_spy, QL_INTERCEPT.EXIT)

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

    # Make sure that ReadSection() was intercepted once.
    mockito.verify(read_section_spy, times=1).__call__(*mockito.ARGS)
Exemplo n.º 16
0
 def test_arm_stat64(self):
     ql = Qiling(
         ["../examples/rootfs/arm_linux/bin/arm_stat64", "/bin/arm_stat64"],
         "../examples/rootfs/arm_linux",
         verbose=QL_VERBOSE.DEBUG)
     ql.run()
     del ql
Exemplo n.º 17
0
 def test_armoabi_le_linux_syscall_elf_static(self):
     # src: https://github.com/qilingframework/qiling/blob/1f1e9bc756e59a0bfc112d32735f8882b1afc165/examples/src/linux/posix_syscall.c
     path = ["../examples/rootfs/arm_linux/bin/posix_syscall_lsb.armoabi"]
     rootfs = "../examples/rootfs/arm_linux"
     ql = Qiling(path, rootfs, verbose=QL_VERBOSE.DEBUG)
     ql.run()
     del ql
Exemplo n.º 18
0
    def test_gdbdebug_shellcode_server(self):
        X8664_LIN = bytes.fromhex(
            '31c048bbd19d9691d08c97ff48f7db53545f995257545eb03b0f05')

        ql = Qiling(code=X8664_LIN, archtype='x8664', ostype='linux')
        ql.debugger = 'gdb:127.0.0.1:9998'

        def gdb_test_client():
            # yield to allow ql to launch its gdbserver
            time.sleep(1.337 * 2)

            with SimpleGdbClient('127.0.0.1', 9998) as client:
                client.send(
                    'qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;xmlRegisters=i386'
                )
                client.send('vMustReplyEmpty')
                client.send('QStartNoAckMode')
                client.send('Hgp0.0')
                client.send('?')
                client.send('qC')
                client.send('g')
                client.send('p10')
                client.send('c')
                client.send('k')

                # yield to make sure ql gdbserver has enough time to receive our last command
                time.sleep(1.337)

        threading.Thread(target=gdb_test_client, daemon=True).start()

        ql.run()
        del ql
Exemplo n.º 19
0
    def test_elf_linux_x8664_flex_api(self):
        opened = []

        def onenter_fopen(ql: Qiling):
            params = ql.os.resolve_fcall_params({
                'filename': STRING,
                'mode': STRING
            })

            # log opened filenames
            opened.append(params['filename'])

        def hook_main(ql: Qiling):
            # set up fopen hook when reaching main
            ql.set_api('fopen', onenter_fopen, QL_INTERCEPT.ENTER)

        ql = Qiling(["../examples/rootfs/x8664_linux/bin/x8664_fetch_urandom"],
                    "../examples/rootfs/x8664_linux",
                    verbose=QL_VERBOSE.DEFAULT)

        ba = ql.loader.images[0].base
        ql.hook_address(hook_main, ba + 0x10e0)
        ql.run()
        del ql

        # test whether we interpected opening urandom
        self.assertListEqual(opened, [r'/dev/urandom'])
Exemplo n.º 20
0
 def test_pe_win_x86_return_from_main_exit_trap(self):
     ql = Qiling(["../examples/rootfs/x86_windows/bin/return_main.exe"],
                 "../examples/rootfs/x86_windows",
                 libcache=True,
                 stop_on_exit_trap=True)
     ql.run()
     del ql
Exemplo n.º 21
0
    def test_x86_fake_urandom(self):
        class Fake_urandom(QlFsMappedObject):
            def read(self, size):
                return b"\x01"

            def fstat(self):
                return -1

            def close(self):
                return 0

        ql = Qiling(["../examples/rootfs/x86_linux/bin/x86_fetch_urandom"],
                    "../examples/rootfs/x86_linux",
                    verbose=QL_VERBOSE.DEBUG)
        ql.add_fs_mapper("/dev/urandom", Fake_urandom())

        ql.exit_code = 0
        ql.exit_group_code = 0

        def check_exit_group_code(ql, exit_code, *args, **kw):
            ql.exit_group_code = exit_code

        def check_exit_code(ql, exit_code, *args, **kw):
            ql.exit_code = exit_code

        ql.set_syscall("exit_group", check_exit_group_code, QL_INTERCEPT.ENTER)
        ql.set_syscall("exit", check_exit_code, QL_INTERCEPT.ENTER)

        ql.run()
        self.assertEqual(0, ql.exit_code)
        self.assertEqual(0, ql.exit_group_code)
        del ql
Exemplo n.º 22
0
 def test_pe_win_x86_hello(self):
     ql = Qiling(["../examples/rootfs/x86_windows/bin/x86_hello.exe"],
                 "../examples/rootfs/x86_windows",
                 verbose=QL_VERBOSE.DEFAULT,
                 profile="profiles/append_test.ql")
     ql.run()
     del ql
Exemplo n.º 23
0
def emulate(path, rootfs, verbose=QL_VERBOSE.DEBUG, enable_trace=False):
    ql = Qiling([path], rootfs, verbose=verbose)

    if enable_trace:
        trace(ql)

    ql.run()
Exemplo n.º 24
0
    def test_elf_linux_mips32el_static(self):
        def random_generator(size=6, chars=string.ascii_uppercase + string.digits):
            return ''.join(random.choice(chars) for x in range(size))

        ql = Qiling(["../examples/rootfs/mips32el_linux/bin/mips32el_hello_static", random_generator(random.randint(1,99))], "../examples/rootfs/mips32el_linux")
        ql.run()
        del ql 
Exemplo n.º 25
0
 def _t():
     ql = Qiling(
         ["../examples/rootfs/x86_windows/bin/GetLastError.exe"],
         "../examples/rootfs/x86_windows")
     ql.run()
     del ql
     return True
Exemplo n.º 26
0
    def test_elf_linux_arm_custom_syscall(self):
        def my_syscall_write(ql, write_fd, write_buf, write_count, *args, **kw):
            regreturn = 0
            buf = None
            mapaddr = ql.mem.map_anywhere(0x100000)
            ql.log.info("0x%x" %  mapaddr)
            
            reg = ql.arch.regs.read("r0")
            print("reg : 0x%x" % reg)
            ql.arch.regs.r0 = reg
            
            
            try:
                buf = ql.mem.read(write_buf, write_count)
                ql.log.info("\n+++++++++\nmy write(%d,%x,%i) = %d\n+++++++++" % (write_fd, write_buf, write_count, regreturn))
                ql.os.fd[write_fd].write(buf)
                regreturn = write_count
            except:
                regreturn = -1
                ql.log.info("\n+++++++++\nmy write(%d,%x,%i) = %d\n+++++++++" % (write_fd, write_buf, write_count, regreturn))
                if ql.verbose >= QL_VERBOSE.DEBUG:
                    raise
            self.set_syscall = reg
            return regreturn

        ql = Qiling(["../examples/rootfs/arm_linux/bin/arm_hello"], "../examples/rootfs/arm_linux")
        ql.os.set_syscall(0x04, my_syscall_write)
        ql.run()
        
        self.assertEqual(1, self.set_syscall)
        
        del self.set_syscall
        del ql
Exemplo n.º 27
0
 def _t():
     ql = Qiling([
         "../examples/rootfs/x86_windows/bin/NtQuerySystemInformation.exe"
     ], "../examples/rootfs/x86_windows")
     ql.run()
     del ql
     return True
Exemplo n.º 28
0
 def test_tcp_elf_linux_mips32eb(self):
     ql = Qiling(
         ["../examples/rootfs/mips32_linux/bin/mips32_tcp_test", "20005"],
         "../examples/rootfs/mips32_linux",
         multithread=True)
     ql.run()
     del ql
Exemplo n.º 29
0
        def _t():
            if 'QL_FAST_TEST' in os.environ:
                return

            class Fake_Drive(QlFsMappedObject):
                def read(self, size):
                    return random.randint(0, 256)

                def write(self, bs):
                    print(bs)
                    return

                def fstat(self):
                    return -1

                def close(self):
                    return 0

            ql = Qiling(["../examples/rootfs/x86_windows/bin/UselessDisk.bin"],
                        "../examples/rootfs/x86_windows",
                        verbose=QL_VERBOSE.DEBUG)
            ql.add_fs_mapper(r"\\.\PHYSICALDRIVE0", Fake_Drive())
            ql.run()
            del ql
            return True
Exemplo n.º 30
0
        def hook_StartServiceA(ql: Qiling, address: int, params):
            hService = params["hService"]
            service_handle = ql.os.handle_manager.get(hService)
            ql.test_set_api = True
            if service_handle.name == "amsint32":
                if service_handle.name in ql.os.services:
                    service_path = ql.os.services[service_handle.name]
                    service_path = ql.os.path.transform_to_real_path(
                        service_path)
                    ql.amsint32_driver = Qiling([service_path],
                                                ql.rootfs,
                                                verbose=QL_VERBOSE.DISASM)
                    init_unseen_symbols(
                        ql.amsint32_driver,
                        ql.amsint32_driver.loader.dlls["ntoskrnl.exe"] +
                        0xb7695, b"NtTerminateProcess", 0, "ntoskrnl.exe")
                    print("load amsint32_driver")

                    try:
                        ql.amsint32_driver.run()
                        return 1
                    except UcError as e:
                        print("Load driver error: ", e)
                        return 0
                else:
                    return 0
            else:
                return 1