Beispiel #1
0
def hook_CreateThread(ql: Qiling, address: int, params):
    CREATE_SUSPENDED = 0x00000004

    lpThreadAttributes = params["lpThreadAttributes"]
    dwStackSize = params["dwStackSize"]
    lpStartAddress = params["lpStartAddress"]
    lpParameter = params["lpParameter"]
    dwCreationFlags = params["dwCreationFlags"]
    lpThreadId = params["lpThreadId"]

    # new thread obj
    new_thread = QlWindowsThread(ql)

    if dwCreationFlags & CREATE_SUSPENDED == CREATE_SUSPENDED:
        thread_status = QlWindowsThread.READY
    else:
        thread_status = QlWindowsThread.RUNNING

    # create new thread
    thread_id = new_thread.create(lpStartAddress, lpParameter, thread_status)

    # append the new thread to ThreadManager
    ql.os.thread_manager.append(new_thread)

    # create thread handle
    new_handle = Handle(obj=new_thread)
    ql.os.handle_manager.append(new_handle)

    # set lpThreadId
    # FIXME: Temporary fix for the crash
    # if lpThreadId != 0:
    # ql.mem.write_ptr(lpThreadId, thread_id)

    # set thread handle
    return new_handle.id
Beispiel #2
0
def setup(ql):
    ql.heap = Heap(ql, ql.commos.HEAP_BASE_ADDR,
                   ql.commos.HEAP_BASE_ADDR + ql.commos.HEAP_SIZE)
    ql.hook_mem_unmapped(ql_x86_windows_hook_mem_error)

    # setup gdt
    if ql.arch == QL_X86:
        ql_x86_setup_gdt_segment_fs(ql, FS_SEGMENT_ADDR, FS_SEGMENT_SIZE)
        ql_x86_setup_gdt_segment_gs(ql, GS_SEGMENT_ADDR, GS_SEGMENT_SIZE)
        ql_x86_setup_gdt_segment_ds(ql)
        ql_x86_setup_gdt_segment_cs(ql)
        ql_x86_setup_gdt_segment_ss(ql)
    elif ql.arch == QL_X8664:
        ql_x8664_set_gs(ql)

    # handle manager
    ql.handle_manager = HandleManager()
    # registry manger
    ql.registry_manager = RegistryManager(ql)
    # clipboard
    ql.clipboard = Clipboard(ql)
    # fibers
    ql.fiber_manager = FiberManager(ql)
    # Place to set errors for retrieval by GetLastError()
    # thread manager
    main_thread = Thread(ql)
    ql.thread_manager = ThreadManager(ql, main_thread)
    new_handle = Handle(thread=main_thread)
    ql.handle_manager.append(new_handle)
    # user configuration
    ql.config = ql_init_configuration(ql)
    # variables used inside hooks
    ql.hooks_variables = {}
Beispiel #3
0
def __CreateEvent(ql: Qiling, address: int, params):
    # Implementation seems similar enough to Mutex to just use it

    try:
        namespace, name = params["lpName"].split("\\")
    except ValueError:
        name = params["lpName"]
        namespace = ""

    handle = ql.os.handle_manager.search(name)

    if handle is not None:
        ql.os.last_error = ERROR_ALREADY_EXISTS
        # FIXME: fail with a nullptr?
        # return 0
    else:
        mutex = Mutex(name, namespace)

        if params['bInitialState']:
            mutex.lock()

        handle = Handle(obj=mutex, name=name)
        ql.os.handle_manager.append(handle)

    # FIXME: shouldn't it be 'id' instead of 'ID'?
    return handle.ID
Beispiel #4
0
def _CreateFile(ql: Qiling, address: int, params):
    s_lpFileName = params["lpFileName"]
    dwDesiredAccess = params["dwDesiredAccess"]
    # dwShareMode = params["dwShareMode"]
    # lpSecurityAttributes = params["lpSecurityAttributes"]
    # dwCreationDisposition = params["dwCreationDisposition"]
    # dwFlagsAndAttributes = params["dwFlagsAndAttributes"]
    # hTemplateFile = params["hTemplateFile"]

    # access mask DesiredAccess
    mode = ""
    if dwDesiredAccess & GENERIC_WRITE:
        mode += "wb"
    else:
        mode += "rb"

    try:
        f = ql.os.fs_mapper.open(s_lpFileName, mode)
    except FileNotFoundError:
        ql.os.last_error = ERROR_FILE_NOT_FOUND
        return INVALID_HANDLE_VALUE

    new_handle = Handle(obj=f)
    ql.os.handle_manager.append(new_handle)

    return new_handle.id
Beispiel #5
0
def hook_MapViewOfFile(ql: Qiling, address: int, params):
    hFileMappingObject = params['hFileMappingObject']
    dwFileOffsetLow = params['dwFileOffsetLow']
    dwNumberOfBytesToMap = params['dwNumberOfBytesToMap']

    map_file_handle = ql.os.handle_manager.search_by_obj(hFileMappingObject)

    if map_file_handle is None:
        ret = ql.os.heap.alloc(dwNumberOfBytesToMap)
        new_handle = Handle(obj=hFileMappingObject, name=ret)
        ql.os.handle_manager.append(new_handle)
    else:
        ret = map_file_handle.name

    hFile = ql.os.handle_manager.get(hFileMappingObject).obj

    if ql.os.handle_manager.get(hFile):
        f = ql.os.handle_manager.get(hFile).obj

        if type(f) is file:
            f.seek(dwFileOffsetLow, 0)
            data = f.read(dwNumberOfBytesToMap)
            ql.mem.write(ret, data)

    return ret
