你們信不信一句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控制台程序的,有對應其他語言環境的可以試試看.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM