与 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_two
和value
之间的字节是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 显然都不会这样做。
免责声明:我不担心语法。
在了解缓冲区溢出的同时,我正在尝试与我的 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_two
和value
之间的字节是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 显然都不会这样做。