Beispiel #1
0
 def publishers(self):
     h = windows.winproxy.EvtOpenPublisherEnum(None, 0)
     size = 0x1000
     buffer = ctypes.create_unicode_buffer(size)
     ressize = gdef.DWORD()
     with ClosingEvtHandle(h):
         while True:
             try:
                 windows.winproxy.EvtNextPublisherId(h, size, buffer, ressize)
             except WindowsError as e:
                 if e.winerror != gdef.ERROR_NO_MORE_ITEMS:
                     raise
                 return
             assert buffer[ressize.value - 1] == "\x00"
             name = buffer[:ressize.value - 1]
             publisher = EvtPublisher(name)
             yield publisher
Beispiel #2
0
 def _get_object_type(self):
     lh = self.local_handle
     xxx = gdef.PUBLIC_OBJECT_TYPE_INFORMATION()
     size_needed = gdef.DWORD()
     try:
         winproxy.NtQueryObject(lh, gdef.ObjectTypeInformation,
                                ctypes.byref(xxx), ctypes.sizeof(xxx),
                                ctypes.byref(size_needed))
     except WindowsError as e:
         if e.code != gdef.STATUS_INFO_LENGTH_MISMATCH:
             raise
         size = size_needed.value
         buffer = ctypes.c_buffer(size)
         winproxy.NtQueryObject(lh, gdef.ObjectTypeInformation, buffer,
                                size, ctypes.byref(size_needed))
         xxx = gdef.PUBLIC_OBJECT_TYPE_INFORMATION.from_buffer_copy(buffer)
     return xxx.TypeName.str
def enumerate_kernel_modules():
    if windows.current_process.is_wow_64:
        return enumerate_kernel_modules_syswow64()
    cbsize = gdef.DWORD()
    winproxy.NtQuerySystemInformation(gdef.SystemModuleInformation, None, 0,
                                      ctypes.byref(cbsize))
    raw_buffer = (cbsize.value * gdef.BYTE)()
    buffer = gdef.SYSTEM_MODULE_INFORMATION.from_address(
        ctypes.addressof(raw_buffer))
    winproxy.NtQuerySystemInformation(gdef.SystemModuleInformation,
                                      ctypes.byref(raw_buffer),
                                      ctypes.sizeof(raw_buffer),
                                      ctypes.byref(cbsize))
    modules = (SystemModule * buffer.ModulesCount).from_address(
        ctypes.addressof(buffer) +
        gdef.SYSTEM_MODULE_INFORMATION.Modules.offset)
    return list(modules)
    def get_name(self,
                 nametype=gdef.CERT_NAME_SIMPLE_DISPLAY_TYPE,
                 param_type=0,
                 flags=0):
        """Retrieve the subject or issuer name of the certificate.
        See `CertGetNameStringA <https://msdn.microsoft.com/en-us/library/windows/desktop/aa376086(v=vs.85).aspx>`_

        :returns: :class:`str`
        """
        if nametype == gdef.CERT_NAME_RDN_TYPE:
            param_type = gdef.DWORD(param_type)
            param_type = gdef.LPDWORD(param_type)
        size = winproxy.CertGetNameStringA(self, nametype, flags, param_type,
                                           None, 0)
        namebuff = ctypes.c_buffer(size)
        size = winproxy.CertGetNameStringA(self, nametype, flags, param_type,
                                           namebuff, size)
        return namebuff[:-1]
Beispiel #5
0
def verify_signature(cert, encoded_blob):
    # Verify parameters
    verif_param = gdef.CRYPT_KEY_VERIFY_MESSAGE_PARA()
    verif_param.cbSize = ctypes.sizeof(gdef.CRYPT_KEY_VERIFY_MESSAGE_PARA)
    verif_param.dwMsgEncodingType = windows.crypto.DEFAULT_ENCODING
    verif_param.hCryptProv = None
    # The public key used
    pubkey = cert.pCertInfo[0].SubjectPublicKeyInfo
    # Preparing in/out buffer/size
    signed_buffer = windows.utils.BUFFER(
        gdef.BYTE).from_buffer_copy(encoded_blob)
    decoded_buffer = windows.utils.BUFFER(
        gdef.BYTE).from_buffer_copy(encoded_blob)
    decoded_size = gdef.DWORD(len(decoded_buffer))
    winproxy.CryptVerifyMessageSignatureWithKey(verif_param,
                                                pubkey, signed_buffer,
                                                len(encoded_blob),
                                                decoded_buffer, decoded_size)
    return bytearray(decoded_buffer[:decoded_size.value])
