예제 #1
0
    def _query_handle(self, handle, klass, object_info_type):
        """Gets the object handle info.

        Parameters
        ----------


        handle: HANDLE
            handle object
        klass: int
            the class of information to query
        object_info_type: Structure
            structure type which holds the handle info
        """
        buff = malloc(self._object_buff_size)
        rlen = ULONG()
        status = nt_query_object(handle, klass, buff, self._object_buff_size,
                                 byref(rlen))
        if status >= 0:
            info = cast(buff, POINTER(object_info_type))
            self._buffers.append(buff)
            return info
        else:
            # reallocate the buffer size
            # and try again
            buff = realloc(buff, rlen.value)
            status = nt_query_object(handle, klass, buff,
                                     self._object_buff_size, None)
            if status >= 0:
                info = cast(buff, POINTER(object_info_type))
                self._buffers.append(buff)
                return info
            else:
                free(buff)
                return None
예제 #2
0
def read_process_memory(process, chunk, size):
    """Reads a memory block from the process address space.
    """
    buff = malloc(size)
    status = _read_process_memory(process, chunk, buff, size, None)
    if status != ERROR_SUCCESS:
        return buff
    else:
        free(buff)
예제 #3
0
파일: process.py 프로젝트: CaineQT/fibratus
def read_process_memory(process, chunk, size):
    """Reads a memory block from the process address space.
    """
    buff = malloc(size)
    status = _read_process_memory(process,
                                  chunk,
                                  buff,
                                  size,
                                  None)
    if status != ERROR_SUCCESS:
        return buff
    else:
        free(buff)
예제 #4
0
파일: handle.py 프로젝트: CaineQT/fibratus
    def _query_handle(self, handle, klass, object_info_type):
        """Gets the object handle info.

        Parameters
        ----------


        handle: HANDLE
            handle object
        klass: int
            the class of information to query
        object_info_type: Structure
            structure type which holds the handle info
        """
        buff = malloc(self._object_buff_size)
        rlen = ULONG()
        status = nt_query_object(handle,
                                 klass,
                                 buff,
                                 self._object_buff_size,
                                 byref(rlen))
        if status >= 0:
            info = cast(buff, POINTER(object_info_type))
            self._buffers.append(buff)
            return info
        else:
            # reallocate the buffer size
            # and try again
            buff = realloc(buff, rlen.value)
            status = nt_query_object(handle,
                                     klass,
                                     buff,
                                     self._object_buff_size,
                                     None)
            if status >= 0:
                info = cast(buff, POINTER(object_info_type))
                self._buffers.append(buff)
                return info
            else:
                free(buff)
                return None
예제 #5
0
파일: registry.py 프로젝트: cpluse/fibratus
    def _query_value(self, hkey, subkey, value_name):
        """Get value content and value type from registry.

        Parameters
        ----------

        hkey: HKEY
            handle to registry root key
        subkey: str
            path representing the subkey
        value:
            the name of the value
        """
        if not hkey:
            return NA, NA
        value_type = c_ulong()
        buff = malloc(MAX_BUFFER_SIZE)
        buff_size = c_ulong(MAX_BUFFER_SIZE)

        status = reg_get_value(hkey, c_wchar_p(subkey),
                               c_wchar_p(value_name),
                               RRF_RT_ANY,
                               byref(value_type),
                               buff, byref(buff_size))
        if status == ERROR_SUCCESS:
            value = cast(buff, c_wchar_p).value
            value_type = value_type.value
            if value_type in self._reg_value_types:
                if value_type == ValueType.REG_BINARY.value:
                    value = '<binary>'
                [value_type] = [v.name for v in ValueType if v.value == value_type]
            else:
                value_type = ValueType.REG_NONE.name
            free(buff)
            return value, value_type
        else:
            free(buff)
            return NA, NA
