与 C 程序一起执行的 Perl 代码将不正确的字节长度写入 Windows 中的内存

Perl code executed alongside C program writes incorrect byte length to memory in Windows

免责声明:我不担心语法。

在了解缓冲区溢出的同时,我正在尝试与我的 C 程序一起执行的 Perl 代码来演示溢出是如何工作的。但是,当我输入代码 .\Buffer $(perl -e 'print "A"x16 . "\xef\xbe\xad\xde"') 时,它只会将 $(perl 添加到内存中的第一个缓冲区,buffer_two,如下所示:

.\Buffer $(perl -e 'print "A"x16 . "\xef\xbe\xad\xde"')

[BEFORE] buffer_two is at 0061FF0C and contains two
[BEFORE] buffer_one is at 0061FF14 and contains one
[BEFORE] value is at 0061FF1C and is 5 (0x00000005)

[STRCPY] copying 6 bytes into buffer_two

[AFTER] buffer_two is at 0061FF0C and contains $(perl
[AFTER] buffer_one is at 0061FF14 and contains one
[AFTER] value is at 0061FF1C and is 5 (0x00000005) 

buffer_twovalue之间的字节是16字节(gdb) print 0x0061ff1c - 0x0061ff0c = 16),所以我打印16次“A”来填充space。但是,应该发生的是 "A"x16 之后的文本应该覆盖下一个内存地址。在 Linux 上使用时,代码工作正常,我得到以下输出:

./Buffer $(perl -e 'print "A"x16 . "\xef\xbe\xad\xde"')
[BEFORE] buffer_two is at 0x7ffca168185c and contains two
[BEFORE] buffer_one is at 0x7ffca1681864 and contains one
[BEFORE] value is at 0x7ffca168186c and is 5 (0x00000005)

[STRCPY] copying 20 bytes into buffer_two

[AFTER] buffer_two is at 0x7ffca168185c and contains AAAAAAAAAAAAAAAAᆳ�
[AFTER] buffer_one is at 0x7ffca1681864 and contains AAAAAAAAᆳ�
[AFTER] value is at 0x7ffca168186c and is -559038737 (0xdeadbeef)

完整代码如下:

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

int main(int argc, char *argv[])
{

int value = 5;
char buffer_one[8], buffer_two[8]; //create two buffers of 8 bytes

strcpy(buffer_one, "one"); //copy strings one and two into buffers
strcpy(buffer_two, "two");

printf("[BEFORE] buffer_two is at %p and contains %s\n", buffer_two, buffer_two); //print initial address and value
printf("[BEFORE] buffer_one is at %p and contains %s\n", buffer_one, buffer_one);
printf("[BEFORE] value is at %p and is %d (0x%08x)\n", &value, value, value);

printf("\n[STRCPY] copying %d bytes into buffer_two\n\n", strlen(argv[1])); //copy first argument digits into buffer two

//if((int *)argv[1] > (int *)8) //test if argument input is greater than 8 bytes
//{
    //printf("[!!] Buffer error\n\n");
    //exit(-1); 
//}

strcpy(buffer_two, argv[1]);

printf("[AFTER] buffer_two is at %p and contains %s\n", buffer_two, buffer_two);
printf("[AFTER] buffer_one is at %p and contains %s\n", buffer_one, buffer_one);
printf("[AFTER] value is at %p and is %d (0x%08x)\n", &value, value, value);

}

在写这个 post 时我注意到它只写了 6 个字节,我不确定为什么。

.\Buffer $(perl -e 'print "A"x16 . "\xef\xbe\xad\xde"')

此语法(运行 括号中的命令并用其输出替换 $(...))是(许多)UNIX shells 的一个特性。

您在 Windows 上使用的任何 shell 显然都不会这样做。