使用c语言实现缓冲区溢出

使用c语言实现缓冲区溢出,c,buffer,buffer-overflow,C,Buffer,Buffer Overflow,我试图创建一个缓冲区溢出,它将用“31337”的值覆盖变量“b”。编译后的文件名为“bo”。缓冲区的大小为010,即8个字节,因此我用“aaaaaa”填充它,31337是7A69的十六进制。因此,Linux中的以下命令在理论上应该可以工作,但不成功: printf 'AAAAAAAA\x69\x7A\x00\x00' | ./bo 上面的命令应该覆盖“b”变量。如果我将b变量更改为1337,并将命令更改为以下内容,则该命令有效: printf 'xxxxxxxx\x39\x05\x00\x00

我试图创建一个缓冲区溢出,它将用“31337”的值覆盖变量“b”。编译后的文件名为“bo”。缓冲区的大小为010,即8个字节,因此我用“aaaaaa”填充它,31337是7A69的十六进制。因此,Linux中的以下命令在理论上应该可以工作,但不成功:

printf 'AAAAAAAA\x69\x7A\x00\x00' | ./bo
上面的命令应该覆盖“b”变量。如果我将b变量更改为1337,并将命令更改为以下内容,则该命令有效:

printf 'xxxxxxxx\x39\x05\x00\x00' | ./bo
1337是539的十六进制数

以下是来自终端的命令结果

root@kali:~# printf 'AAAAAAAA\x69\x7A\x00\x00' | ./bo
1111638594
我以为是31337

root@kali:~# printf 'AAAAAAAA\x39\x05\x00\x00' | ./bo
1337
有人知道我做错了什么吗?它适用于十六进制1337,但不适用于31337。以下是源代码:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

int play()
{
    int a;
    int b;
    char buffer[010];
    a = 0x41414141;
    b = 0x42424242;

    if (read(STDIN_FILENO, &buffer, 0xC) < 0) 
        perror("read");

    printf("%d\n", b);
}


int main(int argc, char *argv[]){
    play();
    exit(EXIT_SUCCESS);
}
#包括
#包括
#包括
int play()
{
INTA;
int b;
字符缓冲区[010];
a=0x4141;
b=0x4242;
如果(读取(标准数据文件号和缓冲区,0xC)<0)
佩罗(“阅读”);
printf(“%d\n”,b);
}
int main(int argc,char*argv[]){
play();
退出(退出成功);
}

不能假设变量在堆栈上有特定位置。然而,有一种方法可以强制执行。您可以这样做:

int play()
{
    struct {
        int a;
        char buffer[010];
        int b;
    } vars;

    vars.a = 0x41414141;
    vars.b = 0x42424242;

    if (read(STDIN_FILENO, &vars.buffer, 0xC) < 0) 
        perror("read");

    printf("%d\n", vars.b);
}
事实并非如此


但我不确定你能相信或使用多少。这只保证
&a您正在调用未定义的bahaviour。因此,您的代码的结果通常无法预测。我不知道您在哪里覆盖缓冲区。@klutt对不起,代码“为您工作”是什么意思?你能让缓冲区溢出正常工作吗?我不确定什么是未定义的行为。“我正在尝试创建缓冲区溢出”。。为什么?这对未来的用户/访问者有何用处?它执行了
readfile(“Success.txt”)
。未定义的行为表示该行为未定义。它可以做任何事情,包括按预期工作。太棒了。我刚刚确认更改订单确实有效。非常感谢您的帮助。@Coding新手请记住,您在做这样的事情时是在玩火。您可能会导致未定义的行为。搜索这个术语并阅读它,你会发现如果可以的话你想避免它,因为它使调试变得非常困难。(当你不做像这样的黑客行为时,你要不惜一切代价避免它。)@klutt因为OP已经指定他们使用gcc,你可以在结构定义上添加
\uuuuu attribute_uuu((打包))
,以确保没有填充。虽然它只是对编译器的一个提示,但可能会有所帮助。@AjayBrahmakshatriya因为它只是一个提示,所以依赖它是一个非常糟糕的主意。:)@klutt它不仅仅是生成一个结构(因为如果字符在整数之间,它肯定会有填充)。但我会让你来判断。
struct {
    int a;
    int b;
    char buffer[010];
} vars;
int main()
{
    struct {
        char x;
        int a;
        char y;
    } v;

    struct {
        char x;
        char y;
        int a;
    } w;

    printf("%d\n", sizeof(v));
    printf("%d\n", sizeof(w));
}
$ ./a.out 
12
8