Exemplo n.º 1
0
    def __bytes__(self) -> bytes:
        variable_chunk = b''

        binary_path_name_ndr = ConformantVaryingString(representation=self.binary_path_name)
        load_order_group_ndr = ConformantVaryingString(representation=self.load_order_group)
        dependencies_ndr = ConformantVaryingString(representation='\x00'.join(self.dependencies))
        service_start_name_ndr = ConformantVaryingString(representation=self.service_start_name)
        display_name_ndr = ConformantVaryingString(representation=self.display_name)

        ndr_strings = (
            binary_path_name_ndr, load_order_group_ndr, dependencies_ndr, service_start_name_ndr, display_name_ndr
        )

        for ndr_string in ndr_strings:
            variable_chunk += bytes(ndr_string)
            variable_chunk += ((4 - (len(variable_chunk) % 4)) % 4) * b'\x00'

        return b''.join([
            struct_pack('<I', self.service_type.value),
            struct_pack('<I', self.start_type.value),
            struct_pack('<I', self.error_control.value),
            struct_pack('<I', Pointer(representation=b'').referent_id),
            struct_pack('<I', Pointer(representation=b'').referent_id),
            struct_pack('<I', self.tag_id),
            struct_pack('<I', Pointer(representation=b'').referent_id),
            struct_pack('<I', Pointer(representation=b'').referent_id),
            struct_pack('<I', Pointer(representation=b'').referent_id),
            variable_chunk
        ])
Exemplo n.º 2
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
        )
Exemplo n.º 3
0
 def __bytes__(self) -> bytes:
     return b''.join([
         self.key_handle,
         ndr_pad(bytes(RRPUnicodeString(representation=self.sub_key_name))),
         ndr_pad(bytes(RRPUnicodeString(representation=self.class_name))),
         self._OPTIONS_STRUCT.pack(int(self.options)),
         self._SAM_DESIRED_STRUCT.pack(int(self.sam_desired)),
         ndr_pad(
             bytes(
                 Pointer(representation=bytes(self.security_attributes)))),
         bytes(
             Pointer(representation=self._DISPOSITION_STRUCT.pack(
                 self.disposition)))
     ])
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
    def __bytes__(self) -> bytes:
        server_name_bytes = bytes(
            Pointer(representation=ConformantVaryingString(
                representation=self.server_name or '')))

        return b''.join([
            ndr_pad(server_name_bytes),
            bytes(
                ShareEnumStruct(
                    share_info=ShareInfoContainer.from_level_and_params(
                        level=self.level))),
            struct_pack('<i', self.preferred_maximum_length),
            bytes(
                Pointer(representation=self.resume_handle) if self.
                resume_handle else NullPointer())
        ])
Exemplo n.º 6
0
 def __bytes__(self) -> bytes:
     return b''.join([
         self.service_handle,
         struct_pack('<I', self.argc),
         bytes(
             Pointer(representation=b''.join([
                 struct_pack('<I', len(self.argv)), b''.join(
                     struct_pack('<I',
                                 Pointer(representation=b'').referent_id)
                     for _ in self.argv), b''.join(
                         ndr_pad(data=bytes(
                             ConformantVaryingString(
                                 representation=argument_string)))
                         for argument_string in self.argv)
             ])) if self.argv else NullPointer())
     ])
Exemplo n.º 7
0
    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)
