首页 > 解决方案 > 气体中 scanf 调用的存储寄存器

问题描述

我正在尝试了解 scanf 函数,对此有 3 个问题。这是c文件:

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

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

这是气体:

.text
    .section    .rodata
.LC0:
    .string "Enter X:"
.LC1:
    .string "%i"
.LC2:
    .string "You entered %d...\n"
    .text
    .globl  main
    .type   main, @function
main:
    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: }
    leave   
    ret 
    .size   main, .-main
    .ident  "GCC: (Debian 8.3.0-6) 8.3.0"
    .section    .note.GNU-stack,"",@progbits

1)rsi应该取xint 的地址,但它取地址 from -4(%rbp),那里什么都没有,在执行时。因为x变量的初始化来自stdinas scanf 等待输入来初始化变量。但是在-4(%rbp)指导的时候是leaq -4(%rbp), %rax什么?它看起来像垃圾,而不是 的地址x,应该从 初始化哪个值stdin

2)根据此整数描述的 xmm 寄存器中未传递给 rax 的浮点参数的数量,将movl $0, %eax中的 FP 寄存器归零al,但这与 的约定相同printf。所以我的问题是,glibc 或其他库中的哪些函数应用了这个约定?(所以我必须%al在 printf、scanf、......中归零?)。我假设每个有va_list或变量的参数?

3)气体源中的堆栈金丝雀应该保护scanf缓冲区免受溢出吗?根据这个:https://reverseengineering.stackexchange.com/questions/10823/how-does-scanf-interact-with-my-code-in-assembly,这应该设置金丝雀(在masm中):

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

但是我在我的气源中看不到与此类似的东西,它也是 gcc 的输出,它应该自行设置它(除非在我的源中不可见的 scanf 函数本身进行了一些检查)。那么它在哪里呢?

标签: gccx86-64gnu-assemblerabi

解决方案


推荐阅读