0

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 i need it to read the files in 512 bytes chunks, at the moment if i give it a file that is more than 512 bytes it only outputs the 512 bytes, 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 byte ptr [keyBuffer], al

    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

    @@readLoop1:
        invoke ReadFile, edi, addr buffer, sizeof buffer, addr bytesRead, NULL
        xor ecx, ecx
        mov ecx, dword ptr [bytesRead]
        cmp ecx, 0
        je @@endReadLoop1

        lea edi, [buffer]
        mov esi, edi
        mov edx, ecx

        @@loop1:
            mov al, byte ptr [esi]
            sub al, byte ptr [keyBuffer]
            mov byte ptr [edi], al

            inc esi
            inc edi
            dec edx
            jnz @@loop1

        ; Update ecx to the correct number of bytes read
        mov ecx, dword ptr [bytesRead]

        invoke WriteFile, ebx, addr buffer, ecx, addr bytesWritten, NULL

        jmp @@readLoop1
    @@endReadLoop1:
    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 byte ptr [keyBuffer], al

    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

    @@readLoop2:
        invoke ReadFile, edi, addr buffer, sizeof buffer, addr bytesRead, NULL
        xor ecx, ecx
        mov ecx, dword ptr [bytesRead]
        cmp ecx, 0
        je @@endReadLoop2

        lea edi, [buffer]
        mov esi, edi
        mov edx, ecx

        @@loop2:
            mov al, byte ptr [esi]
            add al, byte ptr [keyBuffer]
            mov byte ptr [edi], al

            inc esi
            inc edi
            dec edx
            jnz @@loop2

        ; Update ecx to the correct number of bytes read
        mov ecx, dword ptr [bytesRead]

        invoke WriteFile, ebx, addr buffer, ecx, addr bytesWritten, NULL        

        jmp @@readLoop2
    @@endReadLoop2:

    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

maybe the problem is on the WriteFile function, i dont know:

invoke WriteFile, ebx, addr buffer, ecx, addr bytesWritten, NULL
Lucas
  • 23
  • 4
  • 1
    It's not the writing, it's the reading. You mismanage the `edi` register so it is no longer the read file handle in the second iteration. – Jester May 29 '23 at 00:07
  • so maybe i should use a different handle for the ReadFile ? – Lucas May 29 '23 at 00:13
  • 3
    The `lea edi, [buffer]` destroys your handle. Either save and restore **properly** or use a different register if you still have a free one. – Jester May 29 '23 at 00:17
  • 1
    i used another register and it worked, thank you! – Lucas May 29 '23 at 00:33
  • 1
    @Lucas The problem with the EDI register was addressed in [my answer to your previous question](https://stackoverflow.com/questions/76352878/how-can-i-fix-my-caesar-cipher-implementation-in-assembly-language-to-read-multi/76352956#76352956). Maybe you missed the edit that I made to it... – Sep Roland May 29 '23 at 18:26
  • i missed it, sorry – Lucas May 29 '23 at 21:48

0 Answers0