【问题标题】:x86 Assembly, How to get a user input wihout it being displayed in console?x86 程序集,如何在不显示在控制台中的情况下获取用户输入?
【发布时间】:2021-07-31 01:50:50
【问题描述】:

我对汇编语言非常陌生,并试图编写一个简单的程序。它获取不应在控制台中显示的用户输入(密码)。

对于普通输入,我像这样使用 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

【问题讨论】:

  • 你需要使用GetConsoleMode,清除位2,然后SetConsoleMode。我已经有一个工作示例。如果没有人同时发布,我稍后会发布答案。

标签: assembly x86 masm irvine32


【解决方案1】:

TL;DR您需要从控制台模式中清除ENABLE_ECHO_INPUT 位,使用GetConsoleModeSetConsoleMode

ReadString 在内部使用 ReadConsoleA,使用 Windows 自动为控制台子系统的可执行文件创建的控制台(即,它使用 GetStdHandle 检索控制台输入和输出句柄)。

ReadConsoleA 是否会回显读取的字符取决于控制台模式
具体来说,标志 ENABLE_ECHO_INPUT(值 0x4)在清除后将阻止回显字符。

要获得当前的控制台模式,请使用GetConsoleMode,清除ENABLE_ECHO_INPUT 位和取反的ENABLE_ECHO_INPUT 模式(即NASM 中的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 

注意此代码是为 NASM 编写的,并与 Microsoft 的 link 链接。使其适应您的工具。

DisableEcho 返回必须传递给EnableEcho 的原始控制台模式(在edx 中,按照欧文的调用约定)。
喜欢:

call DisableEcho

;Here echo is disabled when calling ReadXXX

mov edx, eax              ;Assuming eax has been preserved
call EnableEcho

根据您的需要调整代码,我没有使用全局变量,因为与 Irvine 相反,我更喜欢纯函数。
有些人发现缺少全局变量更难理解。

这是一个完整的程序,它将读取用户名、密码和 OTP 代码(只是为了显示在密码提示之前启用了回显)和然后将它们全部打印出来。

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  

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-01
    • 1970-01-01
    • 2013-04-13
    • 1970-01-01
    • 2011-06-12
    • 1970-01-01
    • 2012-11-30
    相关资源
    最近更新 更多