【问题标题】:Why does C have the %n format specifier, despite the obvious downsides? [duplicate]尽管有明显的缺点,为什么 C 有 %n 格式说明符? [复制]
【发布时间】:2014-06-20 00:15:14
【问题描述】:

我一直在学习格式字符串漏洞,这是我第一次听说%n。而且我不明白它为什么存在。

好的,当然,我可以想象你想知道到目前为止你写了多少个字符的情况。但是还有很多其他方法可以找到字符串的长度,%n 似乎是一种奇怪的方法。它与所有其他格式说明符不同,因为它不写入字符串,而是写入内存中其他一些手动指定的位置。而且因为它太不直观了——谁会期望 printf 写入任意内存? - 它似乎具有制造安全漏洞的明显潜力。除非有人警告您格式字符串漏洞,否则您可能永远不会考虑它。

这样做一定是有原因的。但那是什么?还是上面描述的问题在当时不被认为是严重的?

【问题讨论】:

  • 有史以来最糟糕的问题措辞。如果您只是问“什么是……的有效用途”,您可能已经得到了答案。
  • 我已经知道它是如何工作的。我想知道为什么语言是这样设计的,而不是让人们使用 strlen()。
  • @πάνταῥεῖ 我不太明白你在说什么。我的问题是:为什么在 C 语言中定义 %n 格式说明符,尽管它有明显的缺点?也许我应该改变我的标题以反映这一点。
  • 只有在运行时可以修改格式字符串才有危险;如果它是文字,您只需传递与"%n" 说明符对应的int 对象的地址。至于strlen,如果您正在使用printffprintf 写入文件,则没有什么可以应用strlen

标签: c


【解决方案1】:

This question 中所示,它实际上并未将其值存储在随机内存中。


没有打印。参数必须是一个指向有符号整数的指针,其中存储了到目前为止写入的字符数。

#include <stdio.h>

int main()
{
  int val;

  printf("blah %n blah\n", &val);

  printf("val = %d\n", val);

  return 0;

}

如果您想知道何时在控制台上换行、想要对齐您的值以及您可能希望对输出执行的其他格式化过程,则此参数很有用。

【讨论】:

  • 我知道它没有存储在“随机内存”中,我知道它是这样工作的。但我想知道为什么它会这样工作。与 strlen() 相比,计算换行是否更方便?
  • 除非您总是使用sprintf 或等价将输出打印到字符串缓冲区,然后在使用printf 之前使用strlen,否则没有其他方法(没有hacky)来获取长度printf 输出。
  • 除了\t 被视为一个字符,这意味着您也不能使用它进行正确的换行。
  • @Mehrdad 那么不要使用\t,我的输出中从来没有,我什至没有避免它。
  • @Serdalis:患者:“医生,医生!我走路的时候很痛!”医生:“那就别走路了:P,我有轮椅,我什至不会避免走路”
猜你喜欢
  • 1970-01-01
  • 2020-07-30
  • 2016-06-25
  • 2012-06-22
  • 1970-01-01
  • 2014-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多