Example #1
0
def hook_TerminateProcess(ql: Qiling, address: int, params):
    # Samples will try to kill other process! We don't want to always stop!
    process = params["hProcess"]

    if process == ql.os.profile.getint(
            "KERNEL", "pid"):  # or process == ql.os.image_address:
        ql.emu_stop()
        ql.os.PE_RUN = False

    return 1
Example #2
0
def ql_syscall_execve(ql: Qiling, pathname: int, argv: int, envp: int):
    file_path = ql.os.utils.read_cstring(pathname)
    real_path = ql.os.path.transform_to_real_path(file_path)

    def __read_str_array(addr: int) -> Iterator[str]:
        if addr:
            while True:
                elem = ql.mem.read_ptr(addr)

                if elem == 0:
                    break

                yield ql.os.utils.read_cstring(elem)
                addr += ql.arch.pointersize

    args = [s for s in __read_str_array(argv)]

    env = {}
    for s in __read_str_array(envp):
        k, _, v = s.partition('=')
        env[k] = v

    ql.emu_stop()

    ql.log.debug(
        f'execve({file_path}, [{", ".join(args)}], [{", ".join(f"{k}={v}" for k, v in env.items())}])'
    )

    ql.loader.argv = args
    ql.loader.env = env
    ql._path = real_path
    ql.mem.map_info = []
    ql.clear_ql_hooks()

    # Clean debugger to prevent port conflicts
    # ql.debugger = None

    if ql.code:
        return

    # recreate cached uc
    del ql.arch.uc
    uc = ql.arch.uc

    # propagate new uc to arch internals
    ql.arch.regs.uc = uc

    if hasattr(ql.arch, 'msr'):
        ql.arch.msr.uc = uc

    QlCoreHooks.__init__(ql, uc)

    ql.os.load()
    ql.loader.run()
    ql.run()
Example #3
0
def __leaf_53(ql: Qiling):
    al = ql.arch.regs.al

    if al == 0x01:
        ql.os.clear_cf()
    elif al == 0x0e:
        ql.arch.regs.ax = 0x0102
        ql.os.clear_cf()
    elif al == 0x07:
        if (ql.arch.regs.bx == 1) and (ql.arch.regs.cx == 3):
            ql.log.info("Emulation Stop")
            ql.emu_stop()
    else:
        raise NotImplementedError()
Example #4
0
def ql_syscall_futex(ql: Qiling, uaddr: int, op: int, val: int, timeout: int,
                     uaddr2: int, val3: int):
    FUTEX_WAIT = 0
    FUTEX_WAKE = 1
    FUTEX_FD = 2
    FUTEX_REQUEUE = 3
    FUTEX_CMP_REQUEUE = 4
    FUTEX_WAKE_OP = 5
    FUTEX_LOCK_PI = 6
    FUTEX_UNLOCK_PI = 7
    FUTEX_TRYLOCK_PI = 8
    FUTEX_WAIT_BITSET = 9
    FUTEX_WAKE_BITSET = 10
    FUTEX_WAIT_REQUEUE_PI = 11
    FUTEX_CMP_REQUEUE_PI = 12
    FUTEX_PRIVATE_FLAG = 128

    if op & (FUTEX_PRIVATE_FLAG - 1) == FUTEX_WAIT:
        # def futex_wait_addr(ql, th, arg):
        #     addr, val = arg
        #     return ql.unpack32(ql.mem.read(addr, 4)) == val

        regreturn = ql.os.futexm.futex_wait(ql, uaddr,
                                            ql.os.thread_management.cur_thread,
                                            val)

    elif op & (FUTEX_PRIVATE_FLAG - 1) == FUTEX_WAIT_BITSET:
        regreturn = ql.os.futexm.futex_wait(ql, uaddr,
                                            ql.os.thread_management.cur_thread,
                                            val, val3)

    elif op & (FUTEX_PRIVATE_FLAG - 1) == FUTEX_WAKE:
        regreturn = ql.os.futexm.futex_wake(ql, uaddr,
                                            ql.os.thread_management.cur_thread,
                                            val)

    elif op & (FUTEX_PRIVATE_FLAG - 1) == FUTEX_WAKE_BITSET:
        regreturn = ql.os.futexm.futex_wake(ql, uaddr,
                                            ql.os.thread_management.cur_thread,
                                            val, val3)

    else:
        ql.log.debug(f'futex({uaddr:x}, {op:d}, {val:d}) = ?')
        ql.emu_stop()
        #ql.os.thread_management.cur_thread.stop()
        #ql.os.thread_management.cur_thread.stop_event = THREAD_EVENT_EXIT_GROUP_EVENT
        regreturn = 0

    return regreturn