Beispiel #6
0
def DeviceIoControl(hDevice,
                    dwIoControlCode,
                    lpInBuffer,
                    nInBufferSize=None,
                    lpOutBuffer=NeededParameter,
                    nOutBufferSize=None,
                    lpBytesReturned=None,
                    lpOverlapped=None):
    if nInBufferSize is None:
        nInBufferSize = len(lpInBuffer)
    if nOutBufferSize is None:
        nOutBufferSize = len(lpOutBuffer)
    if lpBytesReturned is None:
        # Some windows check 0 / others does not
        lpBytesReturned = ctypes.byref(gdef.DWORD())
    return DeviceIoControl.ctypes_function(hDevice, dwIoControlCode,
                                           lpInBuffer, nInBufferSize,
                                           lpOutBuffer, nOutBufferSize,
                                           lpBytesReturned, lpOverlapped)
Beispiel #7
0
    def values(self):
        """The values of the registry key

        :type: [:class:`KeyValue`] - A list of values"""
        res = []
        # Get max info keys

        max_name_size, max_data_size = self.get_key_size_info()
        # Null terminators
        max_name_size += 1
        max_data_size += 2
        with ExpectWindowsError(259):
            for i in itertools.count():
                value_type = gdef.DWORD()
                namesize = gdef.DWORD(max_name_size)
                keyname = ctypes.create_unicode_buffer(namesize.value)
                datasize = gdef.DWORD(max_data_size)
                databuffer = windows.utils.BUFFER(gdef.BYTE,
                                                  nbelt=datasize.value)()
                # A value can have been added in-between.
                # So recheck the size given by get_key_size_info :)
                # But check 10 times max as RegEnumValueW may bug (seen) and always return  ERROR_MORE_DATA even with enought size
                for _ in range(10):
                    try:
                        winproxy.RegEnumValueW(self.phkey, i, keyname,
                                               namesize, None, value_type,
                                               databuffer, datasize)
                        break
                    except WindowsError as e:
                        if e.winerror != gdef.ERROR_MORE_DATA:
                            raise
                        # I found some strange Windows where even with a big enought buffer:
                        # - the data was filled
                        # - ERROR_MORE_DATA was returned
                        ## To prevent such bug to trigger and infinite loop, two things
                        # - If the retuned namesize <= the passed keysize and keyname is not empty -> return the data`
                        # - Max 10 test to prevent Infinite loop
                        if ((namesize.value <= max_name_size)
                                and (datasize.value <= max_data_size)
                                and (keyname[:namesize.value].count("\x00") <
                                     namesize.value)):  # Not just 0 Zero ?
                            break

                        # Update the sizes / buffers & try again :)
                        max_name_size, max_data_size = self.get_key_size_info()
                        max_name_size = max(
                            max_name_size + 1, namesize.value + 1
                        )  # namesize.value may be > to max_name_size apparently (guessed)
                        max_data_size = max(
                            max_data_size + 2, datasize.value + 2
                        )  # datasize.value may be > to max_data_size apparently (seen)
                        namesize = gdef.DWORD(max_name_size)
                        keyname = ctypes.create_unicode_buffer(namesize.value)
                        datasize = gdef.DWORD(max_data_size)
                        databuffer = windows.utils.BUFFER(
                            gdef.BYTE, nbelt=datasize.value)()
                else:
                    # Probably a windows bug that prevent us from retrieving the data
                    # Raise something (thus preventing getting the other values..) ? ignore it ?
                    raise ValueError(
                        "Could not extract registry key values, problably a Windows/hook bug"
                    )
                vobj = decode_registry_buffer(value_type.value, databuffer,
                                              datasize.value)
                res.append(KeyValue(keyname.value, vobj, value_type.value))
        return res
