unable to print characters in assembly [duplicate] - linux

This question already has an answer here:
Using interrupt 0x80 on 64-bit Linux [duplicate]
(1 answer)
Closed 1 year ago.
I am trying to print the character h in assembly, but it is not outputting anything right now. I see no reason, nor can I understand why this is not working.
I would believe that it is because I am using %rbp instead of %eax but I am reasonably new to assembly, and I do not know whether writing to the %rbp register instead of %eax makes a difference.
.section .text
.global _start
_start:
mov %eax, %edi
call main
movl $1, %eax
int $0x80
main:
pushq %rbp
movq %rsp, %rbp
movl $4, %eax
movl $1, %ebx
push $0x068
movl $5, %edx
movq %rbp, %rsp
syscall
popq %rbp
ret
The code is compiled with
> as $(BIN_DIR)/assembly.asm -o $(BIN_DIR)/a.o
> ld $(BIN_DIR)/a.o -o $(BIN_DIR)/a

I looked up the structure in e.g. Free Pascal sources which somewhat illustrates how parameters are allocated and how success is determined.
movq sysnr, %rax { Syscall number -> rax. }
// for calls that have less parameters, just skip the relevant lines that load it
movq param1, %rdi { shift arg1 - arg5. }
movq param2, %rsi
movq param3, %rdx
movq param4, %r10
movq param5, %r8
movq param6, %r9
syscall { Do the system call. }
cmpq $-4095, %rax { Check %rax for error. }
jnae .LSyscOK { Jump to error handler if error. }
negq %rax
movq %rax,%rdi
call seterrno // call some function to set errno threadvar
movq $-1,%rax
.LSyscOK: // end of procedure

Related

illegal instruction gnu assembly

.globl start
.section .text
_start:
movq $2, %rbx
movq $3, %rcx
movq $1, %rax
mainloop:
addq $0, %rcx
jz complete
mulq %rbx
decq %rcx
jmp mainloop
complete:
movq %rax, %rdi
movq $60, %rax
syscall
I have been trying to run this code, but keep getting an
illegal instruction
through the assembler.
I cannot figure why it is supposed to run through GNU assembler.

How do canary words allow gcc to detect buffer overflows?

I could test using strncpy() with larger source string then the destination:
int main() {
char *ptr = malloc(12);
strcpy(ptr,"hello world!");
return 0;
}
Compiling with the flag -fstack-protector and using the -S option I got:
.file "malloc.c"
.text
.globl main
.type main, #function
main:
.LFB2:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $32, %rsp
movl %edi, -20(%rbp)
movq %rsi, -32(%rbp)
movq %fs:40, %rax
movq %rax, -8(%rbp)
xorl %eax, %eax
movq $0, -16(%rbp)
movl $12, %edi
call malloc
movq %rax, -16(%rbp)
movq -16(%rbp), %rax
movabsq $8022916924116329800, %rdx
movq %rdx, (%rax)
movl $560229490, 8(%rax)
movb $0, 12(%rax)
movl $0, %eax
movq -8(%rbp), %rcx
xorq %fs:40, %rcx
je .L3
call __stack_chk_fail
.L3:
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE2:
.size main, .-main
Could someone explain to me how this works? And why isn't the "canary word" also overwritten by the \0 of the hello world! string?
Could someone explain to me how does this work ?
Canary word is read from fs:40 and store at top of frame here:
movq %fs:40, %rax
movq %rax, -8(%rbp)
It's below the return address so if your code happens to overflow the buffer (which will be below -8(%rbp)), it'll first overwrite the -8(%rbp) location. This will be detected by GCC prior to issuing ret here:
movq -8(%rbp), %rcx
xorq %fs:40, %rcx ; Checks that %fs:40 == -8(%rbp)
je .L3 ; Ok, return
call __stack_chk_fail ; Die
as overwritten contents of -8(%rbp) will likely to be different from proper value (installed from fs:40).
And why is not the canary word also overwritten by the \0 of the hello world!?
Your code has heap overflow, not buffer overflow so SSP can't help...

