Beispiel #1
0
    def from_bytes(cls, data: bytes) -> ROpenSCManagerWRequest:
        machine_name = ConformantVaryingString.from_bytes(data=Pointer.from_bytes(data=data).representation)
        machine_name_len: int = len(machine_name)
        offset = Pointer.structure_size + machine_name_len + ((4 - (machine_name_len % 4)) % 4)

        database_name = ConformantVaryingString.from_bytes(data=Pointer.from_bytes(data=data[offset:]).representation)
        database_name_len: int = len(database_name)
        offset += Pointer.structure_size + database_name_len + ((4 - (database_name_len % 4)) % 4)

        return cls(
            machine_name=machine_name.representation,
            desired_access=SCManagerAccessFlagMask.from_int(struct_unpack('<I', data[offset:offset + 4])[0]),
            database_name=DatabaseName(database_name.representation) if database_name else None
        )
    def from_bytes(cls, data: bytes) -> Tuple[ShareInfo1Container, int]:
        entries_read: int = struct_unpack('<I', data[:4])[0]
        pointer_data = Pointer.from_bytes(data[4:]).representation
        max_count = struct_unpack('<I', pointer_data[:4])[0]

        offset = 4
        entry_share_type_list: List[ShareType] = []
        for _ in range(entries_read):
            entry_share_type_list.append(
                ShareType.from_int(struct_unpack('<I', pointer_data[offset+4:offset+8])[0])
            )
            offset += 12

        entries: List[ShareInfo1] = []
        for i in range(entries_read):
            netname_cvs = ConformantVaryingString.from_bytes(data=pointer_data[offset:])
            offset += calculate_pad_length(len(netname_cvs))
            remark_cvs = ConformantVaryingString.from_bytes(pointer_data[offset:])
            offset += calculate_pad_length(len(remark_cvs))

            entries.append(
                ShareInfo1(
                    netname=netname_cvs.representation,
                    share_type=entry_share_type_list[i],
                    remark=remark_cvs.representation
                )
            )

        return cls(entries=tuple(entries)), 8 + offset
    def from_bytes(cls,
                   data: ByteString,
                   base_offset: int = 0,
                   strict: bool = False) -> BaseRegCreateKeyRequest:

        data = memoryview(data)[base_offset:]
        offset = 0

        key_handle: bytes = cls._KEY_HANDLE_STRUCT.unpack_from(
            buffer=data, offset=offset)[0]
        offset += cls._KEY_HANDLE_STRUCT.size

        ndr_sub_key_name = RRPUnicodeString.from_bytes(data=data[offset:])
        offset += calculate_pad_length(len(ndr_sub_key_name))

        ndr_class_name = RRPUnicodeString.from_bytes(data=data[offset:])
        offset += calculate_pad_length(len(ndr_class_name))

        options = RegOptions.from_int(value=cls._OPTIONS_STRUCT.unpack_from(
            buffer=data, offset=offset)[0])
        offset += cls._OPTIONS_STRUCT.size

        sam_desired = Regsam.from_int(
            value=cls._SAM_DESIRED_STRUCT.unpack_from(buffer=data,
                                                      offset=offset)[0])
        offset += cls._SAM_DESIRED_STRUCT.size

        security_attributes_pointer = Pointer.from_bytes(data=data,
                                                         base_offset=offset)
        offset += Pointer.structure_size
        security_attributes = RPCSecurityAttributes.from_bytes(
            data=security_attributes_pointer.representation)
        offset += calculate_pad_length(len(security_attributes))

        disposition_pointer = Pointer.from_bytes(data=data, base_offset=offset)
        offset += Pointer.structure_size
        disposition = Disposition(
            cls._DISPOSITION_STRUCT.unpack_from(
                buffer=disposition_pointer.representation)[0])

        return cls(key_handle=key_handle,
                   sub_key_name=ndr_sub_key_name.representation,
                   class_name=ndr_class_name.representation,
                   options=options,
                   sam_desired=sam_desired,
                   security_attributes=security_attributes,
                   disposition=disposition)
