我对汇编语言非常陌生,并且试图编写一个简单的程序。它获得一个不应该显示在控制台中的用户输入(密码)。
对于正常输入,我使用Irvine32库,如下所示。但是这个方法显示输入用户输入,对于像密码这样的输入,这应该是隐藏的,我不知道该如何做。
INCLUDE Irvine32.inc
.data
idPromptStr byte "Please enter ID : ", 13, 10, 0
id DWORD ?
.code
main proc
mov edx,OFFSET idPromptStr
call WriteString
call ReadInt ;Reads the integer value from console and moves it to eax.
mov id,eax ;Input value is taken in eax.
main endp
end main发布于 2021-05-09 16:31:53
TL;DR您需要使用GetConsoleMode和SetConsoleMode从控制台模式中清除ENABLE_ECHO_INPUT位。
ReadString在内部使用ReadConsoleA,使用Windows为控制台子系统自动创建的可执行控制台(即使用GetStdHandle检索控制台输入和输出句柄)。

每当ReadConsoleA将或不回显字符时,读取字符取决于控制台模式。
具体来说,当清除标志ENABLE_ECHO_INPUT (值0x4)时,将防止字符回显。
要获得当前的控制台模式,请使用GetConsoleMode,清除ENABLE_ECHO_INPUT位和ENABLE_ECHO_INPUT (即and rm32, ~ENABLE_ECHO_INPUT中的and rm32, ~ENABLE_ECHO_INPUT)的否定模式。
然后用这个新值设置控制台模式。
下面是禁用和重新启用回波的函数:
;No args, return the console mode to pass to EnableEcho
DisableEcho:
push esi
push edi
;-- Get console input handle ---
push STD_INPUT_HANDLE
call _GetStdHandle@4
mov esi, eax
;-- Clear the ENABLE_ECHO_INPUT bit --
sub esp, 04
push esp
push eax
call _GetConsoleMode@8
pop eax
mov edi, eax
and eax, ~ENABLE_ECHO_INPUT
push eax
push esi
call _SetConsoleMode@8
mov eax, edi
pop edi
pop esi
ret
;edx = value returned from DisableEcho
EnableEcho:
;-- Get console input handle ---
push STD_INPUT_HANDLE
call _GetStdHandle@4
;-- Set mode --
push edx
push eax
call _SetConsoleMode@8
ret Note这段代码是为NASM编写的,并将与微软的链接链接。让它适应你的工具。
DisableEcho返回必须传递给EnableEcho的原始控制台模式(按照欧文的调用约定,在edx中)。
比如:
call DisableEcho
;Here echo is disabled when calling ReadXXX
mov edx, eax ;Assuming eax has been preserved
call EnableEcho根据您的需要调整代码,我没有使用全局变量,因为与Irvine相反,只要可能,我更喜欢纯函数。
有些人发现缺乏全局变量很难理解。
下面是一个完整的程序,它将读取用户名、密码和OTP代码(只是为了显示在密码提示之前和之后启用了echo ),然后将所有这些代码打印出来。
BITS 32
GLOBAL _start
%define STD_INPUT_HANDLE -10
%define ENABLE_ECHO_INPUT 4
%define STRLEN 82
EXTERN _ReadString@0
EXTERN _ExitProcess@4
EXTERN _SetConsoleMode@8
EXTERN _GetConsoleMode@8
EXTERN _GetStdHandle@4
EXTERN _WriteString@0
SECTION .bss
myUsername resb STRLEN
myPassword resb STRLEN
myOTP resb STRLEN
SECTION .data
strUsername db "Username: ", 0
strPassword db "Password:", 0
strOTP db 13, 10, "OTP code: ", 0
strCRLF db 13, 10, 0
SECTION .text
_start:
;-- Read the username --
mov edx, strUsername
call _WriteString@0
mov edx, myUsername
mov ecx, STRLEN
call _ReadString@0
;-- Disable echo --
call DisableEcho
mov esi, eax
;-- Read the password --
mov edx, strPassword
call _WriteString@0
mov edx, myPassword
mov ecx, STRLEN
call _ReadString@0
;-- Restore the echo ---
mov edx, esi
call EnableEcho
;-- Read the otp --
mov edx, strOTP
call _WriteString@0
mov edx, myOTP
mov ecx, STRLEN
call _ReadString@0
;-- Show --
mov edx, myUsername
call _WriteString@0
mov edx, strCRLF
call _WriteString@0
mov edx, myPassword
call _WriteString@0
mov edx, strCRLF
call _WriteString@0
mov edx, myOTP
call _WriteString@0
;-- Exit --
push 0
call _ExitProcess@4
;No args, return the console mode to pass to EnableEcho
DisableEcho:
push esi
push edi
;-- Get console input handle ---
push STD_INPUT_HANDLE
call _GetStdHandle@4
mov esi, eax
;-- Clear the ENABLE_ECHO_INPUT bit --
sub esp, 04
push esp
push eax
call _GetConsoleMode@8
pop eax
mov edi, eax
and eax, ~ENABLE_ECHO_INPUT
push eax
push esi
call _SetConsoleMode@8
mov eax, edi
pop edi
pop esi
ret
;edx = value returned from DisableEcho
EnableEcho:
;-- Get console input handle ---
push STD_INPUT_HANDLE
call _GetStdHandle@4
;-- Set mode --
push edx
push eax
call _SetConsoleMode@8
ret https://stackoverflow.com/questions/67457224
复制相似问题