【发布时间】:2021-04-20 04:28:31
【问题描述】:
考虑以下程序:
#include <stdio.h>
int main(void)
{
char c[10] = "hello!";
char d[10] = {'\0'};
sprintf (d, "%s", c);
return printf("%s\n", d);
}
使用gcc -Wall -pedantic a.c(CentOS 上的GCC 4.8.5)编译后,当我在可执行文件上运行nm 时,我可以看到strcpy 被列为未定义符号:
nm a.out | grep strcpy
U strcpy@@GLIBC_2.2.5
strcpy 是如何以及为什么出现在图片中的?如果我在 GCC 8.3.0 上编译相同的程序,strcpy 符号在nm 的输出中找不到。此外,在 GCC 4.8.5 上,如果我在 % 符号 sprintf (d, " %s", c) 之前添加一个空格,则 sprintf 调用不会替换为 strcpy。
使用-S 开关和gcc 生成的汇编代码支持这些发现。有人可以帮我理解这里发生了什么吗?
客户审核可执行文件,如果他们发现对strcpy 的调用,将引发危险信号。我只是想了解为什么sprintf 调用被strcpy 取代。
【问题讨论】:
-
也许编译器将对
sprintf()的调用优化为strcpy(d, c)— 达到相同的结果。查看汇编器——使用 GCC 的-S选项;source.c的输出文件应该是source.s。 -
降级编译器比升级编译器更有可能奏效。旧版本可能不会进行这种优化。较新的版本几乎可以肯定。还要考虑抑制优化
-O0是否有帮助——它可能会,也可能不会。 -
使用
memcpy,或者写一个循环,或者sprintf(d, "%.*s", (int)sizeof(d) - 1, c);,或者... -
@babon 当然你必须这样做。这是一个安全审计。否则这只是老笑话
Problem: "Evidence of hydraulic leak on right main landing gear." Solution: "Evidence removed."的编程等价物 -
我不明白为什么如果客户对
strcpy有问题,他们不会对sprintf有问题提供他们都可能遭受同样的失败。您是说 sprintf 的 所有用法 已经经过专门审核,以确保内容适合目标缓冲区?你真的应该考虑edit提出你的问题。
标签: c gcc compilation strcpy nm