예제 #6
0
파일: registry.py 프로젝트: mycyty/fibratus
    def _query_value(self, hkey, subkey, value_name):
        """Get value content and value type from registry.

        Parameters
        ----------

        hkey: HKEY
            handle to registry root key
        subkey: str
            path representing the subkey
        value:
            the name of the value
        """
        if not hkey:
            return NA, NA
        value_type = c_ulong()
        buff = malloc(MAX_BUFFER_SIZE)
        buff_size = c_ulong(MAX_BUFFER_SIZE)

        status = reg_get_value(hkey, c_wchar_p(subkey), c_wchar_p(value_name),
                               RRF_RT_ANY, byref(value_type), buff,
                               byref(buff_size))
        if status == ERROR_SUCCESS:
            value = cast(buff, c_wchar_p).value
            value_type = value_type.value
            if value_type in self._reg_value_types:
                if value_type == ValueType.REG_BINARY.value:
                    value = '<binary>'
                [value_type
                 ] = [v.name for v in ValueType if v.value == value_type]
            else:
                value_type = ValueType.REG_NONE.name
            free(buff)
            return value, value_type
        else:
            free(buff)
            return NA, NA
예제 #7
0
    def _query_process_info(self, handle, read_peb=True):
        """Gets an extended proc info.

        Parameters
        -----------

        handle: HANDLE
            handle to process for which the info
            should be acquired
        read_peb: boolean
            true in case the process PEB should be read

        """
        pbi_buff = malloc(sizeof(PROCESS_BASIC_INFORMATION))
        status = zw_query_information_process(handle,
                                              PROCESS_BASIC_INFO,
                                              pbi_buff,
                                              sizeof(PROCESS_BASIC_INFORMATION),
                                              byref(ULONG()))

        info = {}

        if status == STATUS_SUCCESS:
            pbi = cast(pbi_buff, POINTER(PROCESS_BASIC_INFORMATION))
            ppid = pbi.contents.inherited_from_unique_process_id
            if read_peb:
                # read the PEB to get the process parameters.
                # Because the PEB structure resides
                # in the address space of another process
                # we must read the memory block in order
                # to access the structure's fields
                peb_addr = pbi.contents.peb_base_address
                peb_buff = read_process_memory(handle, peb_addr, sizeof(PEB))
                if peb_buff:
                    peb = cast(peb_buff, POINTER(PEB))
                    # read the RTL_USER_PROCESS_PARAMETERS struct
                    # which contains the command line and the image
                    # name of the process
                    pp = peb.contents.process_parameters
                    pp_buff = read_process_memory(handle,
                                                  pp,
                                                  sizeof(RTL_USER_PROCESS_PARAMETERS))
                    if pp_buff:
                        pp = cast(pp_buff, POINTER(RTL_USER_PROCESS_PARAMETERS))

                        comm = pp.contents.command_line.buffer
                        comm_len = pp.contents.command_line.length
                        exe = pp.contents.image_path_name.buffer
                        exe_len = pp.contents.image_path_name.length

                        # these memory reads are required
                        # to copy the command line and image name buffers
                        cb = read_process_memory(handle, comm, comm_len)
                        eb = read_process_memory(handle, exe, exe_len)

                        if cb and eb:
                            # cast the buffers to
                            # UNICODE strings
                            comm = cast(cb, c_wchar_p).value
                            exe = cast(eb, c_wchar_p).value

                            # the image name contains the full path
                            # split the string to get the exec name
                            name = exe[exe.rfind('\\') + 1:]
                            info = ddict(name=name,
                                         comm=comm,
                                         parent_pid=ppid)
                            free(cb)
                            free(eb)
                        free(pp_buff)

                    free(peb_buff)
            else:
                # query only the process image file name
                exe = ctypes.create_unicode_buffer(MAX_PATH)
                size = DWORD(MAX_PATH)
                name = None
                status = query_full_process_image_name(handle,
                                                       0,
                                                       exe,
                                                       byref(size))
                if status:
                    exe = exe.value
                    name = exe[exe.rfind('\\') + 1:]
                info = ddict(name=name if name else NA,
                             comm=exe if type(exe) is str else None,
                             parent_pid=ppid)
        if pbi_buff:
            free(pbi_buff)

        return info