Beispiel #4
0
def unpack_structure(data: ByteString,
                     structure: dict[str, tuple[Type, ...]],
                     offset: int = 0) -> dict[str, Any]:

    data = memoryview(data)[offset:]
    offset = 0

    structure_values: dict[str, Any] = {}

    for value_name, item_types in structure.items():
        item_data = data[offset:]

        item_types_deque: Deque[Type] = deque(item_types)

        while True:
            try:
                item_type = item_types_deque.popleft()
            except IndexError:
                break

            if item_type in {LPDWORD, LPBYTE, LPBYTE_VAR}:
                item_types_deque.extendleft(reversed(get_args(item_type)))
            elif item_type in {DWORD}:
                struct = CTYPE_TO_STRUCT[item_type.__supertype__]

                item_data = struct.unpack_from(buffer=item_data)[0]
                offset += struct.size
            elif item_type is Pointer:
                pointer = Pointer.from_bytes(data=item_data)
                item_data = pointer.representation
                offset += Pointer.structure_size
            else:
                if isinstance(item_data, (ByteString, memoryview)):
                    item_data = item_type.from_bytes(item_data)

                    if issubclass(item_type, NDRType):
                        offset += calculate_pad_length(
                            length_unpadded=len(item_data))
                    else:
                        offset += len(item_data)

                    if hasattr(item_data, 'representation'):
                        item_data = item_data.representation
                else:
                    item_data = item_type(item_data)

        structure_values[value_name] = item_data

    return structure_values
    def from_bytes(cls,
                   data: ByteString,
                   base_offset: int = 0) -> RPCSecurityDescriptor:
        data = memoryview(data)[base_offset:]
        offset = 0

        security_descriptor_pointer = Pointer.from_bytes(data=data,
                                                         base_offset=offset)
        security_descriptor = SecurityDescriptor.from_bytes(
            data=security_descriptor_pointer.representation) if not isinstance(
                security_descriptor_pointer, NullPointer) else None

        # TODO: Parse `cbInSecurityDescriptor` and `cbOutSecurityDescriptor`?

        return cls(security_descriptor=security_descriptor)
Beispiel #6
0
    def from_bytes(cls, data: bytes) -> RChangeServiceConfigWRequest:

        offset = cls.STRUCTURE_SIZE
        attribute_name_class_pair = (
            ('binary_path_name', ConformantVaryingString),
            ('load_order_group', ConformantVaryingString),
            ('dependencies', UnidimensionalConformantArray),
            ('service_start_name', ConformantVaryingString),
            ('password', UnidimensionalConformantArray),
            ('display_name', ConformantVaryingString)
        )
        kwargs = {}
        for attribute_name, attribute_class in attribute_name_class_pair:
            # Skip attributes in between variable ones.
            if attribute_name in {'dependencies', 'service_start_name', 'display_name'}:
                offset += 4

            attribute_pointer = Pointer.from_bytes(data=data[offset:])
            attribute_ndr = (
                attribute_class.from_bytes(data=attribute_pointer.representation)
                if not isinstance(attribute_pointer, NullPointer) else None
            )
            attribute_len = len(attribute_ndr) if attribute_ndr is not None else 0

            if attribute_name == 'dependencies':
                kwargs[attribute_name] = tuple(
                    b''.join(attribute_ndr.representation).decode(encoding='utf-16-le').split('\x00')
                ) if attribute_ndr else tuple()
            elif attribute_name == 'password':
                kwargs[attribute_name] = b''.join(attribute_ndr.representation).decode(encoding='utf-16-le').rstrip('\x00')
            else:
                kwargs[attribute_name] = attribute_ndr.representation if attribute_ndr is not None else None

            offset += calculate_pad_length(length_unpadded=attribute_pointer.structure_size+attribute_len, multiple=4)

        service_type_int_val: int = struct_unpack('<I', data[20:24])[0]
        start_type_int_val: int = struct_unpack('<I', data[24:28])[0]
        error_control_int_val: int = struct_unpack('<I', data[28:32])[0]

        return cls(
            service_handle=data[:20],
            service_type=ServiceType(service_type_int_val) if service_type_int_val != SERVICE_NO_CHANGE else None,
            start_type=StartType(start_type_int_val) if start_type_int_val != SERVICE_NO_CHANGE else None,
            error_control=ErrorControl(error_control_int_val) if error_control_int_val != SERVICE_NO_CHANGE else None,
            **kwargs
        )
Beispiel #7
0
    def from_bytes(cls, data: bytes) -> RStartServiceWRequest:

        argc = struct_unpack('<I', data[20:24])
        argv_ndr_representation = Pointer.from_bytes(
            data=data[24:]).representation

        num_argv: int = struct_unpack('<I', argv_ndr_representation[:4])[0]
        offset = 4 + num_argv * Pointer.structure_size

        argv_list: List[str] = []
        for _ in range(num_argv):
            argv_ndr_string = ConformantVaryingString.from_bytes(
                data=argv_ndr_representation[offset:])
            argv_list.append(argv_ndr_string.representation)
            offset += calculate_pad_length(
                length_unpadded=len(argv_ndr_string), multiple=4)

        return cls(service_handle=data[:20], argv=tuple(argv_list))
Beispiel #8
0
    def from_bytes(cls, data: ByteString, base_offset: int = 0) -> BaseRegSaveKeyRequest:
        data = memoryview(data)[base_offset:]
        offset = 0

        key_handle: bytes = cls._KEY_HANDLE_STRUCT.unpack_from(buffer=data, offset=base_offset)[0]
        offset += cls._KEY_HANDLE_STRUCT.size

        ndr_save_path = RRPUnicodeString.from_bytes(data=data, base_offset=offset)
        offset += calculate_pad_length(length_unpadded=len(ndr_save_path))

        security_attributes_ndr_pointer = Pointer.from_bytes(data=data, base_offset=offset)
        offset += Pointer.structure_size
        security_attributes = RPCSecurityAttributes.from_bytes(data=security_attributes_ndr_pointer.representation)
        offset += calculate_pad_length(length_unpadded=len(security_attributes))

        return cls(
            key_handle=key_handle,
            save_path=ndr_save_path.representation,
            security_attributes=security_attributes
        )
