c数组-警告:格式不是字符串文字

n8ghc7c1  于 2022-12-03  发布在  其他
关注(0)|答案(7)|浏览(132)

我正在尝试学习C语言,但我已经遇到了一个问题。我认为这是微不足道的,但我需要知道它。我已经写了:

#include <stdio.h>
#include <string.h>

int main() 
{
    char str_a[20];

    strcpy(str_a, "Hello, world!\n");
    printf(str_a);
}

一旦我尝试编译它与:gcc -g -o char_array2 char_array2.c我收到一条错误消息,内容是:

char_array2.c: In function ‘main’:
char_array2.c:9:2: warning: format not a string literal and no format arguments [-Wformat-security]

有人能帮忙吗?

ozxc1zmp

ozxc1zmp1#

当使用printf时,格式字符串作为字符串文字比作为变量更好:

printf("%s", str_a);
vs91vp4v

vs91vp4v2#

只是为了给其他答案添加一些东西,你最好这样做,因为(很久以前?)人们这样写printf,黑客发现了一种从堆栈读取和写入堆栈的方法,更多的here
例如,这样一个简单的程序:

blackbear@blackbear-laptop:~$ cat format_vul.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    char text[1024];
    static int test_var = -1;

    if(argc < 2) {
        printf("Use: %s <input>\n", argv[0]);
        exit(-1);
    }

    strcpy(text, argv[1]);

    printf("The correct way:\n");
    printf("%s", text);

    printf("\nThe wrong way:\n");
    printf(text);

    printf("\n[*]: test_var @ %8p = %d ( 0x%x )\n", &test_var, test_var, test_var);
}
blackbear@blackbear-laptop:~$ ./format_vul AAAA
The correct way:
AAAA
The wrong way:
AAAA
[*]: test_var @ 0x804a024 = -1 ( 0xffffffff )

可用于将test_var的值从0xffffff更改为其他值,如0xaabbccdd:

blackbear@blackbear-laptop:~$ ./format_vul $(printf "\x24\xa0\x04\x08JUNK\x2
5\xa0\x04\x08JUNK\x26\xa0\x04\x08JUNK\x27\xa0\x04\x08").%8x.%8x.%8x.%8x.%8x.
%8x.%8x.%8x.%8x.%110x.%n%239x%n%239x%n%239x%n
The correct way:
$�JUNK%�JUNK&�JUNK'�.%8x.%8x.%8x.%8x.%8x.%8x.%8x.%8x.%8x.%110x.%n%239x%n%239
x%n%239x%n
The wrong way:
$�JUNK%�JUNK&�JUNK'�.bfffefec.  154d7c.  155d7c.  155d7c.      f0.      f0.b
ffff4a4.       4.       4.                                                  
                                                     174.                   

                                                50415243                    

                                               50415243                     

                                              50415243
[*]: test_var @ 0x804a024 = -1430532899 ( 0xaabbccdd )
tsm1rwdh

tsm1rwdh3#

该警告是由于编译器希望printf的第一个参数为字符串文字而引起的。它希望您编写以下代码:

printf("%s\n", str_a);

这是因为printf的第一个参数是格式字符串,然后再传递格式参数。
注意:事实上,你可以将变量用作格式字符串,但你可能不应该这样做。这就是为什么编译器会发出警告而不是错误。

h6my8fg2

h6my8fg24#

printf()要求其格式为字符串文字,而不是动态创建的字符串。要修复此问题,请尝试以下操作:

printf("%s", str_a); // %s denotes a string

或者使用puts

puts(str_a);
jhdbpxl9

jhdbpxl95#

请阅读警告“无格式参数”-即字符串中没有%。
尝试printf("%s", str_a);

deikduxw

deikduxw6#

错误来自printf(str_a);。您的代码应该是printf("%s",str_a);。有关printf的更多信息,请查看以下链接。http://www.cprogramming.com/tutorial/printf-format-strings.html

9o685dep

9o685dep7#

实际上,通过写:

printf(str_a);

你在帮助恶意用户进行格式字符串攻击。实际上,他们实际上可以在输入字符串中写入如下内容:

%x%x%x

如果在这个格式之后不传递参数,如果你的堆栈没有被保护,由于printf()的作用,使用这个字符串的用户可以读取你的内存。我不喜欢给自己太多的细节,因为我不是一个关于格式字符串攻击的Maven,但是这里有一些更详细的资源!
OWASPWikipedia显示器

相关问题