Recently I have been trying to learn assembly x86 using NASM on a Windows platform, I am trying to make a function that reads a character from stdin ignoring any line feeds and carriage returns, but the problem is that when the function reaches the ret operation the program crashes, strangely when i run the function without the call to ReadConsoleA
the program finishes correctly.
Code:
section .bss
temp_char resb 1
bytes_written_holder resq 1
section .data
global _start
extern GetStdHandle, WriteConsoleA, ReadConsoleA, ExitProcess
section .text
getinput:
mov rcx, -10
call GetStdHandle
mov rcx, rax
mov rdx, temp_char
mov r8, 1
mov r9, bytes_written_holder
push 0
call ReadConsoleA
mov al, [temp_char]
cmp al, 0xa
je getinput
cmp al, 0xd
je getinput
ret
_start:
call getinput
mov rcx, -11
call GetStdHandle
mov rcx, rax
mov rdx, temp_char
mov r8, 1
mov r9, bytes_written_holder
push 0
call WriteConsoleA
mov rcx, 0
call ExitProcess
I am using NASM to assemble and GoLink to link:
nasm -f win64 printtest.s -o printtest.obj
GoLink.exe /console /entry _start printtest.obj kernel32.dll
Related
The assembly file is obtained by using gcc -g -S, and the part of .s file is as follows:
.L3:
.loc 1 22 11
mov eax, DWORD PTR -12[rbp]
mov edx, eax
mov rcx, QWORD PTR .refptr._ZSt4cout[rip]
call _ZNSolsEi
.loc 1 22 18
mov rdx, QWORD PTR .refptr._ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_[rip]
mov rcx, rax
call _ZNSolsEPFRSoS_E
.loc 1 23 7
mov DWORD PTR -12[rbp], 0
.loc 1 12 2
add DWORD PTR -4[rbp], 1
jmp .L6
What does .loc 1 22 11 stand for?
When the -g flag is added to gcc it directs the compiler to add debugging information. .loc appears only when the compiler generates debugging information with -g flag:
https://sourceware.org/binutils/docs-2.38/as/Loc.html#Loc
I'm writing a simple assembly program on Darwin x86_64 (MacOS 10.14.6) that creates a file (test.txt) and writes "E" to it. However, for some reason, the "E" is not written to the file. What am I doing wrong?
Here's my program:
global start
section .text
start:
;Create the file
mov rax, 0x2000005
mov rdi, fname
mov rsi, 0x200
mov rdx, 0o644
syscall
;Write to file
mov rdi, rax ;As far as I know, this uses the fd returned by creating a file (previous syscall)
mov rsi, msg
mov rdx, 1
mov rax, 0x2000004
syscall
;Exit
mov rax, 0x2000001
mov rdi, 0
syscall
section .data
msg: db "E" ;Message
fname: db "test.txt" ;File name
I have also tried this:
global start
section .text
start:
mov rax, 0x2000005
mov rdi, fname
mov rsi, 0x200
mov rdx, 0o644
syscall
mov rdi, rax
mov rsi, msg
mov rdx, 2
mov rax, 0x2000004
syscall
mov rax, 0x2000001
mov rdi, 0
syscall
section .data
msg: db "E", -1
fname: db "test.txt", 0
Yet neither work.
I found the answer:
I found that opening the file with create mode and write mode works.
global start
section .text
start:
;Open file with create mode and write mode
mov rax, 0x2000005
mov rdi, fname
mov rsi, 0x201
mov rdx, 0o644
syscall
;Now write
mov rdi, rax
mov rsi, msg
mov rdx, 1
mov rax, 0x2000004
syscall
;Exit
mov rax, 0x2000001
mov rdi, 0
syscall
section .data
msg: db "E"
fname: db "test.txt"
Also, here is an array of flags for opening files:
O_ACCMODE: 0x3
O_APPEND: 0x8
O_ASYNC: 0x40
O_CLOEXEC: 0x1000000
O_CREAT: 0x200
O_DIRECTORY: 0x100000
O_DSYNC: 0x400000
O_EXCL: 0x800
O_EXLOCK: 0x20
O_NDELAY: 0x4
O_NOCTTY: 0x20000
O_NOFOLLOW: 0x100
O_NONBLOCK: 0x4
O_RDONLY: 0x0
O_RDWR: 0x2
O_SHLOCK: 0x10
O_SYNC: 0x80
O_TRUNC: 0x400
O_WRONLY: 0x1
To combine, use the | operator (in C) or or (in assembly).
I recently started programming in assembly language and could get something wrong. This code is supposed to write out "21947392":
section .data
nl db 10
section .bss
number resb 19
.end resb 1
section .text
GLOBAL start
start:
mov rdi, 21947392
call _printNumber
mov rax, 0x2000001
xor rdi, rdi
syscall
_printNumber:
mov rcx, 10
mov rsi, number.end
mov rax, rdi
_loop:
xor rdx, rdx
div rcx
add rdx, 48
mov [rsi], rdx
dec rsi
cmp rax, 0
jne _loop
mov rdi, rsi
inc rdi
mov rsi, number.end
sub rsi, rdi
call _print
mov rdi, nl
mov rsi, 1
call _print
ret
_print:
mov rax, 0x2000004
mov rdx, rsi
mov rsi, rdi
mov rdi, 1
syscall
ret
It is written for macOS x64 on NASM and it only prints "2" (and seems to even differ from one assembly to another)...
Here are the commands I use in terminal:
nasm -f macho64 -o printNumber.o printNumber.asm
ld printNumber.o -o printNumber
./printNumber
Please, help find what's wrong.
I am trying to mimic Security Tubes execve tutorial (http://hackoftheday.securitytube.net/2013/04/demystifying-execve-shellcode-stack.html) in 64bit Asm. I am not sure where the bus error is coming from. I stepped through through the app in GDB but the error didn't occur until after I was out of frame. If anyone knows what is happening, I would love to hear from you.
.section __DATA,__data
.section __TEXT,__text
.globl _start
_start:
xor %rax, %rax
push %rax
movabsq $0x68732f6e69622f2f, %rdi
push %rax
mov %rsp, %rsi
push %rdi
mov %rsp, %rdx
mov $0x2000059, %rax
syscall
The following should work better but I don't have osx to test:
.globl _start
_start:
xor %edx, %edx ; NULL for env
movabsq $0x0068732f6e69622f, %rax ; /bin/sh<0>
push %rax
mov %rsp, %rdi ; filename
push %rdx ; NULL for argv terminator
push %rdi ; argv[0] = filename
mov %rsp, %rsi ; argv
mov $0x200003b, %eax ; I think 59 is decimal
syscall
In this application, I am trying to print a character passed through command line arguments (Intel Mac OS X). EX:
./thisapp q
Desired output:
q
However, it prints out a bunch of symbols and nonsense, but what is interesting is that different characters produce different gibberish. This leads me to believe that I am close. Does this need to be "formatted" for it to produce the correct letter?
.section __DATA,__data
.section __TEXT,__text
.globl _start
_start:
push %rbp
mov %rsp,%rbp
lea -32(%rsp), %r10 #<--- should be argv
add $8, %r10 #<--- should be argv[1]
movl $0x2000004, %eax
mov $1, %edi
mov %r10, %rsi
mov $16, %edx
syscall
xor %rax, %rax
mov $0x2000001, %eax
mov $0, %edi
syscall
Thanks to everyone's help I was able to get this working. Here is the code in the event someone else is looking to do this:
.section __DATA,__data
.section __TEXT,__text
.globl _start
_start:
push %rbp
mov %rsp,%rbp
lea 24(%rbp), %r10
movl $0x2000004, %eax
mov $1, %edi
mov (%r10), %rsi
mov $1, %edx
syscall
xor %rax, %rax
mov $0x2000001, %eax
mov $0, %edi
syscall
I would like to point out that this will only print 1 element (letter/number). I still need to figure out how to get the length(size?) of whatever was passed.