예제 #8
0
    def _enum_handles(self, process_id=None):
        """Enumerates handle information.

        Enumerates handle info on
        the start of the kernel capture.

        Returns a dictionary of handle's
        information including the handle id,
        access mask, and the process which owns
        the handle.
        """
        buff_size = MAX_BUFFER_SIZE
        size = c_ulong()
        # allocate the initial buffer
        buff = malloc(buff_size)
        handles = {}

        while True:
            status = zw_query_system_information(
                SYSTEM_HANDLE_INFORMATION_CLASS, buff, buff_size, byref(size))
            if status == STATUS_INFO_LENGTH_MISMATCH:
                # the buffer is too small
                # increment the buffer size and try again
                buff_size += MAX_BUFFER_SIZE
            elif status == STATUS_SUCCESS:
                # cast the buffer to `SYSTEM_HANDLE_INFORMATION` struct
                # which contains an array of `SYSTEM_HANDLE` structures
                sys_handle_info = cast(buff,
                                       POINTER(SYSTEM_HANDLE_INFORMATION))
                sys_handle_info = sys_handle_info.contents
                handle_count = sys_handle_info.number_of_handles

                # resize the array size to the
                # actual number of file handles
                sys_handles = (SYSTEM_HANDLE * buff_size).from_address(
                    addressof(sys_handle_info.handles))

                for i in range(handle_count):
                    sys_handle = sys_handles[i]
                    pid = sys_handle.process_id
                    handle = sys_handle.handle
                    obj = sys_handle.object
                    obj_type_index = sys_handle.object_type_number
                    access_mask = sys_handle.access_mask
                    if process_id and process_id == pid:
                        handles[obj] = ddict(pid=process_id,
                                             handle=handle,
                                             obj=obj,
                                             access_mask=access_mask,
                                             obj_type_index=obj_type_index)
                    elif process_id is None:
                        handles[obj] = ddict(pid=pid,
                                             handle=handle,
                                             obj=obj,
                                             access_mask=access_mask,
                                             obj_type_index=obj_type_index)
                break
            else:
                raise HandleEnumError(status)
            # reallocate the buffer
            buff = realloc(buff, buff_size)
        # free the buffer memory
        free(buff)

        return handles
예제 #9
0
 def free_buffers(self):
     for buff in self._buffers:
         free(buff)
예제 #10
0
파일: thread.py 프로젝트: wwebb-r7/fibratus
    def _query_process_info(self, handle, read_peb=True):
        """Gets an extended proc info.

        Parameters
        -----------

        handle: HANDLE
            handle to process for which the info
            should be acquired
        read_peb: boolean
            true in case the process PEB should be read

        """
        pbi_buff = malloc(sizeof(PROCESS_BASIC_INFORMATION))
        status = zw_query_information_process(
            handle, PROCESS_BASIC_INFO, pbi_buff,
            sizeof(PROCESS_BASIC_INFORMATION), byref(ULONG()))

        info = {}

        if status == STATUS_SUCCESS:
            pbi = cast(pbi_buff, POINTER(PROCESS_BASIC_INFORMATION))
            ppid = pbi.contents.inherited_from_unique_process_id
            if read_peb:
                # read the PEB to get the process parameters.
                # Because the PEB structure resides
                # in the address space of another process
                # we must read the memory block in order
                # to access the structure's fields
                peb_addr = pbi.contents.peb_base_address
                peb_buff = read_process_memory(handle, peb_addr, sizeof(PEB))
                if peb_buff:
                    peb = cast(peb_buff, POINTER(PEB))
                    # read the RTL_USER_PROCESS_PARAMETERS struct
                    # which contains the command line and the image
                    # name of the process
                    pp = peb.contents.process_parameters
                    pp_buff = read_process_memory(
                        handle, pp, sizeof(RTL_USER_PROCESS_PARAMETERS))
                    if pp_buff:
                        pp = cast(pp_buff,
                                  POINTER(RTL_USER_PROCESS_PARAMETERS))

                        comm = pp.contents.command_line.buffer
                        comm_len = pp.contents.command_line.length
                        exe = pp.contents.image_path_name.buffer
                        exe_len = pp.contents.image_path_name.length

                        # these memory reads are required
                        # to copy the command line and image name buffers
                        cb = read_process_memory(handle, comm, comm_len)
                        eb = read_process_memory(handle, exe, exe_len)

                        if cb and eb:
                            # cast the buffers to
                            # UNICODE strings
                            comm = cast(cb, c_wchar_p).value
                            exe = cast(eb, c_wchar_p).value

                            # the image name contains the full path
                            # split the string to get the exec name
                            name = exe[exe.rfind('\\') + 1:]
                            info = ddict(name=name, comm=comm, parent_pid=ppid)
                            free(cb)
                            free(eb)
                        free(pp_buff)

                    free(peb_buff)
            else:
                # query only the process image file name
                exe = ctypes.create_unicode_buffer(MAX_PATH)
                size = DWORD(MAX_PATH)
                name = None
                status = query_full_process_image_name(handle, 0, exe,
                                                       byref(size))
                if status:
                    exe = exe.value
                    name = exe[exe.rfind('\\') + 1:]
                info = ddict(name=name if name else NA,
                             comm=exe,
                             parent_pid=ppid)
        if pbi_buff:
            free(pbi_buff)

        return info
