My code implements the Caesar Cipher, it asks the user the name of the input file which contains the string i want to be encrypted/decrypted, the name of the output file and the key/cipher, my problem is that it is only reading the first number of the key, if i give it a number with two digits as a key then it only reads the first, like 14, 15, it only reads the 1. How can i fix this? Here is the code:
.686
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
.data
; Strings do menu e prompts
menuTitle db "Cifra de Cesar",13,10,0
option1 db "1. Descriptografar",13,10
option2 db "2. Criptografar",13,10
option3 db "3. Criptoanalise",13,10
option4 db "4. Sair",13,10
menuPrompt db "Escolha uma opcao:",0
filePrompt db "Digite o nome do arquivo de entrada:",0
outFilePrompt db "Digite o nome do arquivo de saida:",0
keyPrompt db "Digite a chave (1 a 20):",0
; Buffers e variáveis auxiliares
inputFileBuffer db 10240 dup(0)
outputFileBuffer db 10240 dup(0)
outputBuffer db 10240 dup(0)
userInputBuffer db 256 dup(0)
buffer db 512 dup(0)
keyBuffer db 256 dup(0)
console_count dd 0
inputHandle dd 0
outputHandle dd 0
bytesRead dd 0
bytesWritten dd 0
.code
start:
; Obtém os handles de entrada e saída padrão
invoke GetStdHandle, STD_INPUT_HANDLE
mov inputHandle, eax
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov outputHandle, eax
menuLoop:
; Exibe o menu de opções e lê a escolha do usuário
invoke WriteConsole, outputHandle, addr menuTitle, sizeof menuTitle, addr console_count, NULL
invoke WriteConsole, outputHandle, addr option1, sizeof option1, addr console_count, NULL
invoke WriteConsole, outputHandle, addr option2, sizeof option2, addr console_count, NULL
invoke WriteConsole, outputHandle, addr option3, sizeof option3, addr console_count, NULL
invoke WriteConsole, outputHandle, addr option4, sizeof option4, addr console_count, NULL
invoke WriteConsole, outputHandle, addr menuPrompt, sizeof menuPrompt, addr console_count, NULL
invoke ReadConsole, inputHandle, addr userInputBuffer, sizeof userInputBuffer, addr console_count, NULL
; Verifica a opção escolhida e executa a ação correspondente
mov al, byte ptr [userInputBuffer]
cmp al, '4'
je exitProgram
cmp al, '1'
je descriptografar
cmp al, '2'
je criptografar
cmp al, '3'
je criptoanalise
jmp menuLoop
descriptografar:
; Solicita e lê os nomes dos arquivos de entrada, saída e chave
invoke StdOut, addr filePrompt
invoke StdIn, addr inputFileBuffer, 10240
invoke StdOut, addr outFilePrompt
invoke StdIn, addr outputFileBuffer, 10240
invoke StdOut, addr keyPrompt
invoke StdIn, addr keyBuffer, 256
invoke atodw, addr keyBuffer
mov ecx, eax
invoke CreateFile, addr inputFileBuffer, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
mov edi, eax
invoke CreateFile, addr outputFileBuffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
mov ebx, eax
invoke ReadFile, edi, addr buffer, sizeof buffer, addr bytesRead, NULL
xor ecx, ecx
mov cl, byte ptr [bytesRead]
lea edi, [buffer]
mov esi, edi
@@loop1:
mov al, byte ptr [esi]
sub al, byte ptr [keyBuffer]
mov byte ptr [edi], al
inc esi
inc edi
loop @@loop1
; Atualize o valor de ecx para o número correto de bytes lidos
mov ecx, [bytesRead]
invoke WriteFile, ebx, addr buffer, ecx, addr bytesWritten, NULL
invoke CloseHandle, edi
invoke CloseHandle, ebx
jmp menuLoop
criptografar:
invoke StdOut, addr filePrompt
invoke StdIn, addr inputFileBuffer, 10240
invoke StdOut, addr outFilePrompt
invoke StdIn, addr outputFileBuffer, 10240
invoke StdOut, addr keyPrompt
invoke StdIn, addr keyBuffer, 256
invoke atodw, addr keyBuffer
mov ecx, eax
invoke CreateFile, addr inputFileBuffer, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
mov edi, eax
invoke CreateFile, addr outputFileBuffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
mov ebx, eax
invoke ReadFile, edi, addr buffer, sizeof buffer, addr bytesRead, NULL
xor ecx, ecx
mov cl, byte ptr [bytesRead]
lea edi, [buffer]
mov esi, edi
@@loop2:
mov al, byte ptr [esi]
add al, byte ptr [keyBuffer]
mov byte ptr [edi], al
inc esi
inc edi
loop @@loop2
; Atualize o valor de ecx para o número correto de bytes lidos
mov ecx, [bytesRead]
invoke WriteFile, ebx, addr buffer, ecx, addr bytesWritten, NULL
invoke CloseHandle, edi
invoke CloseHandle, ebx
jmp menuLoop
criptoanalise:
invoke StdOut, addr filePrompt
invoke StdIn, addr inputFileBuffer, 256
jmp menuLoop
exitProgram:
invoke ExitProcess, 0
end start
I think the problem is with the atodw function:
invoke StdOut, addr keyPrompt
invoke StdIn, addr keyBuffer, 256
invoke atodw, addr keyBuffer
mov ecx, eax
invoke atodw, addr keyBuffer mov eax, eax
mov eax, eax
There's little point in moving EAX to EAX
Seeing how you use the key (sub al, byte ptr [keyBuffer]
and add al, byte ptr [keyBuffer]
), you should write:
invoke atodw, addr keyBuffer
mov byte ptr [keyBuffer], al
There's more going on here!
xor ecx, ecx mov cl, byte ptr [bytesRead]
BytesRead is a dword that is limited to 512 (sizeof buffer
). You should not be reading this as a byte! You risk loosing 256 or 512 bytes from doing so!
Simply write mov ecx, [bytesRead]
lea edi, [buffer] ... <<< the loop invoke CloseHandle, edi invoke CloseHandle, ebx
You won't be able to successfully close the file once the handle in EDI gets destroyed by using that register in the loop(s).
You could preserve the handle on the stack:
lea edi, [buffer]
push edi
... <<< the loop
pop edi
invoke CloseHandle, edi
invoke CloseHandle, ebx