天天看點

關于那些沒有标準答案的問題一覽

有時候,有一些問題沒有一個标準的答案,或者,即使它有答案,但是這個答案也是沒有實際意義的。今天我們就來列舉幾個來看看。

問題:我怎麼知道目前系統裡有多少個指向一個共享記憶體對象的引用?

即使有辦法知道,當你得到答案之後的幾毫秒,你的答案已經是錯誤的了。為什麼?因為有人可能在你擷取引用數之後立即打開了一個新的引用句柄。這就是”由于無法避免的競争條件所導緻的無意義答案”的一個例子。

問題:在不進入一個臨界區的前提下,我如何确定這個臨界區是未鎖定的?

和上面一樣,當你得到答案後,可能立即會有另一個線程決定進入該臨界區,進而讓你剛剛得到的答案變成了錯誤的答案。

問題:我如何确定目前系統上是否安裝有一個鍵盤鈎子?

和上面一樣,當你得到”肯定沒有,一切安全”的答案後,可能會有人立即安裝一個鈎子。

這個問題實際上會更嚴重,因為一般對這個問題感興趣的人,通常會想要實作一個安全的鍵盤通路功能。但是這個時候,可能有人已經安裝了一個鍵盤鈎子,這就意味着,他們已經将代碼挂接到你的程序中了(畢竟它是一個鈎子嘛)。他們很容易将IsKeyboardHooked給Hook掉,并讓其直接傳回FALSE。

現在當你的程式詢問系統,目前是否有安裝鍵盤鈎子,在上面的情況下,你會直接得到一個”愉快的”答案:”沒有,一切安全”。接下裡你會”盲目自信”地相信這個答案,并認為系統裡沒有安裝鍵盤鈎子。這實際上是不可信的,隻是因為這個是某個人Hook掉真實代碼後僞造的一個假答案。

你無法從系統本身内部可靠地推斷該系統的安全性

這就像是試圖向自己證明我沒有瘋一樣。

系統本身可能已經受到攻擊,是以你的所有推理都可以被虛拟化。此外,你的程式可能在虛拟機環境中運作,在這種情況下,虛拟機中缺少鍵盤鈎子并不能證明什麼。鍵盤記錄可能發生在虛拟機的宿主軟體中。

從使用者界面的角度來說,桌面是一個安全邊界。一旦你讓某人在你的桌面上運作,這就意味着你信任他們。 因為現在他們可以向你的程式發送随機消息、注入鈎子、攻擊你的視窗句柄、編輯你的菜單,并且通常還會在各種應用程式程序中晃來晃去,圖謀不軌。

這就是為什麼讓Windows服務與桌面互動是一個如此可怕的錯誤。通過允許和桌面互動,你就開始信任那些不應該信任的安全上下文了。 當然,它可以讓你的Windows服務操控該桌面上的對象,但同時,它也可以讓該桌面上的對象操控你的服務。這是一把雙刃劍,在親自行動之前,最好弄清楚其中的利害關系。

總結

安全問題無小事,切不可高估人性。

這又使我想起了目前正在開發的拓撲梅爾智慧辦公平台(Topomel Box),我在其中引入了契約式程式設計的理念,對于一個元件,它不應該相信任何從外部輸入的資料,它應該懷疑一切,并對資料進行有效性校驗,隻有通過了檢驗才開始它的進一步動作,也即:所有元件之間都暗含一個個确定的契約,隻有滿足了契約所訂立的限制,才會得到相應的服務。

尼采:如果你長時間凝視深淵,深淵也在凝視你。

最後