Beispiel #6
0
def hook_InitializeSListHead(ql: Qiling, address: int, params):
    ListHead = params["ListHead"]

    handle = Handle(obj=[], id=ListHead)
    ql.os.handle_manager.append(handle)

    return 0
Beispiel #7
0
def _CreateFileMapping(ql: Qiling, address: int, params):
    hFile = params['hFile']
    lpName = params['lpName']

    new_handle = Handle(obj=hFile, name=lpName)
    ql.os.handle_manager.append(new_handle)

    return new_handle.id
Beispiel #8
0
def hook_FindFirstFileA(ql: Qiling, address: int, params):
    filename = params['lpFileName']
    pointer = params['lpFindFileData']

    if filename == 0:
        return INVALID_HANDLE_VALUE
    elif len(filename) >= MAX_PATH:
        return ERROR_INVALID_PARAMETER

    target_dir = os.path.join(ql.rootfs, filename.replace("\\", os.sep))
    ql.log.info('TARGET_DIR = %s' % target_dir)
    real_path = ql.os.path.transform_to_real_path(filename)

    # Verify the directory is in ql.rootfs to ensure no path traversal has taken place
    if not os.path.exists(real_path):
        ql.os.last_error = ERROR_FILE_NOT_FOUND
        return INVALID_HANDLE_VALUE

    # Check if path exists
    filesize = 0
    try:
        f = ql.os.fs_mapper.open(real_path, "r")
        filesize = os.path.getsize(real_path)
    except FileNotFoundError:
        ql.os.last_error = ERROR_FILE_NOT_FOUND
        return INVALID_HANDLE_VALUE

    # Get size of the file
    file_size_low = filesize & 0xffffff
    file_size_high = filesize >> 32

    # Create a handle for the path
    new_handle = Handle(obj=f)
    ql.os.handle_manager.append(new_handle)

    # Spoof filetime values
    filetime = ql.pack64(datetime.now().microsecond)

    find_data = Win32FindData(
        ql,
        FILE_ATTRIBUTE_NORMAL,
        filetime,
        filetime,
        filetime,
        file_size_high,
        file_size_low,
        0,
        0,
        filename,
        0,
        0,
        0,
        0,
    )

    find_data.write(pointer)

    return new_handle.id
Beispiel #9
0
def hook__wfopen_s(ql: Qiling, address: int, params):
    dst = params["pFile"]
    filename = params["filename"]
    mode = params["mode"]
    f = ql.os.fs_mapper.open(filename, mode)
    new_handle = Handle(obj=f)
    ql.os.handle_manager.append(new_handle)
    ql.mem.write(dst, ql.pack(new_handle.id))
    return 1
Beispiel #10
0
def hook_OpenThreadToken(ql: Qiling, address: int, params):
    token_pointer = params["TokenHandle"]

    token = Token(ql)
    new_handle = Handle(obj=token)

    ql.os.handle_manager.append(new_handle)
    ql.mem.write_ptr(token_pointer, new_handle.id)

    return 1
Beispiel #11
0
def hook_OpenProcessToken(ql: Qiling, address: int, params):
    token_pointer = params["TokenHandle"]

    token = Token(ql)
    new_handle = Handle(obj=token)

    ql.os.handle_manager.append(new_handle)
    ql.mem.write(token_pointer, ql.pack(new_handle.id))

    return 1
Beispiel #12
0
def _ShellExecute(ql: Qiling, obj: ShellExecuteInfoA):
    def __wstr(shellex: Sequence):
        return ql.os.utils.read_wstring(shellex[0]) if shellex[0] else ''

    ql.log.debug(f'Target executed a shell command!')
    ql.log.debug(f' | Operation  : "{__wstr(obj.verb)}"')
    ql.log.debug(f' | Parameters : "{__wstr(obj.params)}"')
    ql.log.debug(f' | File       : "{__wstr(obj.file)}"')
    ql.log.debug(f' | Directory  : "{__wstr(obj.dir)}"')

    if obj.show[0] == SW_HIDE:
        ql.log.debug(" | With an hidden window")

    process = QlWindowsThread(ql, status=0, isFake=True)
    handle = Handle(obj=process)
    ql.os.handle_manager.append(handle)

    return handle
Beispiel #13
0
def __CreateMutex(ql: Qiling, address: int, params):
    try:
        _type, name = params["lpName"].split("\\")
    except ValueError:
        name = params["lpName"]
        _type = ""

    handle = ql.os.handle_manager.search(name)

    if handle is not None:
        # ql.os.last_error = ERROR_ALREADY_EXISTS
        return 0

    owning = params["bInitialOwner"]
    mutex = Mutex(name, _type)

    if owning:
        mutex.lock()

    handle = Handle(obj=mutex, name=name)
    ql.os.handle_manager.append(handle)

    return handle.id
Beispiel #14
0
def hook_GetConsoleWindow(ql: Qiling, address: int, params):
    handle = Handle(name="console_window")
    ql.os.handle_manager.append(handle)

    return handle.id