好久沒更新博客了,今天是扒衣見君節,難得閑下來就來說說一個最近有趣的發現吧.
首先廢話不多說,直接上代碼吧
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控制台程序的,有對應其他語言環境的可以試試看.