Exemplo n.º 8
0
    def __bytes__(self) -> bytes:
        dependencies_ndr = Pointer(
            representation=UnidimensionalConformantArray(representation=tuple(
                bytes([byte])
                for byte in '\x00'.join(self.dependencies).encode(
                    encoding='utf-16-le')))) if len(
                        self.dependencies) != 0 else NullPointer()

        password_ndr = Pointer(representation=UnidimensionalConformantArray(
            representation=tuple(
                bytes([byte]) for byte in (self.password +
                                           '\x00').encode(encoding='utf-16-le')
            ))) if self.password is not None else NullPointer()

        return b''.join([
            self.scm_handle,
            ndr_pad(data=bytes(
                ConformantVaryingString(representation=self.service_name))),
            ndr_pad(data=bytes(
                Pointer(representation=ConformantVaryingString(
                    representation=self.display_name)))),
            struct_pack('<I', int(self.desired_access)),
            struct_pack('<I', self.service_type.value),
            struct_pack('<I', self.start_type.value),
            struct_pack('<I', self.error_control.value),
            ndr_pad(data=bytes(
                ConformantVaryingString(
                    representation=self.binary_path_name))),
            ndr_pad(data=bytes(
                Pointer(representation=ConformantVaryingString(
                    representation=self.load_order_group)) if self.
                load_order_group is not None else NullPointer())),
            struct_pack('<I', self.tag_id),
            ndr_pad(data=bytes(dependencies_ndr)),
            struct_pack('<I', (0 if isinstance(dependencies_ndr, NullPointer)
                               else len(dependencies_ndr.representation) -
                               UnidimensionalConformantArray.STRUCTURE_SIZE)),
            ndr_pad(data=bytes(
                Pointer(representation=ConformantVaryingString(
                    representation=self.service_start_name)) if self.
                service_start_name is not None else NullPointer())),
            ndr_pad(data=bytes(password_ndr)),
            struct_pack('<I', (0 if isinstance(password_ndr, NullPointer) else
                               len(password_ndr.representation) -
                               UnidimensionalConformantArray.STRUCTURE_SIZE))
        ])
Exemplo n.º 9
0
 def __bytes__(self) -> bytes:
     return b''.join([
         self.key_handle,
         bytes(
             Pointer(representation=self._DISPOSITION_STRUCT.pack(
                 self.disposition))),
         self._RETURN_CODE_STRUCT.pack(self.return_code)
     ])
Exemplo n.º 10
0
    def __bytes__(self) -> bytes:
        security_descriptor_len = self.in_security_descriptor

        return b''.join([
            bytes(
                Pointer(representation=bytes(self.security_descriptor))
                if self.security_descriptor is not None else NullPointer()),
            self._IN_SECURITY_DESCRIPTOR_STRUCT.pack(security_descriptor_len),
            self._OUT_SECURITY_DESCRIPTOR_STRUCT.pack(security_descriptor_len)
        ])
Exemplo n.º 11
0
    def __bytes__(self) -> bytes:

        machine_name_bytes = bytes(
            Pointer(representation=ConformantVaryingString(representation=self.machine_name or ''))
        )

        database_name_bytes = bytes(
            Pointer(
                representation=ConformantVaryingString(
                    representation=self.database_name.value if self.database_name else ''
                )
            )
        )

        return b''.join([
            ndr_pad(machine_name_bytes),
            ndr_pad(database_name_bytes),
            struct_pack('<I', int(self.desired_access))
        ])
Exemplo n.º 12
0
    def __bytes__(self) -> bytes:
        if len(self.representation) == 0:
            pointer = NullPointer()
            string_len = 0
        else:
            pointer = Pointer(representation=ConformantVaryingString(
                representation=self.representation))
            string_len = len(self.representation_bytes)

        return b''.join(
            [pack('<H', string_len),
             pack('<H', string_len),
             bytes(pointer)])
Exemplo n.º 13
0
    def __bytes__(self) -> bytes:
        fixed_part: bytes = b''
        variable_part: bytes = b''
        for entry in self.entries:
            netname_pointer = Pointer(representation=ConformantVaryingString(representation=entry.netname))
            remark_pointer = Pointer(representation=ConformantVaryingString(representation=entry.remark))

            fixed_part += b''.join([
                struct_pack('<I', netname_pointer.referent_id),
                struct_pack('<I', int(entry.share_type)),
                struct_pack('<I', remark_pointer.referent_id)
            ])

            variable_part += b''.join([
                ndr_pad(bytes(netname_pointer.representation)),
                ndr_pad(bytes(remark_pointer.representation))
            ])

        return b''.join([
            struct_pack('<I', self.entries_read),
            b''.join([fixed_part, variable_part]) or b'\x00\x00\x00\x00'
        ])
Exemplo n.º 14
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
Exemplo n.º 15
0
    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)
Exemplo n.º 16
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
        )
Exemplo n.º 17
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))
Exemplo n.º 18
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]))
Exemplo n.º 19
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
        )
Exemplo n.º 20
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)
Exemplo n.º 21
0
 def __bytes__(self) -> bytes:
     return b''.join([
         self.key_handle,
         ndr_pad(bytes(RRPUnicodeString(representation=str(self.save_path)))),
         bytes(Pointer(representation=bytes(self.security_attributes)))
     ])
Exemplo n.º 22
0
    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)