функция для 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]