1、缓冲区溢出攻击实验:
gets函数在使用中有很大的漏洞,在获得字符时gets函数以EOF||’\n’作为结束标志当字符串过多时会发生缓冲区溢出。用以下代码和gets的原码来理解gets函数的缓冲区溢出问题。
代码:
#include <stdio.h>
#include <stdlib.h>
/* Implementation of library function gets() */
char *gets(char *dest)
{
int c = getchar();
char *p = dest;
while (c != EOF && c != '\n') {
*p++ = c;
c = getchar();
}
*p = '\0';
return dest;
}
/* Read input line and write it back */
void echo()
{
char buf[4]; /* Way too small! */
gets(buf);
puts(buf);
}
void call_echo()
{
echo();
}
/*void smash()
{
printf("I've been smashed!\n");
exit(0);
}
*/
int main()
{
printf("Type a string:");
call_echo();
return 0;
}
函数gets()就是我们经常在C语言中使用的库函数的源码,用以得到从键盘输入的字符。函数echo()调用函数gets()并把从键盘输入的字符存入数组buf[]。函数call_echo()调用echo(),输出数组中的字符。其实可以不用这个函数,直接在主函数中调用echo(),这样做是为了程序的美观和条理。在运行中会出现溢出问题。
当输入字符串长度小于等于4时程序能够正常运行,当输入字符串长度大于4时程序运行结果会出现 :已放弃(核心已转储)。这是因为gets函数以 EOF||’\n’作为结束标志,并不会检验字符串的长度。由于最先定义的数组长度为4,分配的存储空间为1*4个字节,当超过4个字节时就会发生缓冲区溢出问题。
2、浮点数加减法不具有交换律实验
设两个浮点数 x 和 y:
则浮点数加减运算结果为:
1 对阶:首先要把指数位(阶码)调成一样,并相应的使M移位,由于有效域左移会引起 最高有效位丢失,误差大,所以采用右移,此时阶码要增加。所以对阶原则是:小阶向大阶看齐。
2 有效数加减:简单的无符号数字相加减。
3 规格化:有效数求和结果可能大于1,那么就向右规格化:尾数右移1位,阶码加1。
4舍入:对于右移出去的位,采取舍入
我们可以写一个函数来加深对浮点数加减法的理解:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFSIZE 256
int main(int argc, char *argv[]) {
char prefix[BUFSIZE];
char next[BUFSIZE];
int i;
float sum = 0.0;
for (i = 1; i < argc; i++) {
float x = atof(argv[i]);
sum += x;
if (i == 1) {
sprintf(prefix, "%.4g", x);
} else {
sprintf(next, " + %.4g", x);
strcat(prefix, next);
printf("%s = %.4g\n", prefix, sum);
}
}
return 0;
}
运行如下: