Author Topic: Displaying * on terminal instead of characters?  (Read 10842 times)

Offline sandeepyadav

  • Jr. Member
  • *
  • Posts: 8
Displaying * on terminal instead of characters?
« on: September 07, 2013, 04:53:05 PM »

I want to perform password checking. So, the entered character should be displayed as *.
If 5 characters are entered, ***** should be displayed.

Thanks & regards,
Sandeep

Offline encryptor256

  • Full Member
  • **
  • Posts: 250
  • Country: lv
  • Win64 .
    • On Youtube: encryptor256
Re: Displaying * on terminal instead of characters?
« Reply #1 on: September 07, 2013, 05:36:15 PM »
Hi!

In background you can do a lot of things, but for display,
display is informational, so, for each key press display one '*'.
Encryptor256's Investigation \ Research Department.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Displaying * on terminal instead of characters?
« Reply #2 on: September 07, 2013, 09:22:40 PM »
In DOS, this is easy - there's a "no echo input" interrupt service for int 21h (two of them, in fact). I don't know how Windows does it - SetConsoleMode, I suspect. As I recall, you're using Linux - 64-bit Linux. I don't know that one, either, but I do have a 32-bit routine which may help. It'll need some adjustment for 64-bit, but I suspect it's pretty similar...

Code: [Select]
; ...
; misc. equates
%define NL 10
%define STDIN 0
%define STDOUT 1

; sys_calls
%define SYS_EXIT 1
%define SYS_READ 3
%define SYS_WRITE 4
%define SYS_IOCTL 54
;...

;-----------------------------
; ioctl subfunctions
%define TCGETS 0x5401 ; tty-"magic"
%define TCSETS 0x5402

; flags for 'em
%define ICANON 2 ;.Do erase and kill processing.
%define ECHO 8 ;.Enable echo.


    struc termios
alignb 4
.c_iflag: resd 1 ; input mode flags
.c_oflag: resd 1 ; output mode flags
.c_cflag: resd 1 ; control mode flags
.c_lflag: resd 1 ; local mode flags
.c_line: resb 1 ; line discipline
.c_cc: resb 19 ; control characters
    endstruc
;---------------------------------

getc:
    push ebp
    mov ebp, esp
   
    sub esp, termios_size     ; make a place for current kbd mode
   
    push edx
    push ecx
    push ebx
   
    mov eax, SYS_IOCTL        ; get current mode
    mov ebx, STDIN
    mov ecx, TCGETS
    lea edx, [ebp - termios_size]
    int 80h
   
                              ; monkey with it
    and dword [ebp - termios_size + termios.c_lflag], ~(ICANON | ECHO)

    mov eax, SYS_IOCTL
    mov ebx, STDIN
    mov ecx, TCSETS
    lea edx, [ebp - termios_size]
    int 80h
   
    xor eax, eax
    push eax         ; this is the buffer to read into
     
    mov eax, SYS_READ
    mov ebx, STDIN
    mov ecx, esp     ; character goes on the stack
    mov edx, 1       ; just one
    int 80h          ; do it
                     
                     ; restore normal kbd mode
    or dword [ebp - termios_size + termios.c_lflag], ICANON | ECHO
   
    mov eax, SYS_IOCTL 
    mov ebx, STDIN
    mov ecx, TCSETS
    lea edx, [ebp - termios_size]
    int 80h
   
    pop eax          ; get character into al

    pop ebx          ; restore caller's regs
    pop ecx
    pop edx
   
    mov esp, ebp     ; leave
    pop ebp
    ret
;-------------------------

This is defective in several ways. I only use one copy of the termios structure, modify it in place, set the new configuration, then modify it back... This ASSumes that we had a "normal" configuration to begin with - if not, I've just messed it up. Better to use two copies. I've seen code that uses TCGETS twice, but I suspect it's much faster to copy the structure. Modify the copy and TCSETS from that, then TCSETS to the original when we're done. The other thing is that if we recieve certain signals while we're waiting for a key, it'll put us back in "wait for 'enter' " (and echo) mode. SIGSUSP for sure, and I think SIGWINCH will do it, too. I can live with this for my naive purposes, but it needs a lot of improvement! This counts as "teaching sloppy solutions to beginners" and I really shouldn't do it! You'll need to print the '*' for each character by normal methods, of course.

Give it a shot, and ask again if you have trouble.

Best,
Frank