我的代码实现了Caesar Cipher,它向用户询问输入文件的名称,其中包含我要加密/解密的字符串,输出文件的名称和密钥/密码,我的问题是它只阅读密钥的第一个数字,如果我给予它一个有两位数的数字作为密钥,那么它只读取第一个,如14,15,它只读取1。我该怎么解决这个问题?下面是代码:
.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
我认为问题出在atodw函数上:
invoke StdOut, addr keyPrompt
invoke StdIn, addr keyBuffer, 256
invoke atodw, addr keyBuffer
mov ecx, eax
1条答案
按热度按时间33qvvth11#
mov eax, eax
将EAX迁移到EAX没有什么意义看看你如何使用密钥(
sub al, byte ptr [keyBuffer]
和add al, byte ptr [keyBuffer]
),你应该这样写:还有更多的事情发生在这里!
sizeof buffer
)的双字。你不应该把它读成一个字节!这样做可能会丢失256或512个字节!简单地写为
mov ecx, [bytesRead]
一旦EDI中的句柄通过在循环中使用该寄存器而被销毁,您将无法成功关闭文件。
你可以在堆栈上保留句柄: