Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Tim Newsham格式字符串攻击_C_Security_Exploit_Format String - Fatal编程技术网

C Tim Newsham格式字符串攻击

C Tim Newsham格式字符串攻击,c,security,exploit,format-string,C,Security,Exploit,Format String,我正在阅读关于格式字符串漏洞的文章,发现一开始有些部分很难理解 正在讨论下列方案 /* * fmtme.c * Format a value into a fixed-size buffer */ #include <stdio.h> int main(int argc, char **argv) { char buf[100]; int x; if(argc != 2) exit(1); x = 1; s

我正在阅读关于格式字符串漏洞的文章,发现一开始有些部分很难理解

正在讨论下列方案

/*
 * fmtme.c
 *       Format a value into a fixed-size buffer
 */

#include <stdio.h>

int
main(int argc, char **argv)
{
    char buf[100];
    int x;
    if(argc != 2)
        exit(1);
    x = 1;
    snprintf(buf, sizeof buf, argv[1]);
    buf[sizeof buf - 1] = 0;
    printf("buffer (%d): %s\n", strlen(buf), buf);
    printf("x is %d/%#x (@ %p)\n", x, x, &x);
    return 0;
}
该报说:

"A quick analysis of the program will reveal that the stack layout of the
program when the snprintf function is called is:

    Address  Contents       Description
    fp+8     Buffer         pointer 4-byte address
    fp+12    Buffer         length 4-byte integer
    fp+16    Format         string 4-byte address
    fp+20    Variable x     4-byte integer
    fp+24    Variable buf   100 characters

The four values output in the previous test were the next four arguments on
the stack after the format string: the variable x, then three 4-byte
integers
taken from the uninitialized buf variable."
这里的
fp
是什么?文件指针

为什么它是从fp+8开始的,而不是从fp+4开始的,当增量为4时,其他地方(4字节地址)

在这里,地址越大,表示该值在堆栈上越高还是越低

“目录”下的名称是什么意思


当我运行上述程序时,
x
,即
1
,的值没有被打印出来。也许是因为不同的建筑

我是这样的

./fmtme "%x %x %x %x"
buffer (34): cd512860 b3356d80 b3356d80 8247ee8
x is 1/0x1 (@ 0x7ffc08247d8c)
有人能帮忙吗?

  • fp
    代表“帧指针”

  • 参数从
    fp+8
    开始,因为
    fp+4
    是返回地址,
    fp+0
    是保存的帧指针

  • 在x86使用的传统向下扩展堆栈中,较高的地址在堆栈中越深(先前推送的项)

内容有点不清楚-它试图描述堆栈槽中的内容,但其中一些没有名称。这可能更清楚:

Address  Contents                  Description
fp+8     First snprintf argument   pointer 4-byte address
fp+12    Second snprintf argument  length 4-byte integer
fp+16    Third snprintf argument   string 4-byte address
fp+20    Variable x in main        4-byte integer
fp+24    Variable buf in main      100 characters
您看不到相同的结果,因为这些类型的东西——形式上未定义的行为——对您使用的体系结构、编译器和编译器版本高度敏感。从用
%p
打印的指针值可以看出,您使用的是64位体系结构-如果您使用的是x86-64,那么函数的前6个整型参数将在寄存器中传递,而不是在堆栈中传递,因此,这就是伪
%x
格式开始查找的地方。您可以尝试使用
-m32
编译器选项为x86编译,但没有任何保证。

  • fp
    代表“帧指针”

  • 参数从
    fp+8
    开始,因为
    fp+4
    是返回地址,
    fp+0
    是保存的帧指针

  • 在x86使用的传统向下扩展堆栈中,较高的地址在堆栈中越深(先前推送的项)

内容有点不清楚-它试图描述堆栈槽中的内容,但其中一些没有名称。这可能更清楚:

Address  Contents                  Description
fp+8     First snprintf argument   pointer 4-byte address
fp+12    Second snprintf argument  length 4-byte integer
fp+16    Third snprintf argument   string 4-byte address
fp+20    Variable x in main        4-byte integer
fp+24    Variable buf in main      100 characters

您看不到相同的结果,因为这些类型的东西——形式上未定义的行为——对您使用的体系结构、编译器和编译器版本高度敏感。从用
%p
打印的指针值可以看出,您使用的是64位体系结构-如果您使用的是x86-64,那么函数的前6个整型参数将在寄存器中传递,而不是在堆栈中传递,因此,这就是伪
%x
格式开始查找的地方。您可以尝试使用
-m32
编译器选项为x86进行编译,但没有任何保证。

@user3386109我们能以某种方式将旧的体系结构与新的体系结构联系起来吗?如果这就是不同之处?@user3386109我们能以某种方式将旧架构与新架构联系起来吗?如果这是不同之处的话?我是架构概念的新手。您是如何从用
%p
打印的地址看出我使用的是64位体系结构机器的?我发现
snprintf()
的参数是从右向左推的,这有点奇怪。如果给出更多的参数,它们将出现在“格式”和“变量x”之间。但是为什么
snprintf()
读取“缓冲区”并进行跟踪?这不匹配。我怀疑这是作者的一个错误。@J…S:因为打印的指针值超过32位(而且我也认为它在Linux x86-64上的典型堆栈地址范围内)。@thebusybee:从右向左推参数是很常见的。这意味着您可以访问varargs函数中的所有参数,而不必知道它们有多少(因为第一个参数始终位于函数项上堆栈指针的已知偏移量处,就在返回地址之后)@thebusybee:非常清楚地展示了从右到左的论点推进。我是架构概念的新手。您是如何从用
%p
打印的地址看出我使用的是64位体系结构机器的?我发现
snprintf()
的参数是从右向左推的,这有点奇怪。如果给出更多的参数,它们将出现在“格式”和“变量x”之间。但是为什么
snprintf()
读取“缓冲区”并进行跟踪?这不匹配。我怀疑这是作者的一个错误。@J…S:因为打印的指针值超过32位(而且我也认为它在Linux x86-64上的典型堆栈地址范围内)。@thebusybee:从右向左推参数是很常见的。这意味着您可以访问varargs函数中的所有参数,而不必知道它们有多少个(因为第一个参数始终位于函数项上堆栈指针的已知偏移量处,就在返回地址之后)。@thebusybee:非常清楚地演示了从右到左推送参数。