首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么返回指向本地解密变量的指针为null而不是指向堆栈中位置的指针?

为什么返回指向本地解密变量的指针为null而不是指向堆栈中位置的指针?
EN

Stack Overflow用户
提问于 2019-12-15 11:44:30
回答 2查看 85关注 0票数 1

在下面的代码段中,str_s不应该指向堆栈中的某个位置。

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char* fun_s(){
    char str[8]="vikash";
    printf("s :%p\n", str);
    return str;
}

char* fun_h(){
    char* str = (char*)malloc(8);
    printf("h :%p\n", str);
    strcpy(str, "vikash");
    return str;
}

int main(){
    char* str_s = fun_s();
    char* str_h = fun_h();
    printf("s :%p\nh :%p\n", str_s, str_h);
    return 0;
}

我知道fun_s的返回存在问题,并且这个指针的内容不能被信任,但根据我的理解,它应该指向堆栈中的某个位置,而不是零?我在我的控制台中得到以下输出。请你解释一下为什么第三行打印(零)而不是0x7ffce7561220

代码语言:javascript
复制
s :0x7ffce7561220
h :0x55c49538d670
s :(nil)
h :0x55c49538d670

GCC版本

代码语言:javascript
复制
gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

操作系统:Ubuntu 18.04.3 LTS

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-12-15 12:14:21

编译器是有意从该函数中注入一个空返回值。我没有gcc 7.4,但我有7.3,我想结果是相似的:

fun_s编译为程序集可提供以下内容:

代码语言:javascript
复制
.LC0:
        .string "s :%p\n"
fun_s:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        movabs  rax, 114844764957046
        mov     QWORD PTR [rbp-8], rax
        lea     rax, [rbp-8]
        mov     rsi, rax
        mov     edi, OFFSET FLAT:.LC0
        mov     eax, 0
        call    printf
        mov     eax, 0 ; ======= HERE =========
        leave
        ret

注意,0到eax的硬集合,它将在返回到调用方时保存结果指针。

使str静态提供以下内容:

代码语言:javascript
复制
.LC0:
        .string "s :%p\n"
fun_s:
        push    rbp
        mov     rbp, rsp
        mov     esi, OFFSET FLAT:str.2943
        mov     edi, OFFSET FLAT:.LC0
        mov     eax, 0
        call    printf
        mov     eax, OFFSET FLAT:str.2943
        pop     rbp
        ret

简而言之,编译器正在检测本地地址返回,并将其重写为NULL。在这样做时,它可以防止任何后来恶意使用所述地址(例如:内容注入攻击)。

我认为没有理由不允许编译器这样做。我相信语言纯粹主义者会证实或拒绝这种怀疑。

票数 3
EN

Stack Overflow用户

发布于 2019-12-15 12:10:01

大多数现代编译器检测到指向局部变量的指针的返回,实际上返回NULL (一般来说,对于UBs来说比较激进,其方法是-让程序尽快失败或“使UB能够检测运行时”,就像在本例中那样) https://godbolt.org/z/pDUXmm

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59343586

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档