6

我今天正在学习缓冲区溢出,并且遇到了许多易受攻击的程序示例。让我好奇的是,如果有任何理由使用这样的程序参数:

int main(int argc, char *argv[])
{
    char argument_buffer[100];
    strcpy(argument_buffer, argv[1]);

    if(strcmp(argument_buffer, "testArg") == 0)
    {
        printf("Hello!\n");
    }
    // ...
}

而不是简单地:

int main(int argc, char *argv[])
{
    if(strcmp(argv[1], "testArg") == 0)
    {
        printf("Hello!\n");
    }
}

请注意,我知道strcpy等的缺点 - 这只是一个例子。我的问题是 -使用临时缓冲区来存储来自 argv 的参数有什么真正的理由吗?我假设没有,但因此我很好奇,为什么它出现在溢出示例中,而实际上它从未使用过?也许是因为纯粹的理论。

4

4 回答 4

2

一个可能的现实示例:重命名*.foo*.bar;的程序 您将需要原始文件名和它的副本,其中.foo部分更改.bar为调用rename().

于 2012-04-20T15:42:14.067 回答
1

一些程序在文件名前面加上默认路径:

void OpenLogFile (const char *fileName) {
  char pathName[256];
  sprintf(pathName, "/var/log/%s", fileName);
  logFd = open(pathName, ...);
  ...
}

int main (int argc, char **argv) {
  ...
  OpenLogFile(argv[i]);
  ...
}

如果调用程序的实体传入的名称长于 255-9 左右,sprintf则覆盖结束后的pathName, 和繁荣。

于 2012-04-20T15:53:48.787 回答
1

在过去,IIRC argv 及其内容不能保证在所有平台上都是可写和稳定的。C89 / C90 / ANSI-C 标准化了一些现有的做法。与 envp[] 类似。也可能是复制程序的灵感来自于旧平台(例如 MS-DOS)上缺乏内存保护。通常(并且现在)操作系统和/或 CRT 负责将 args 从调用者的内存复制到进程的私有内存区域。

于 2012-04-20T15:55:03.387 回答
0

我不是在缓冲区溢出或安全性方面回答这个问题,而是严格回答为什么有人可能想要复制 argv 的内容。

如果您的程序接受很多参数,例如会更改执行路径或处理模式的标志,您可能希望将 argv 的内容直接传输到日志文件,或者将其临时存储在缓冲区中。如果对 argv 的内容做出的所有决定都发生在 main 中,并且您仍想记录 argv 的内容,则可能不需要复制到缓冲区。

如果您依赖已调度的线程、进程,甚至是基于 argv 内容做出决策的子例程,您可能希望将 argv 值放在缓冲区中,以便您可以传递它们。

编辑:

如果您担心传递指针,请将 argv 的内容复制到固定大小的缓冲区。

于 2012-04-20T15:36:17.907 回答