Beispiel #8
0
    def connect_to_port(self,
                        port_name,
                        connect_message=None,
                        port_attr=None,
                        port_attr_flags=0x10000,
                        obj_attr=None,
                        flags=gdef.ALPC_MSGFLG_SYNC_REQUEST,
                        timeout=None):
        """Connect to the ALPC port ``port_name``. Most of the parameters have defauls value is ``None`` is passed.

            :param AlpcMessage connect_message: The message send with the connection request, if not ``None`` the function will return an :class:`AlpcMessage`
            :param ALPC_PORT_ATTRIBUTES port_attr: The port attributes, one with default value will be used if this parameter is ``None``
            :param int port_attr_flags: ``ALPC_PORT_ATTRIBUTES.Flags`` used if ``port_attr`` is ``None`` (MUTUALY EXCLUSINVE WITH ``port_attr``)
            :param OBJECT_ATTRIBUTES obj_attr: The attributes of the port (can be None)
            :param int flags: The flags for :func:`NtAlpcConnectPort`
            :param int timeout: The timeout of the request
        """
        # TODO raise on mutual exclusive parameter
        if self.handle is not None:
            raise ValueError("Client already connected")
        handle = gdef.HANDLE()
        port_name_unicode = self._alpc_port_to_unicode_string(port_name)

        if port_attr is None:
            port_attr = gdef.ALPC_PORT_ATTRIBUTES()
            port_attr.Flags = port_attr_flags  # Flag qui fonctionne pour l'UAC
            port_attr.MaxMessageLength = DEFAULT_MESSAGE_SIZE
            port_attr.MemoryBandwidth = 0
            port_attr.MaxPoolUsage = 0xffffffff
            port_attr.MaxSectionSize = 0xffffffff
            port_attr.MaxViewSize = 0xffffffff
            port_attr.MaxTotalSectionSize = 0xffffffff
            port_attr.DupObjectTypes = 0xffffffff

            port_attr.SecurityQos.Length = ctypes.sizeof(port_attr.SecurityQos)
            port_attr.SecurityQos.ImpersonationLevel = gdef.SecurityImpersonation
            port_attr.SecurityQos.ContextTrackingMode = 0
            port_attr.SecurityQos.EffectiveOnly = 0

        if connect_message is None:
            send_msg = None
            send_msg_attr = None
            buffersize = None
        elif isinstance(connect_message, windows.pycompat.anybuff):
            buffersize = gdef.DWORD(len(connect_message) + 0x1000)
            send_msg = AlpcMessagePort.from_buffer_size(buffersize.value)
            send_msg.data = connect_message
            send_msg_attr = MessageAttribute.with_all_attributes()
        elif isinstance(connect_message, AlpcMessage):
            send_msg = connect_message.port_message
            send_msg_attr = connect_message.attributes
            buffersize = gdef.DWORD(connect_message.port_message_buffer_size)
        else:
            raise ValueError(
                "Don't know how to send <{0!r}> as connect message".format(
                    connect_message))

        receive_attr = MessageAttribute.with_all_attributes()
        winproxy.NtAlpcConnectPort(handle, port_name_unicode, obj_attr,
                                   port_attr, flags, None, send_msg,
                                   buffersize, send_msg_attr, receive_attr,
                                   timeout)
        # If send_msg is not None, it contains the ClientId.UniqueProcess : PID of the server :)
        self.handle = handle.value
        self.port_name = port_name
        return AlpcMessage(send_msg,
                           receive_attr) if send_msg is not None else None
Beispiel #9
0
def NtProtectVirtualMemory(ProcessHandle, BaseAddress, NumberOfBytesToProtect, NewAccessProtection, OldAccessProtection=None):
    if OldAccessProtection is None:
        OldAccessProtection = gdef.DWORD()
    return NtProtectVirtualMemory.ctypes_function(ProcessHandle, BaseAddress, NumberOfBytesToProtect, NewAccessProtection, OldAccessProtection)
Beispiel #10
0
 def raw_hash(self):
     size = gdef.DWORD(100)
     buffer = ctypes.c_buffer(size.value)
     winproxy.CryptHashCertificate(None, 0, 0, self.pbCertEncoded, self.cbCertEncoded, ctypes.cast(buffer, gdef.LPBYTE), size)
     return buffer[:size.value]
Beispiel #11
0
 def size(self):
     array_size = gdef.DWORD()
     windows.winproxy.EvtGetObjectArraySize(self, array_size)
     return array_size.value
Beispiel #12
0
def VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect=None):
    if lpflOldProtect is None:
        lpflOldProtect = ctypes.byref(gdef.DWORD())
    return VirtualProtect.ctypes_function(lpAddress, dwSize, flNewProtect,
                                          lpflOldProtect)
from pfwtest import *


@pytest.mark.parametrize("type, size", [
(gdef.BYTE, 10),
(gdef.DWORD, 12),
(gdef.GUID, 42)])
def test_improved_BUFFER_size(type, size):
    x = utils.BUFFER(type, 1)(size=size)
    assert len(x) == 1
    assert x.real_size == size
    assert len(x._raw_buffer_) == size

