Linux NASM - Hiding Terminal Input [duplicate] - linux

This question already has answers here:
How do i read single character input from keyboard using nasm (assembly) under ubuntu?
(3 answers)
Reading input from keyboard with x64 linux syscalls (assembly)
(1 answer)
How to stop echo in terminal using c?
(1 answer)
Closed 2 years ago.
Is there a way to disable and enable the display of terminal input within an assembly program?
I am writing a command line program in nasm where user input it periodically read from the terminal (which I want to be displayed) and the program sleeps for certain lengths of time. During that time (unlike what I've found in the Windows command line) the user is still able to type in the terminal. I want to hide that text.
Here's a program that asks for a prompt and waits between certain message:
section .text
global _start
_start:
mov edx,lhello
mov ecx,mhello
mov ebx,1
mov eax,4 ; sys_write
int 0x80
mov dword[sleep_sec],1
mov dword[sleep_usec],0
mov ecx,0
mov ebx,sleep
mov eax,162 ; sys_nanosleep
int 0x80
mov edx,lwrite
mov ecx,mwrite
mov ebx,1
mov eax,4 ; sys_write
int 0x80
mov edx,99
mov ecx,usergift
mov ebx,0
mov eax,3 ; sys_read
int 0x80
mov edx,lsleep
mov ecx,msleep
mov ebx,1
mov eax,4 ; sys_write
int 0x80
mov dword[sleep_sec],2
mov dword[sleep_usec],0
mov ecx,0
mov ebx,sleep
mov eax,162 ; sys_nanosleep
int 0x80
mov edx,ldone
mov ecx,mdone
mov ebx,1
mov eax,4 ; sys_write
int 0x80
mov eax,1 ; sys_exit
int 0x80 ; the end!
section .bss
usergift resb 99
section .data
sleep:
sleep_sec dd 0
sleep_usec dd 0
mhello db 'hello-',0xA
lhello equ $ - mhello
mwrite db 'give me something:'
lwrite equ $ - mwrite
msleep db 'wait for 2 seconds...',0xA
lsleep equ $ - msleep
mdone db 'thank you.',0xA
ldone equ $ - mdone
gives the following output when love is inputted by the user when prompted-
hello-
give me something:love
wait for 2 seconds...
thank you.
but the user is also able to write outside of the prompt-
hello-
ha!give me something:love
wait for 2 seconds...
lies!thank you.

Related

NASM - How can I solve the input reading problem from the terminal? [duplicate]

This question already has answers here:
Read STDIN using syscall READ in Linux: unconsumed input is sent to bash
(2 answers)
Closed 4 months ago.
section .data
yourinputis db "your input is =",0
len equ $ - yourinputis
section .bss
msginput resb 10
section .text
global _start
_start:
mov eax,3 ;read syscall
mov ebx,2
mov ecx,msginput
mov edx,9 ; I don't know that is correct?
int 80h
mov eax,4 ;write syscall
mov ebx,1
mov ecx,yourinputis
mov edx,len
int 80h
mov eax,4 ;write syscall
mov ebx,1
mov ecx,msginput
mov edx,10
int 80h
exit:
mov eax,1 ;exit syscall
xor ebx,ebx
int 80h
This code working very well. But It is so terrible bug(for me:(). If I enter an input longer than 10 --->
$./mycode
012345678rm mycode
your input is 012345678$rm mycode
$
This is happening. And of course "mycode" is not exist right now.
What should I do?
EDIT:The entered input is correctly printed on the screen. But if you enter a long input, it moves after the 9th character to the shell and runs it.
In the example, the "rm mycode" after "012345678" is running in the shell.
If you enter more than 9 characters, they're left in the terminal driver's input buffer. When the program exits, the shell reads from the terminal and tries to execute the rest of the line as a command.
To prevent this, your program should keep reading in a loop until it gets a newline.
You can read the characters one by one until you reach 0x0a. Something like:
_read:
mov esi, msginput
_loop:
mov eax,3 ;read syscall
mov ebx,0
mov ecx, esi
mov edx,1 ; I don't know that is correct?
int 80h
cmp byte[esi], 0x0a
je end
inc esi
jmp _loop
end:
ret
You would have to increase the size of msginput tho.
IMPORTANT: Do note that this is not the efficient way to do this (see the comments), it is only put here as an example to the answer above.

Linux NASM - Drain Terminal Input Without Prompt [duplicate]

This question already has answers here:
How do I discard user input delivered during sleep function?
(3 answers)
Prevent reading of previous / prior user keyboard input from sys.stdin, that works with Click
(1 answer)
Closed 2 years ago.
I want to drain terminal input before prompting the user, or otherwise to close the terminal input until I want to prompt the user for input.
I am writing a program that uses sys_read to prompt the user for input through the terminal. If a user types characters before being prompted, those characters get included in the input. I can easily drain every unread character after the prompt using sys_read again, but it relies on a return character being at the end of the stream of input to prevent prompting the user more than once (I am assuming the user ends every prompt with the return key). I can't rely on the presence of a return character before the prompt, so I can't drain the input the same way.
I have also tried closing stdin with sys_close, but I can't figure out how to open terminal input again, so the program is left frozen when a prompt comes up. Even if I could open the terminal input again, I'm not sure whether or not characters typed while it's closed still get saved for the next time it's read, which would render this approach completely useless.
If there is some sort of obscure termios flag that could disable user input, that would also be an excellent solution.
Here's a program, for example:
global _start
_start:
mov edx,ldot
mov ecx,mdot
mov ebx,1
mov eax,4 ; sys_write
int 0x80
mov dword[sleep_sec],1
mov dword[sleep_usec],0
mov ecx,0
mov ebx,sleep
mov eax,162 ; sys_nanosleep
int 0x80
mov edx,ldesire
mov ecx,mdesire
mov ebx,1
mov eax,4 ; sys_write
int 0x80
call input ; here's the call...
mov edx,lreceive
mov ecx,mreceive
mov ebx,1
mov eax,4 ; sys_write
int 0x80
mov dword[sleep_sec],1
mov dword[sleep_usec],0
mov ecx,0
mov ebx,sleep
mov eax,162 ; sys_nanosleep
int 0x80
mov edx,99
mov ecx,inputed
mov ebx,1
mov eax,4 ; sys_write
int 0x80
mov eax,1 ; sys_exit
int 0x80 ; the end!
input: ; here is all that I am concerned about
mov edx,99
mov ecx,inputed
mov ebx,0 ; stdin
mov eax,3 ; sys_read
int 0x80
cmp eax,99 ; check for valid input
jl inputdone
cmp byte[inputed+98],0xa
je inputdone
inputclear: ; drain
mov eax,3
int 0x80
cmp eax,99
jl inputerror
cmp byte[inputed+98],0xa
je inputerror
jmp inputclear
inputerror:
mov eax,-1
ret
inputdone:
mov eax,1
ret
section .bss
inputed resb 99
section .data
sleep:
sleep_sec dd 0
sleep_usec dd 0
mdot db '...',0xA
ldot equ $ - mdot
mdesire db 'tell me your truest desire:'
ldesire equ $ - mdesire
mreceive db 'you shall receive... '
lreceive equ $ - mreceive
A user who does things when they are told will find no trouble:
...
tell me your truest desire:money
you shall receive... money
But a user who likes to press buttons as they please will struggle:
...
a gtell me your truest desire:love
you shall receive... a glove
And the program won't wait for anyone who makes a mess with the return key:
...
who
tell me your truest desire:you shall receive... who

Converting user input to all caps in assembly (NASM) [duplicate]

This question already has answers here:
X86 NASM Assembly converting lower to upper and upper to lowercase characters
(5 answers)
X86 Assembly Converting lower-case to uppercase
(1 answer)
Closed 3 years ago.
I want to change the string to all caps, although I am having trouble getting the length of the input. What i have tried so far is moving the address of the message into a registrar then indexing through the string and also increment a counter variable. Then comparing the char in the address to a '.' (signifying the end of the message) and if its found not to be equal it will recall this block of statements. At least this is what I want my code to do. Not sure if this is even the right logic. I know there are alot of errors and its messy but I'm learning so please just focus on my main question. thank you! EDIT: the input i use is 'this is a TEST.'
;nasm 2.11.08
SYS_Write equ 4
SYS_Read equ 3
STDIN equ 0
STDOUT equ 1
section .bss
message resb 15
counter resb 2
section .data
msg1: db 'Enter input (with a period) that I will turn into all capitals!',0xa ;msg for input
len1 equ $- msg1
section .text
global _start
_start:
mov eax, SYS_Write ; The system call for write (sys_write)
mov ebx, STDOUT ; File descriptor 1 - standard output
mov ecx, msg1 ; msg to print
mov edx, len1 ; len of message
int 0x80 ; Call the kernel
mov eax, SYS_Read ;system call to read input
mov ebx, STDIN ;file descriptor
mov ecx, message ;variable for input
mov edx, 15 ;size of message
int 0x80 ;kernel call
mov [counter], byte '0'
getLen:
mov eax, message
add eax, [counter]
inc byte [counter]
cmp eax, '.'
jne getLen
mov eax, SYS_Write ; this is to print the counter to make sure it got the right len
mov ebx, STDOUT
mov ecx, counter
mov edx, 2
int 0x80
jmp end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov eax, [message]
;add eax, counter
cmp eax, 90
jg toUpper
toUpper:
sub eax, 32
mov [message], eax
mov eax, SYS_Write ; The system call for write (sys_write)
mov ebx, STDOUT ; File descriptor 1 - standard output
mov ecx, message ; Put the offset of hello in ecx
mov edx, 10 ; helloLen is a constant, so we don't need to say
int 0x80 ; Call the kernel
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
end:
mov eax,1 ; The system call for exit (sys_exit)
mov ebx,0 ; Exit with return code of 0 (no error)
int 0x80 ;

Assembly on Linux: unexpected behaviour from Assembly [duplicate]

This question already has answers here:
In NASM labels next to each other in memory are printing both strings instead of first one
(1 answer)
How does $ work in NASM, exactly?
(2 answers)
Closed 4 years ago.
running the code below generates a file with Welcome to jj Shashwat as content. what i didn't get is why does it writes Shashwat at the end of the file, Shashwat is in a totally different variable. Any idea why does this happen?
section .text
global _start ;must be declared for using gcc
_start:
;create the file
mov eax, 8
mov ebx, file_name
mov ecx, 0777 ;read, write and execute by all
int 0x80 ;call kernel
mov [fd_out], eax
; close the file
mov eax, 6
mov ebx, [fd_out]
;open the file for reading
mov eax, 5
mov ebx, file_name
mov ecx, 2 ;for read/write access
mov edx, 0777 ;read, write and execute by all
int 0x80
mov [fd_out], eax
; write into the file
mov edx,len ;number of bytes
mov ecx, msg ;message to write
mov ebx, [fd_out] ;file descriptor
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
; close the file
mov eax, 6
mov ebx, [fd_out]
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data
file_name db 'myfile.txt', 0
msg db 'Welcome to jj', 0
mgafter db ' Shashwat', 0
lntwo equ $-mgafter
len equ $-msg
section .bss
fd_out resb 1
fd_in resb 1
info resb 26
That's because you said len equ $-msg after defining both msg and msgafter, so len is set to the length of both msg and msgafter, making your write call write both strings. This is because len equ $-msg means “set len to be the difference between the current location ($) and the location of msg.”
To fix this, move the len equ $-msg line right after the definition of msg.

Why can't I sys_write from a pointer to stack memory, using int 0x80? [duplicate]

This question already has an answer here:
What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?
(1 answer)
Closed 4 years ago.
; NASM
push 30 ; '0'
mov rax, 4 ; write
mov rbx, 1 ; stdout
mov rcx, rsp ; ptr to character on stack
mov rdx, 1 ; length of string = 1
int 80h
The code above does not print anything to stdout. It works when i give it a ptr to a character in section .data. What am i doing wrong?
amd64 uses a different method for system calls than int 0x80, although that might still work with 32-bit libraries installed, etc. Whereas on x86 one would do:
mov eax, SYSCALL_NUMBER
mov ebx, param1
mov ecx, param2
mov edx, param3
int 0x80
on amd64 one would instead do this:
mov rax, SYSCALL_NUMBER_64 ; different from the x86 equivalent, usually
mov rdi, param1
mov rsi, param2
mov rdx, param3
syscall
For what you want to do, consider the following example:
bits 64
global _start
section .text
_start:
push 0x0a424242
mov rdx, 04h
lea rsi, [rsp]
call write
call exit
exit:
mov rax, 60 ; exit()
xor rdi, rdi ; errno
syscall
write:
mov rax, 1 ; write()
mov rdi, 1 ; stdout
syscall
ret
30 decimal is the code of the ASCII "record separator". Whatever that is, it's probably not a printable character.
30 hexadecimal (30h or 0x30 in NASM parlance), on the other hand, is the code of the ASCII "0".
Also, you need to use the 64-bit ABI.

Resources