예제 #11
0
파일: handle.py 프로젝트: CaineQT/fibratus
    def _enum_handles(self, process_id=None):
        """Enumerates handle information.

        Enumerates handle info on
        the start of the kernel capture.

        Returns a dictionary of handle's
        information including the handle id,
        access mask, and the process which owns
        the handle.
        """
        buff_size = MAX_BUFFER_SIZE
        size = c_ulong()
        # allocate the initial buffer
        buff = malloc(buff_size)
        handles = {}

        while True:
            status = zw_query_system_information(SYSTEM_HANDLE_INFORMATION_CLASS,
                                                 buff,
                                                 buff_size,
                                                 byref(size))
            if status == STATUS_INFO_LENGTH_MISMATCH:
                # the buffer is too small
                # increment the buffer size and try again
                buff_size += MAX_BUFFER_SIZE
            elif status == STATUS_SUCCESS:
                # cast the buffer to `SYSTEM_HANDLE_INFORMATION` struct
                # which contains an array of `SYSTEM_HANDLE` structures
                sys_handle_info = cast(buff, POINTER(SYSTEM_HANDLE_INFORMATION))
                sys_handle_info = sys_handle_info.contents
                handle_count = sys_handle_info.number_of_handles

                # resize the array size to the
                # actual number of file handles
                sys_handles = (SYSTEM_HANDLE * buff_size).from_address(addressof(sys_handle_info.handles))

                for i in range(handle_count):
                    sys_handle = sys_handles[i]
                    pid = sys_handle.process_id
                    handle = sys_handle.handle
                    obj = sys_handle.object
                    obj_type_index = sys_handle.object_type_number
                    access_mask = sys_handle.access_mask
                    if process_id and process_id == pid:
                        handles[obj] = ddict(pid=process_id,
                                             handle=handle,
                                             obj=obj,
                                             access_mask=access_mask,
                                             obj_type_index=obj_type_index)
                    elif process_id is None:
                        handles[obj] = ddict(pid=pid,
                                             handle=handle,
                                             obj=obj,
                                             access_mask=access_mask,
                                             obj_type_index=obj_type_index)
                break
            else:
                raise HandleEnumError(status)
            # reallocate the buffer
            buff = realloc(buff, buff_size)
        # free the buffer memory
        free(buff)

        return handles
예제 #12
0
파일: handle.py 프로젝트: CaineQT/fibratus
 def free_buffers(self):
     for buff in self._buffers:
         free(buff)