Ошибка расшифровки сообщения с нарушением прав доступа - PullRequest
0 голосов
/ 05 июня 2019

функция для initiliase Schannel

SecureConnect proc uses ebx edi esi, _host: dword, _port: dword, phContext: dword, pCredHandle: dword, cSocket: dword

    SECPKG_CRED_OUTBOUND                equ     2
    SCHANNEL_CRED_VERSION               equ     4
    SCH_CRED_NO_DEFAULT_CREDS           equ     10h
    SCH_CRED_MANUAL_CRED_VALIDATION     equ     8

    ISC_REQ_SEQUENCE_DETECT             equ     8
    ISC_REQ_REPLAY_DETECT               equ     4
    ISC_REQ_CONFIDENTIALITY             equ     10h
    ISC_RET_EXTENDED_ERROR              equ     4000h
    ISC_REQ_ALLOCATE_MEMORY             equ     100h
    ISC_REQ_STREAM                      equ     8000h
    ISC_RET_EXTENDED_ERROR              equ     4000h

    SECURITY_NATIVE_DREP                equ     10h

    IO_BUFFER_SIZE                      equ     8000h

    SEC_I_INCOMPLETE_CREDENTIALS        equ     90320h
    SEC_I_CONTINUE_NEEDED               equ     90312h
    SEC_E_INCOMPLETE_MESSAGE            equ     80090318h

    SCHANNEL_CRED STRUCT

         dwVersion                      dd  ?
         cCreds                         dd  ?
         paCred                         dd  ?
         hRootStore                     dd  ?
         cMappers                       dd  ?
         aphMappers                     dd  ?
         cSupportedAlgs                 dd  ?
         palgSupportedAlgs              dd  ?
         grbitEnabledProtocols          dd  ?
         dwMinimumCipherStrength        dd  ?
         dwMaximumCipherStrength        dd  ?
         dwSessionLifespan              dd  ?
         dwFlags                        dd  ?
         dwCredFormat                   dd  ?

    SCHANNEL_CRED ENDS

    SecBufferDesc STRUCT

         ulVersion                      dd  ?
         cBuffers                       dd  ?
         pBuffers                       dd  ?

    SecBufferDesc ENDS

    SecBuffer STRUCT

         cbBuffer                       dd  ?
         BufferType                     dd  ?
         pvBuffer                       dd  ?

    SecBuffer ENDS

    CERT_CONTEXT STRUCT

         dwCertEncodingType             dd  ?
         pbCertEncoded                  dd  ?
         cbCertEncoded                  dd  ?
         pCertInfo                      dd  ?
         hCertStore                     dd  ?

    CERT_CONTEXT ENDS

    local credentials       : SCHANNEL_CRED
    local sSocket           : dword
    local sin               : sockaddr_in
    local iMode             : dword
    local fd                : fds_set
    local dwSSPIFlags       : dword
    local out_buffer_desc   : SecBufferDesc
    local _out_buffer       : SecBuffer
    local in_buffer_desc    : SecBufferDesc
    local _in_buffer[2]     : SecBuffer
    local dwSSPIOutFlags    : dword
    local IoBuffer          : dword
    local cbIoBuffer        : dword
    local fDoRead           : dword
    local scRet             : dword
    local ExtraData         : SecBuffer

         lea ecx, [ebp - 3 * 4]

         sub ecx, esp

         invoke ZeroMemory, addr [esp + 3 * 4 + 4], ecx

         mov credentials.dwVersion, SCHANNEL_CRED_VERSION
         mov credentials.dwFlags, SCH_CRED_NO_DEFAULT_CREDS or SCH_CRED_MANUAL_CRED_VALIDATION

         invoke AcquireCredentialsHandleA, NULL, _T("Microsoft Unified Security Protocol Provider"), SECPKG_CRED_OUTBOUND, NULL, addr credentials, NULL, NULL, dword ptr [pCredHandle], NULL

         .if eax == 0

             invoke socket, AF_INET, SOCK_STREAM, IPPROTO_TCP

             mov dword ptr [sSocket], eax

             invoke copydata, addr sSocket, dword ptr [cSocket], sizeof dword

             invoke isip, dword ptr [_host]

             .if eax != 0

                 mov eax, dword ptr [_host]
                 jmp @f

             .endif

             invoke xgethostbyname, dword ptr [_host], AF_INET

             invoke inet_ntoa, eax

             @@:

             invoke inet_addr, eax

             mov sin.sin_addr, eax

             mov eax, dword ptr [_port]

             cmp eax, 65536
             jna @f

             invoke atoi, eax

             @@:

             invoke htons, eax

             mov sin.sin_port, ax
             mov sin.sin_family, AF_INET ;???????? ???? ? ??? "AF_INET"

             mov iMode, 1

             invoke setsockopt, dword ptr [sSocket], IPPROTO_TCP, TCP_NODELAY, addr iMode, 4

             mov iMode, 1

             invoke ioctlsocket, dword ptr [sSocket], FIONBIO, addr iMode

             invoke connect, dword ptr [sSocket], addr sin, sizeof sin ;??????????? ?????? ????????

             invoke fd_set_, dword ptr [sSocket], 0, addr fd, 10, 0

             invoke select, 0, 0, addr fd, 0, addr [fd + 4 * 3]

             cmp eax, 1
             jnz close

             mov iMode, 0

             invoke ioctlsocket, dword ptr [sSocket], FIONBIO, addr iMode

             mov dword ptr [dwSSPIFlags], ISC_REQ_SEQUENCE_DETECT or ISC_REQ_REPLAY_DETECT or ISC_REQ_CONFIDENTIALITY or ISC_RET_EXTENDED_ERROR or ISC_REQ_ALLOCATE_MEMORY or ISC_REQ_STREAM

             mov _out_buffer.cbBuffer, 0
             mov _out_buffer.BufferType, SECBUFFER_TOKEN
             mov _out_buffer.pvBuffer, NULL

             mov out_buffer_desc.ulVersion, SECBUFFER_VERSION
             mov out_buffer_desc.cBuffers, 1

             lea eax, _out_buffer
             mov out_buffer_desc.pBuffers, eax

             invoke InitializeSecurityContextA, dword ptr [pCredHandle], NULL, dword ptr [_host], dword ptr [dwSSPIFlags], 0, SECURITY_NATIVE_DREP, NULL, 0, dword ptr [phContext], addr out_buffer_desc, addr dwSSPIOutFlags, NULL

             .if _out_buffer.cbBuffer != 0 && _out_buffer.pvBuffer != NULL

                 invoke synsend, dword ptr [sSocket], _out_buffer.pvBuffer, _out_buffer.cbBuffer, NULL

                 invoke FreeContextBuffer, dword ptr [_out_buffer.pvBuffer]

                 invoke VirtualAlloc, 0, IO_BUFFER_SIZE, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE

                 test eax, eax
                 jz close

                 mov dword ptr [IoBuffer], eax

                 mov dword ptr [scRet], SEC_I_CONTINUE_NEEDED

                 mov dword ptr [cbIoBuffer], 0
                 mov dword ptr [fDoRead], TRUE

                 .while dword ptr [scRet] == SEC_I_CONTINUE_NEEDED || dword ptr [scRet] == SEC_E_INCOMPLETE_MESSAGE || dword ptr [scRet] == SEC_I_INCOMPLETE_CREDENTIALS

                     .if dword ptr [cbIoBuffer] == 0 || dword ptr [scRet] == SEC_E_INCOMPLETE_MESSAGE

                         .if dword ptr [fDoRead] == TRUE

                             mov eax, dword ptr [IoBuffer]
                             add eax, dword ptr [cbIoBuffer]

                             mov ecx, IO_BUFFER_SIZE
                             sub ecx, dword ptr [cbIoBuffer]

                             invoke recv_, dword ptr [sSocket], eax, ecx, 10

                             .break .if eax == 0 || sdword ptr eax < 0

                             add dword ptr [cbIoBuffer], eax

                         .else

                             mov dword ptr [fDoRead], TRUE

                         .endif

                     .endif

                     mov _out_buffer.cbBuffer, 0
                     mov _out_buffer.BufferType, SECBUFFER_TOKEN
                     mov _out_buffer.pvBuffer, NULL

                     mov out_buffer_desc.ulVersion, SECBUFFER_VERSION
                     mov out_buffer_desc.cBuffers, 1

                     lea eax, _out_buffer
                     mov out_buffer_desc.pBuffers, eax

                     mov eax, dword ptr [IoBuffer]
                     mov ecx, dword ptr [cbIoBuffer]

                     mov (0Ch * 0) + _in_buffer.cbBuffer, ecx
                     mov (0Ch * 0) + _in_buffer.BufferType, SECBUFFER_TOKEN
                     mov (0Ch * 0) + _in_buffer.pvBuffer, eax

                     mov (0Ch * 1) + _in_buffer.cbBuffer, 0
                     mov (0Ch * 1) + _in_buffer.BufferType, SECBUFFER_EMPTY
                     mov (0Ch * 1) + _in_buffer.pvBuffer, NULL

                     mov in_buffer_desc.ulVersion, SECBUFFER_VERSION
                     mov in_buffer_desc.cBuffers, 2

                     lea eax, _in_buffer
                     mov in_buffer_desc.pBuffers, eax

                     invoke InitializeSecurityContextA, dword ptr [pCredHandle], dword ptr [phContext], NULL, dword ptr [dwSSPIFlags], 0, SECURITY_NATIVE_DREP, addr in_buffer_desc, 0, NULL, addr out_buffer_desc, addr dwSSPIOutFlags, NULL

                     mov dword ptr [scRet], eax

                     .continue .if dword ptr [scRet] == SEC_E_INCOMPLETE_MESSAGE

                     .break .if sdword ptr [scRet] < 0

                     .if dword ptr [scRet] == SEC_E_OK || dword ptr [scRet] == SEC_I_CONTINUE_NEEDED && _out_buffer.cbBuffer != 0 && _out_buffer.pvBuffer != NULL

                         invoke synsend, dword ptr [sSocket], _out_buffer.pvBuffer, _out_buffer.cbBuffer, NULL

                         invoke FreeContextBuffer, dword ptr [_out_buffer.pvBuffer]

                     .endif

                     .if dword ptr [scRet] == SEC_I_INCOMPLETE_CREDENTIALS

                         invoke MessageBoxA, 0, _T("SEC_I_INCOMPLETE_CREDENTIALS"), 0, 0

                         ;//GetNewClientCredentials(phCreds, dword ptr [phContext]);

                         ;// Повторная попытка.
                         ;fDoRead = FALSE;
                         ;scRet = SEC_I_CONTINUE_NEEDED;

                         ;// Исправляем ошибку Platform SDK!
                         ;// Считаем, что за этим сообщением не может следовать другое
                         ;cbIoBuffer = 0;

                         ;.continue

                     .endif

                     .if dword ptr [(0Ch * 1) + _in_buffer.BufferType] == SECBUFFER_EXTRA

                         mov eax, dword ptr [IoBuffer]
                         add eax, dword ptr [cbIoBuffer]

                         mov ecx, (0Ch * 1) + _in_buffer.cbBuffer

                         mov dword ptr [cbIoBuffer], ecx

                         sub eax, ecx

                         invoke copydata, eax, dword ptr [IoBuffer], (0Ch * 1) + _in_buffer.cbBuffer

                     .else

                         mov dword ptr [cbIoBuffer], 0

                     .endif

                 .endw

                 invoke VirtualFree, dword ptr [IoBuffer], 0, MEM_RELEASE

                 cmp dword ptr [scRet], SEC_E_OK
                 jnz close

                 mov eax, dword ptr [sSocket]

                 jmp _ret

             .endif

         .endif

         close:

         xor eax, eax

 _ret:

 ret

