I am trying to understand scanf function a have 3 question regarding it. this is c file:

#include <stdio.h>
#include <stdlib.h>

int main(){
    int x;
    printf("Enter X:\n");
    printf("You entered %d...\n",x);
    return  0;

and here is gas:

    .section    .rodata
    .string "Enter X:"
    .string "%i"
    .string "You entered %d...\n"
    .globl  main
    .type   main, @function
    pushq   %rbp    #
    movq    %rsp, %rbp  #,
    subq    $16, %rsp   #,
# a.c:5:    printf("Enter X:\n");
    leaq    .LC0(%rip), %rdi    #,
    call    puts@PLT    #
# a.c:6:    scanf("%i",&x);
    leaq    -4(%rbp), %rax  #, tmp90
    movq    %rax, %rsi  # tmp90,
    leaq    .LC1(%rip), %rdi    #,
    movl    $0, %eax    #,
    call    __isoc99_scanf@PLT  #
# a.c:7:    printf("You entered %d...\n",x);
    movl    -4(%rbp), %eax  # x, x.0_1
    movl    %eax, %esi  # x.0_1,
    leaq    .LC2(%rip), %rdi    #,
    movl    $0, %eax    #,
    call    printf@PLT  #
# a.c:8:    return  0;
    movl    $0, %eax    #, _6
# a.c:9: }
    .size   main, .-main
    .ident  "GCC: (Debian 8.3.0-6) 8.3.0"
    .section    .note.GNU-stack,"",@progbits

1) The rsi should take address of x int, but it takes the address from -4(%rbp), where there is nothing, in time of execution. Because the initialization of x variable comes from the stdin as scanf waits for input to init the variable. But the what is in -4(%rbp) in the time of instruction leaq -4(%rbp), %rax? It looks like garbage, not address of x, which value should be initialized from stdin.

2)according to this https://stackoverflow.com/questions/54165346/integer-describing-number-of-floating-point-arguments-in-xmm-registers-not-passe, the movl $0, %eax is to zero FP registers in al, but that is the same convention for printf. So my question is, to which functions from glibc or other libraries apply this convetion? (So I have to zero %al in printf, scanf, ....?). I assume to every, that has va_list or variable argument?

3) where in the gas source is stack canary in that should protect scanf buffer from overflow? according to this: How does scanf interact with my code in assembly, this should set canary (in masm):

0x080484c5 <+6>: mov    eax,gs:0x14
   0x080484cb <+12>:    mov    DWORD PTR [ebp-0xc],eax
   0x080484ce <+15>:    xor    eax,eax

But I see nothing similar to this in my gas source, which is also output from gcc, which should set it by itself (unless there is some checking in the the scanf function itself which is not visible in my source). So where is it?

1 Answer 1

  1. rbp-4 is the location allocated by the compiler for the variable x. You can see that later it’s being read by the mov instruction for the printf call.
  2. al must be set before every call to a variadic function (...).
  3. This depends on GCC version/build options but by default, stack protection is only used in functions with buffers(arrays) over 8 bytes large. Because you have only a single integer, there is no way it would be overrun so no stack protection is added. If you want to enable it regardless, use -fstack-protector-all. Note that the stack protector cannot do anything about integer overflows.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.