Segmentation error upon calling scanf in x86_64 AT&T

I am quite new to Assembly and I am trying to create a program that uses scanf to receive a number from the user. It then outputs "Result: (the number)"
I keep getting a segmentation error upon running the code.
This is the code I have got now:
.global main
mystring: .asciz"input\n"
formatstring: .asciz" %d"
resultstring: .asciz "Result: %ld\n"
main:
movq $0, %rax
movq $mystring, %rdi
call printf
call inout
movq $0, %rax
movq $resultstring, %rdi
call printf
jmp end
inout:
pushq %rbp
subq $8, %rsp
leaq -8(%rbp), %rsi
movq $formatstring, %rdi
movq $0, %rax
call scanf
popq %rbp
ret
end:
movq $0, %rdi
call exit
I suspect there is something wrong with the 'inout' method. Any solutions to make this program working?
leaq -8(%rbp), %rsi
In this instruction you are referring to the %rbp register but you forgot to actually initialize it!

how do I call a external function in assembler?

I have tried to use an external function in assembly code:
.section .rodata
.LC0:
.string "My number is: %lld"
.text
.globl start
start:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
movq $12345, -8(%rbp)
movq -8(%rbp), %rax
movq %rax, %rsi
movl $.LC0, %edi
movl $0, %eax
call printf # my external function
# exit-syscall
mov $1, %eax
mov $0, %ebx
int $0x80
I assembled and linked with:
as -o myObjfile.o mySourcefile.s
ld -e start -o myProgram -lc myObjfile.o
The executable is build, but it doesn't run, so what's wrong with it?
If I understand correctly if the function you want to call is in the C library you can just declare it as an external function.
.section .rodata
.LC0:
.string "My number is: %lld"
.text
.extern printf #declaring the external function
.globl start
start:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
movq $12345, -8(%rbp)
movq -8(%rbp), %rax
movq %rax, %rsi
movl $.LC0, %edi
movl $0, %eax
call printf # my external function
# exit-syscall
mov $1, %eax
mov $0, %ebx
int $0x80
If this doesn't work try linking it explicitly with stdlib.h

Assembly - Why strtol clobbers %rcx register?

Context :
Linux 64.
GCC 4.8.2 (with -O3 -march=native)
The x86_64 abi under my left hand, opened at page 21.
The C code :
int main (int argc, char ** argv) {
printf("%d %s\n", atoi(argv[2]),argv[1] );
}
The assembly code :
(notice that the compiler replaced atoi with strtol by itself)
...
movl $10, %edx
movq 16(%rsi), %rdi
movq 8(%rsi), %rbx
xorl %esi, %esi
call strtol
movl $.LC0, %edi
movq %rbx, %rdx
movl %eax, %esi
xorl %eax, %eax
call printf
xorl %eax, %eax
popq %rbx
...
The question :
%rcx should be reserved for the 4th input integer argument.
strtol has 3 input args (respectively registers %rdi, %rsi, %rdx) and one return, %eax.
Why then is %rcx clobbered ?
This code won't make it :
...
movl $10, %edx
movq 16(%rsi), %rdi
movq 8(%rsi), %rcx <-- look I replaced with %ecx
xorl %esi, %esi
call strtol
movl $.LC0, %edi
movq %rcx, %rdx <-- look I replaced with %ecx
movl %eax, %esi
xorl %eax, %eax
call printf
xorl %eax, %eax
popq %rbx
...
Thanks
In each calling convention I know there are some registers that may be modified by the called function and some which must not be modified.
In 32-bit programs ecx may be modified while ebx must not be modified - or, to be more exact - must be re-stored before returning. For 64-bit programs this rule seems to be the same.
Indeed most functions modify most registers; for this reason there is a "popq %rbx" at the end of the code you posted because rbx must not be modified by the function. rcx may be modified and strtol obviously does that!

Resources