Example #5
0
def ql_syscall_exit_group(ql: Qiling, code: int):
    if ql.os.child_processes == True:
        os._exit(0)

    if ql.multithread:
        def _sched_cb_exit(cur_thread):
            ql.log.debug(f"[Thread {cur_thread.get_id()}] Terminated")
            cur_thread.stop()
            cur_thread.exit_code = code

        td = ql.os.thread_management.cur_thread
        ql.emu_stop()
        td.sched_cb = _sched_cb_exit
    else:
        ql.os.exit_code = code
        ql.os.stop()
Example #6
0
def __sleep_common(ql: Qiling, req: int, rem: int) -> int:
    n = ql.pointersize

    tv_sec = ql.unpack(ql.mem.read(req, n))
    tv_sec += ql.unpack(ql.mem.read(req + n, n)) / 1000000000

    if ql.os.thread_management:
        def _sched_sleep(cur_thread):
            gevent.sleep(tv_sec)

        ql.emu_stop()
        ql.os.thread_management.cur_thread.sched_cb = _sched_sleep

        # FIXME: this seems to be incomplete
        th = ql.os.thread_management.cur_thread
    else:
        time.sleep(tv_sec)

    return 0
Example #7
0
def ql_syscall_vfork(ql: Qiling):
    if ql.host.os == QL_OS.WINDOWS:
        try:
            pid = Process()
            pid = 0
        except:
            pid = -1
    else:
        pid = os.fork()

    if pid == 0:
        ql.os.child_processes = True
        ql.log.debug("vfork(): is this a child process: %r" % (ql.os.child_processes))
        regreturn = 0
    else:
        regreturn = pid

    if ql.os.thread_management:
        ql.emu_stop()

    return regreturn
Example #8
0
def __sleep_common(ql: Qiling,
                   req: int,
                   rem: int,
                   force_timespec64: bool = False) -> int:
    tv_sec_size = 8 if force_timespec64 else ql.arch.pointersize
    tv_nsec_size = ql.arch.pointersize

    # struct timespec {
    #     long      tv_sec;
    #     long      tv_nsec;
    # };
    # struct timespec64 {
    #     time64_t  tv_sec;
    #     long      tv_nsec;
    # };

    tv_sec = ql.unpack64(ql.mem.read(
        req, tv_sec_size)) if force_timespec64 else ql.unpack(
            ql.mem.read(req, tv_sec_size))

    tv_sec += ql.unpack(ql.mem.read(req + tv_sec_size,
                                    tv_nsec_size)) / 1000000000

    if ql.os.thread_management:

        def _sched_sleep(cur_thread):
            gevent.sleep(tv_sec)

        ql.emu_stop()
        ql.os.thread_management.cur_thread.sched_cb = _sched_sleep

        # FIXME: this seems to be incomplete
        th = ql.os.thread_management.cur_thread
    else:
        time.sleep(tv_sec)

    return 0
Example #9
0
            def stop(ql: Qiling):
                ql.log.info("Ok for now")

                ql.emu_stop()
def stopatkillerswtich(ql: Qiling):
    print(f'killerswtch found')
    ql.emu_stop()