SecureConnect endp

decryptmessage

cryptrecv proc uses ebx edi esi, _socket: dword, rbuffer: dword, phContext: dword

    IO_BUFFER_SIZE                      equ     8000h

    SecBufferDesc STRUCT

         ulVersion                      dd  ?
         cBuffers                       dd  ?
         pBuffers                       dd  ?

    SecBufferDesc ENDS

    SecBuffer STRUCT

         cbBuffer                       dd  ?
         BufferType                     dd  ?
         pvBuffer                       dd  ?

    SecBuffer ENDS

    local Cbuffer           : dword
    local cb                : dword
    local _edx              : dword
    local in_buffer_desc    : SecBufferDesc
    local _in_buffer[4]     : SecBuffer
    local scRet             : dword
    local _result           : dword

         lea ecx, [ebp - 3 * 4]

         sub ecx, esp

         invoke ZeroMemory, addr [esp + 3 * 4 + 4], ecx

         invoke ZeroMemory, dword ptr [rbuffer], 4

         mov edi, dword ptr [rbuffer]

         mov dword ptr [_edx], IO_BUFFER_SIZE

         invoke VirtualAlloc, 0, dword ptr [_edx], MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE

         test eax, eax
         jz close

         mov dword ptr [Cbuffer], eax

         _recv:

         .if dword ptr [cb] == 0 || dword ptr [scRet] == SEC_E_INCOMPLETE_MESSAGE

             @@:

             mov eax, dword ptr [Cbuffer]
             add eax, dword ptr [cb]

             mov ecx, dword ptr [_edx]
             sub ecx, dword ptr [cb]

             test ecx, ecx
             jnz @f

             add dword ptr [_edx], IO_BUFFER_SIZE

             invoke VirtualAlloc, 0, dword ptr [_edx], MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE

             test eax, eax
             jz close

             mov esi, eax

             invoke copydata, dword ptr [Cbuffer], esi, dword ptr [cb]

             invoke VirtualFree, dword ptr [Cbuffer], 0, MEM_RELEASE

             mov dword ptr [Cbuffer], esi

             jmp @b

             @@:

             invoke recv, dword ptr [_socket], eax, ecx, 0

             test eax, eax
             jle close

             add dword ptr [cb], eax

         .endif

         invoke copydata, addr cb, addr [(0Ch * 0) + _in_buffer.cbBuffer], 4
         mov (0Ch * 0) + _in_buffer.BufferType, SECBUFFER_DATA
         invoke copydata, addr Cbuffer, addr [(0Ch * 0) + _in_buffer.pvBuffer], 4

         mov (0Ch * 1) + _in_buffer.cbBuffer, 0
         mov (0Ch * 1) + _in_buffer.BufferType, SECBUFFER_EMPTY
         mov (0Ch * 1) + _in_buffer.pvBuffer, NULL

         mov (0Ch * 2) + _in_buffer.cbBuffer, 0
         mov (0Ch * 2) + _in_buffer.BufferType, SECBUFFER_EMPTY
         mov (0Ch * 2) + _in_buffer.pvBuffer, NULL

         mov (0Ch * 3) + _in_buffer.cbBuffer, 0
         mov (0Ch * 3) + _in_buffer.BufferType, SECBUFFER_EMPTY
         mov (0Ch * 3) + _in_buffer.pvBuffer, NULL

         lea eax, _in_buffer

         mov in_buffer_desc.pBuffers, eax
         mov in_buffer_desc.ulVersion, SECBUFFER_VERSION
         mov in_buffer_desc.cBuffers, 4

         invoke DecryptMessage, dword ptr [phContext], addr in_buffer_desc, 0, NULL

         mov dword ptr [scRet], eax

         cmp dword ptr [scRet], SEC_E_INCOMPLETE_MESSAGE
         jz _recv

         cmp dword ptr [scRet], SEC_I_CONTEXT_EXPIRED
         jz close

         .if dword ptr [scRet] == SEC_I_RENEGOTIATE

             invoke MessageBoxA, 0, _T("SEC_I_RENEGOTIATE"), 0, 0

             jmp close

         .endif

         cmp eax, SEC_E_OK
         jnz close

         mov dword ptr [cb], 0

         mov ebx, 1

         .while ebx <= 3

             imul ecx, ebx, 0Ch
             lea esi, [ecx + _in_buffer]

             .if dword ptr [esi + SecBuffer.BufferType] == SECBUFFER_DATA && dword ptr [esi + SecBuffer.cbBuffer] != 0

                 .if dword ptr [edi] == NULL

                     invoke VirtualAlloc, 0, dword ptr [esi + SecBuffer.cbBuffer], MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE

                     test eax, eax
                     jz close

                     mov dword ptr [edi], eax

                     invoke copydata, dword ptr [esi + SecBuffer.pvBuffer], dword ptr [edi], dword ptr [esi + SecBuffer.cbBuffer]

                 .else

                     mov ecx, dword ptr [_result]
                     add ecx, dword ptr [esi + SecBuffer.cbBuffer]

                     invoke VirtualAlloc, 0, ecx, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE

                     test eax, eax
                     jz close

                     mov edx, dword ptr [edi]

                     mov dword ptr [edi], eax

                     invoke copydata, edx, eax, dword ptr [_result]

                     invoke VirtualFree, edx, 0, MEM_RELEASE

                     mov eax, dword ptr [edi]

                     add eax, dword ptr [_result]

                     invoke copydata, dword ptr [esi + SecBuffer.pvBuffer], eax, dword ptr [esi + SecBuffer.cbBuffer]

                 .endif

                 mov eax, dword ptr [esi + SecBuffer.cbBuffer]
                 add dword ptr [_result], eax

             .elseif dword ptr [esi + SecBuffer.BufferType] == SECBUFFER_EXTRA

                 mov edx, dword ptr [Cbuffer]

                 add edx, dword ptr [cb]

                 mov ecx, dword ptr [esi + SecBuffer.cbBuffer]

                 add dword ptr [cb], ecx

                 mov dword ptr [scRet], SEC_I_CONTINUE_NEEDED

                 invoke copydata, dword ptr [esi + SecBuffer.pvBuffer], edx, dword ptr [esi + SecBuffer.cbBuffer]

             .endif

             inc ebx

         .endw

         cmp dword ptr [scRet], SEC_I_CONTINUE_NEEDED
         jz _recv

         jmp _ret

         close:

         invoke VirtualFree, dword ptr [edi], 0, MEM_RELEASE

         mov dword ptr [_result], NULL

     _ret:

     invoke VirtualFree, dword ptr [Cbuffer], 0, MEM_RELEASE

     mov eax, dword ptr [_result]

     ret

cryptrecv endp

этот код работает хорошо.но иногда DecryptMessage завершается с нарушением прав доступа.он не может прочитать данные из dword ptr [Cbuffer]

Я вижу это в отладчике.и после ошибки он говорит мне, что память из dword ptr [Cbuffer] не выделена

нарушение прав доступа произошло внутри функции api окон DecryptMessage.

инструкция, которая происходит

movzx ecx,байт ptr [edi + 3]

в edi размещенном адресе с dword ptr [Cbuffer]

...