Beispiel #9
0
    def from_bytes(cls, data: bytes) -> NetrShareEnumResponse:

        # TODO: Make this more concise.

        info_struct, num_info_struct_bytes = ShareEnumStruct.from_bytes(
            data=data)
        offset = num_info_struct_bytes

        total_entries = struct_unpack('<I', data[offset:offset + 4])[0]
        offset += 4

        resume_handle = Pointer.from_bytes(data=data[offset:offset +
                                                     8]).representation
        offset += len(resume_handle)

        return cls(info_struct=info_struct,
                   total_entries=total_entries,
                   resume_handle=resume_handle,
                   return_code=Win32ErrorCode(
                       struct_unpack('<I', data[offset:offset + 4])[0]))
    def from_bytes(cls,
                   data: ByteString,
                   base_offset: int = 0) -> BaseRegCreateKeyResponse:
        data = memoryview(data)[base_offset:]
        offset = 0

        key_handle: bytes = cls._KEY_HANDLE_STRUCT.unpack_from(
            buffer=data, offset=offset)[0]
        offset += cls._KEY_HANDLE_STRUCT.size

        disposition = Disposition(
            cls._DISPOSITION_STRUCT.unpack_from(
                Pointer.from_bytes(data=data,
                                   base_offset=offset).representation)[0])
        offset += Pointer.structure_size + cls._DISPOSITION_STRUCT.size

        return_code = Win32ErrorCode(
            cls._RETURN_CODE_STRUCT.unpack_from(buffer=data, offset=offset)[0])

        return cls(key_handle=key_handle,
                   disposition=disposition,
                   return_code=return_code)
    def from_bytes(cls, data: bytes) -> RCreateServiceWRequest:

        attribute_name_class_pair = (('service_name', ConformantVaryingString),
                                     ('display_name', ConformantVaryingString),
                                     ('desired_access',
                                      ServiceAccessFlagMask.from_int),
                                     ('service_type',
                                      ServiceType), ('start_type', StartType),
                                     ('error_control',
                                      ErrorControl), ('binary_path_name',
                                                      ConformantVaryingString),
                                     ('load_order_group',
                                      ConformantVaryingString), ('tag_id',
                                                                 None),
                                     ('dependencies',
                                      UnidimensionalConformantArray),
                                     ('_depen_size',
                                      None), ('service_start_name',
                                              ConformantVaryingString),
                                     ('password',
                                      UnidimensionalConformantArray),
                                     ('_pw_size', None))
        kwargs = {}
        offset = 20
        for attribute_name, attribute_class in attribute_name_class_pair:
            if attribute_name in {'_depen_size', '_pw_size'}:
                offset += 4
                continue
            if attribute_name in {'service_name', 'binary_path_name'}:
                ndr_string = attribute_class.from_bytes(data=data[offset:])
                kwargs[attribute_name] = ndr_string.representation
                offset += calculate_pad_length(length_unpadded=len(ndr_string))
            elif attribute_name in {
                    'service_type', 'start_type', 'error_control',
                    'desired_access'
            }:
                kwargs[attribute_name] = attribute_class(
                    struct_unpack('<I', data[offset:offset + 4])[0])
                offset += 4
            elif attribute_name == 'tag_id':
                kwargs[attribute_name] = struct_unpack(
                    '<I', data[offset:offset + 4])[0]
                offset += 4
            else:
                attribute_pointer = Pointer.from_bytes(data=data[offset:])
                attribute_ndr = (attribute_class.from_bytes(
                    data=attribute_pointer.representation) if
                                 not isinstance(attribute_pointer, NullPointer)
                                 else None)
                attribute_len = len(
                    attribute_ndr) if attribute_ndr is not None else 0

                if attribute_name == 'dependencies':
                    kwargs[attribute_name] = tuple(b''.join(
                        attribute_ndr.representation).decode(
                            encoding='utf-16-le').split(
                                '\x00')) if attribute_ndr else tuple()
                elif attribute_name == 'password' and attribute_ndr is not None:
                    kwargs[attribute_name] = b''.join(
                        attribute_ndr.representation).decode(
                            encoding='utf-16-le').rstrip('\x00')
                else:
                    kwargs[
                        attribute_name] = attribute_ndr.representation if attribute_ndr is not None else None

                offset += calculate_pad_length(
                    length_unpadded=attribute_pointer.structure_size +
                    attribute_len)

        return cls(scm_handle=data[:20], **kwargs)