Example #11
0
def ql_syscall_clone(ql: Qiling, flags: int, child_stack: int, parent_tidptr: int, newtls: int, child_tidptr: int):
    CSIGNAL              = 0x000000ff
    CLONE_VM             = 0x00000100
    CLONE_FS             = 0x00000200
    CLONE_FILES          = 0x00000400
    CLONE_SIGHAND        = 0x00000800
    CLONE_PIDFD          = 0x00001000
    CLONE_PTRACE         = 0x00002000
    CLONE_VFORK          = 0x00004000
    CLONE_PARENT         = 0x00008000
    CLONE_THREAD         = 0x00010000
    CLONE_NEWNS          = 0x00020000
    CLONE_SYSVSEM        = 0x00040000
    CLONE_SETTLS         = 0x00080000
    CLONE_PARENT_SETTID  = 0x00100000
    CLONE_CHILD_CLEARTID = 0x00200000
    CLONE_DETACHED       = 0x00400000
    CLONE_UNTRACED       = 0x00800000
    CLONE_CHILD_SETTID   = 0x01000000
    CLONE_NEWCGROUP      = 0x02000000
    CLONE_NEWUTS         = 0x04000000
    CLONE_NEWIPC         = 0x08000000
    CLONE_NEWUSER        = 0x10000000
    CLONE_NEWPID         = 0x20000000
    CLONE_NEWNET         = 0x40000000
    CLONE_IO             = 0x80000000

    # X8664 flags, child_stack, parent_tidptr, child_tidptr, newtls
    if ql.archtype== QL_ARCH.X8664:
        ori_newtls = child_tidptr
        child_tidptr = newtls
        newtls = ori_newtls

    f_th = ql.os.thread_management.cur_thread
    set_child_tid_addr = None

    # Shared virtual memory
    if not (flags & CLONE_VM):
        # FIXME: need a proper os.fork() for Windows
        if ql.platform == QL_OS.WINDOWS:
            try:
                pid = Process()
                pid = 0
            except:
                pid = -1
        else:
            pid = os.fork()

        if pid == 0:
            ql.os.child_processes = True

            f_th.update_global_thread_id()
            f_th.new_thread_id()

            if flags & CLONE_SETTLS == CLONE_SETTLS:
                f_th.set_thread_tls(newtls)

            if flags & CLONE_CHILD_CLEARTID == CLONE_CHILD_CLEARTID:
                f_th.set_clear_child_tid_addr(child_tidptr)

            if child_stack != 0:
                ql.arch.set_sp(child_stack)

        # ql.log.debug(f'clone(new_stack = {child_stack:#x}, flags = {flags:#x}, tls = {newtls:#x}, ptidptr = {parent_tidptr:#x}, ctidptr = {child_tidptr:#x}) = {regreturn:d}')
        ql.emu_stop()

        return pid

    if flags & CLONE_CHILD_SETTID == CLONE_CHILD_SETTID:
        set_child_tid_addr = child_tidptr

    th = ql.os.thread_class.spawn(ql, ql.reg.arch_pc + 2, ql.os.exit_point, set_child_tid_addr = set_child_tid_addr)
    th.path = f_th.path
    ql.log.debug(f'{str(th)} created')

    if flags & CLONE_PARENT_SETTID == CLONE_PARENT_SETTID:
        ql.mem.write(parent_tidptr, ql.pack32(th.id))

    ctx = ql.save(reg=True, mem=False)
    # Whether to set a new tls
    if flags & CLONE_SETTLS == CLONE_SETTLS:
        ql.log.debug(f"new_tls={newtls:#x}")
        th.set_thread_tls(newtls)

    if flags & CLONE_CHILD_CLEARTID == CLONE_CHILD_CLEARTID:
        th.set_clear_child_tid_addr(child_tidptr)

    # Set the stack and return value of the new thread
    # (the return value of the child thread is 0, and the return value of the parent thread is the tid of the child thread)
    # and save the current context.
    regreturn = 0
    ql.reg.arch_sp = child_stack

    # We have to find next pc manually for some archs since the pc is current instruction (like `syscall`).
    if ql.archtype in (QL_ARCH.X8664, ):
        ql.reg.arch_pc += list(ql.disassembler.disasm_lite(bytes(ql.mem.read(ql.reg.arch_pc, 4)), ql.reg.arch_pc))[0][1]
        ql.log.debug(f"Fix pc for child thread to {hex(ql.reg.arch_pc)}")

    ql.os.set_syscall_return(0)
    th.save()

    if th is None or f_th is None:
        raise Exception()

    ql.log.debug(f'Currently running pid is: {os.getpid():d}; tid is: {ql.os.thread_management.cur_thread.id:d}')
    # ql.log.debug(f'clone(new_stack = {child_stack:#x}, flags = {flags:#x}, tls = {newtls:#x}, ptidptr = {parent_tidptr:#x}, ctidptr = {child_tidptr:#x}) = {regreturn:d}')

    # Restore the stack and return value of the parent process
    ql.restore(ctx)
    regreturn = th.id

    # Break the parent process and enter the add new thread event
    ql.emu_stop()
    f_th.stop_event = THREAD_EVENT_CREATE_THREAD
    f_th.stop_return_val = th

    ql.log.debug(f'Currently running pid is: {os.getpid():d}; tid is: {ql.os.thread_management.cur_thread.id:d}')
    # ql.log.debug(f'clone(new_stack = {child_stack:#x}, flags = {flags:#x}, tls = {newtls:#x}, ptidptr = {parent_tidptr:#x}, ctidptr = {child_tidptr:#x}) = {regreturn:d}')

    return regreturn
Example #12
0
def hook_ResetSystem(ql: Qiling, address: int, params):
    ql.emu_stop()

    return EFI_SUCCESS
Example #13
0
 def hook_third_stop_address(ql: Qiling, stops: List[bool]):
     ql.log.info(
         f' >>>> Third stop address: {ql.arch.regs.arch_pc:#010x}')
     stops[2] = True
     ql.emu_stop()
Example #14
0
def hook_ExitProcess(ql: Qiling, address: int, params):
    ql.emu_stop()
    ql.os.PE_RUN = False
Example #15
0
def stop(ql: Qiling, addr, data):
    ql.emu_stop()
Example #16
0
def __leaf_4c(ql: Qiling):
    ql.log.info("Program terminated gracefully")
    ql.emu_stop()
Example #17
0
def hook_FatalExit(ql: Qiling, address: int, params):
    ql.emu_stop()
    ql.os.PE_RUN = False
Example #18
0
 def hook_first_stop_address(ql: Qiling, stops: List[bool]):
     ql.log.info(
         f' >>>> First stop address: {ql.arch.regs.arch_pc:#010x}')
     stops[0] = True
     ql.emu_stop()