你们信不信一句Console.WriteLine就能让你的控制台程序失去响应

好久没更新博客了,今天是扒衣见君节,难得闲下来就来说说一个最近有趣的发现吧.


首先废话不多说,直接上代码吧

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             var bytes = new byte[4096];
 6             for (int i = 0; i < bytes.Length; i++)
 7             {
 8                 bytes[i] = 7;
 9             }
10 
11             Console.WriteLine(Encoding.ASCII.GetString(bytes));
12             string line = Console.ReadLine();//你已经死了 这部分是没有机会跑到了............
13             while (line != "ok")
14             {
15                 Console.WriteLine(line);
16                 line = Console.ReadLine();
17             }
18         }
19     }

有兴趣的童鞋可以建个控制台程序跑一下,看看会不会程序失去响应.看回复中的信息,貌似WIN8.1和WIN10都没这个问题.我这边是在WIN7SP1下测试会失去响应的.如果还有用老掉牙XP的可以测试一下结果发上来看看.


为什么会挂掉呢?

关键就在于这个ASCII代码7,请看下图的ASCII码表.


ASCII的7代表BELL,也就是让主板上的蜂鸣器叫一声,就和你电脑刚刚开机时候的滴一声一样.所以输出ASCII的7就会让主板蜂鸣器叫一声,不过现在都是WINDOWS接管了,不是当年DOS年代了,蜂鸣器这部分由beep.sys这个驱动文件接管了,WIN7下的beep.sys会从声卡发声,XP下的beep.sys还是老样子走主板蜂鸣器的.题外话,当初机器狗病毒也会修改这个beep.sys,毕竟权限是ring0的,拿最高权限和杀毒软件干才是硬道理……
所以我们用Console.WriteLine输出ASCII代码7的时候,等于是调用了系统函数去发声,而不仅仅是在控制台上打印文本.当我们输出大量的ASCII代码7的时候,就会不断的去调用这个系统函数,你会发现进程中有个负责DComLaunch的svchost进程基本上进入死循环状态,而你的控制台程序,在系统函数调用结束之前是不会再有响应了……


 

这玩意能干什么呢?
说了这么多,那么这个问题有什么利用价值呢?其实利用价值还是挺大的,很多做服务类程序的人很喜欢直接上手开一个控制台程序,还喜欢把异常信息之类的打印在控制台上,如果你直接显示了用户的输入,那么我只要发一堆ASCII代码7过来,你的服务基本上就挂了……
虽然我只是在C#里面做了测试,但是不表示其他的语言就没有影响了,毕竟都是做成WINDOWS控制台程序的,有对应其他语言环境的可以试试看.

posted @ 2015-08-01 18:18  happycat1988  阅读(6165)  评论(35编辑  收藏  举报