@pytest.mark.parametrize("params, expected_type, expected_size", [
(([gdef.DWORD(x) for x in range(10)],), gdef.DWORD, 10), # list
(([gdef.GUID() for x in range(10)],), gdef.GUID, 10), # generator
((range(42), gdef.ULONGLONG), gdef.ULONGLONG, 42), # Explicite type
])
def test_improved_buffer(params, expected_type, expected_size):
    x = utils.buffer(*params)
    assert x._type_ == expected_type
    assert len(x) == expected_size

@pytest.mark.parametrize("c_type, buffer, expected_size", [
(gdef.CHAR, "12345", 5),
(gdef.WCHAR, "\x001\x002\x003\x004\x005", 5),
(gdef.DWORD, "1111222233334444", 4),
])
def test_parial_buffer_size_guess(c_type, buffer, expected_size):
    buf = windows.utils.BUFFER(c_type).from_buffer_copy(buffer)
def WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite=None, lpNumberOfBytesWritten=None, lpOverlapped=None):
    if nNumberOfBytesToWrite is None:
        nNumberOfBytesToWrite = len(lpBuffer)
    if lpOverlapped is None and lpNumberOfBytesWritten is None:
        lpNumberOfBytesWritten = ctypes.byref(gdef.DWORD())
    return WriteFile.ctypes_function(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped)
def ReadFile(hFile, lpBuffer, nNumberOfBytesToRead=None, lpNumberOfBytesRead=None, lpOverlapped=None):
    if nNumberOfBytesToRead is None:
        nNumberOfBytesToRead = len(lpBuffer)
    if lpOverlapped is None and lpNumberOfBytesRead is None:
        lpNumberOfBytesRead = ctypes.byref(gdef.DWORD())
    return ReadFile.ctypes_function(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped)
def GetTokenInformation(TokenHandle=NeededParameter, TokenInformationClass=NeededParameter, TokenInformation=None, TokenInformationLength=0, ReturnLength=None):
    if ReturnLength is None:
        ReturnLength = ctypes.byref(gdef.DWORD())
    return GetTokenInformation.ctypes_function(TokenHandle, TokenInformationClass, TokenInformation, TokenInformationLength, ReturnLength)
Beispiel #17
0
 def _get_object_name(self):
     lh = self.local_handle
     size_needed = gdef.DWORD()
     yyy = ctypes.c_buffer(0x1000)
     winproxy.NtQueryObject(lh, gdef.ObjectNameInformation, ctypes.byref(yyy), ctypes.sizeof(yyy), ctypes.byref(size_needed))
     return gdef.LSA_UNICODE_STRING.from_buffer_copy(yyy[:size_needed.value]).str
Beispiel #18
0
 def _lookup_name(self, luid):
     size = gdef.DWORD(0x100)
     buff = ctypes.c_buffer(size.value)
     winproxy.LookupPrivilegeNameA(None, luid, buff, size)
     return buff[:size.value]
Beispiel #19
0
def device_io_control(handle, iocode, buffer):
    outbuffer = ctypes.c_buffer(0x1000)
    returned_size = gdef.DWORD()
    windows.winproxy.DeviceIoControl(handle, iocode, buffer, lpOutBuffer=outbuffer, lpBytesReturned=returned_size)
    return outbuffer[:returned_size.value]
Beispiel #20
0
def GetWindowsDirectoryW(lpBuffer, uSize=None):
    if uSize is None:
        uSize = gdef.DWORD(len(lpBuffer))
    return GetWindowsDirectoryW.ctypes_function(lpBuffer, uSize)
Beispiel #21
0
def GetFileVersionInfoSizeW(lptstrFilename, lpdwHandle=None):
    if lpdwHandle is None:
        lpdwHandle = ctypes.byref(gdef.DWORD())
    return GetFileVersionInfoSizeW.ctypes_function(lptstrFilename, lpdwHandle)
Beispiel #22
0
def PeekNamedPipe(hNamedPipe):
    lpTotalBytesAvail = gdef.DWORD()
    PeekNamedPipe.ctypes_function(hNamedPipe, None, 0, None, lpTotalBytesAvail, None)
    return lpTotalBytesAvail.value
Beispiel #23
0
 def providers(self):
     buffer = windows.utils.BUFFER(gdef.GUID, 0x1000)()
     size = gdef.DWORD()
     windows.winproxy.EnumerateTraceGuidsEx(gdef.TraceGuidQueryList, None, 0, buffer, buffer.real_size, size)
     return [TraceProvider(g) for g in buffer[:size.value / ctypes.sizeof(gdef.GUID)]]