多年來,臺式計算機的安全性一直是人們關注的問題。一旦機器連接到互聯網,本質上就有可能受到某種攻擊。這種滲透可能是為了竊取數據、破壞系統或以某種方式改變其操作。保護手段是眾所周知的并且被廣泛應用。嵌入式系統似乎總是不受這些問題的影響,因為它們很少聯網,而且它們的代碼通常在某種 ROM 中。事情變了。大部分現代系統都連接到 Internet,將代碼復制到 RAM 并從那里執行是常見的做法。這意味著安全性現在是一個重要的嵌入式軟件設計考慮因素。
英語是一種很好的交流工具。它是一種極具表現力的語言,能夠以非常精確和微妙的方式進行交流。然而,在日常講話中,我們大多數人都很懶惰,經常使用沒有 100% 準確度的單詞。我在這里想到的例子是安全和安保幾乎可以互換使用的方式,就好像它們是同義詞一樣。我認為我聽到的最好的定義是這樣的:安全是保護世界免受設備影響的過程;安全性正在保護設備免受外界侵害。安全是我今天的主題。
如果一個系統真的需要完全防彈,則需要工業級加密。這通常需要特定的硬件支持,雖然很容易獲得,但對于不需要如此高安全性的應用程序來說,這可能被認為是多余的。在這種情況下,還有其他選擇,這就是我想探索的。
如果黑客可以訪問設備的內存內容,他們就可以開始弄清楚它做了什么以及它是如何做的。這是改變其運作的第一階段。代碼可以被反匯編,因此可以揭示邏輯。如果沒有加密,就幾乎無法防止這種情況發生。黑客可能做的下一件事是查看數據的十六進制/ASCII 轉儲,看看他們能在那里找到有意義的東西。他們正在尋找模式和可識別的結構。這是可以采取一些預防措施的地方。雖然加密可能不是一種選擇,但混淆是可能的。
數據混淆的目的是通過簡單地降低數據的可識別性來延遲或阻止黑客。通過內存轉儲掃描,最容易發現的事情之一是文本字符串。所以,這就是我將在這里重點介紹的內容。
在 C/C++ 代碼中,文本字符串通常只是包含以空字節結尾的 ASCII 代碼的字節序列。這很容易發現,所以我會改變它。首先,每個字符串的第一個字節將是一個長度說明符,而不是空終止符。字符串的字符會稍微打亂它們的數據,讓它們看起來不那么熟悉——我要做的就是交換每個字節的兩個半字節。我需要一個實用程序,將純文本字符串輸入其中,并生成具有適當初始化的數組的聲明。這是該實用程序的核心功能:
void scramble(int index, unsigned char *input) { ??? unsigned char *charpointer, 字符; ??? printf("unsigned char string%d[%d] = {0x%02x,", index, ?????????? strlen(輸入)+1,strlen(輸入)); ??? 字符指針 = 輸入; ??? 而(*字符指針) ??? { ??????? 字符= *字符指針++; ??????? 字符 = ((字符 & 0x0f) << 4) | ??????????????????? ((字符 & 0xf0) >> 4); ??????? printf("0x%02x", 字符); ??????? if (*字符指針) ??????????? printf(","); ??? } ??? printf("}; // "%s"\n", 輸入); }
如果我向這個函數傳遞一個索引 4 和一個字符串“Hello world”(原來的嗯?),輸出將是:
unsigned char string4[12] = {0x0b, 0x84, 0x56, 0xc6, 0xc6, 0xf6, 0x02, 0x77, 0xf6, 0x27, 0xc6, 0x46};// “你好世界”
我可以將其復制并粘貼到我的代碼中,然后我需要做的就是編寫一個函數來在需要顯示文本時對其進行解讀。我可以通過將index參數替換為字符串來給它一個任意名稱,而不是給每個字符串一個索引號。請注意,生成的代碼在某種程度上是自記錄的,因為注釋以可讀的形式顯示了字符串,但是,當然,這只出現在源代碼中。如果黑客可以訪問您的源代碼,那么您就有足夠的麻煩,我無法提供進一步的幫助!
下面是一些代碼來說明解擾過程:
無效的主要() { ??? 無符號字符臨時,緩沖區[50]; ??? 整數計數 = string4[0],索引 = 0; ??? 而(計數--) ??? { ??????? temp = string4[index+1]; ??????? 溫度 = ((溫度 & 0x0f) << 4) | ((溫度 & 0xf0) >> 4); ??????? 緩沖區[索引] = 溫度; ??????? 索引++; ??? } ??? 緩沖區[索引] = 0; ??? printf("-%s-\n", 緩沖區); }
每個字節中半字節的交換是可以完成加擾的許多不同方式之一。另一種可能性是,比如說,將每個字符左旋轉三位。這里有一些代碼可以做到這一點:
unsigned char leftrotate3(unsigned char c) { ??? c = (c << 3) | (c >> 5); ??? 返回 c; }
我概述的混淆技術會逐個字符地打亂字符串。可以改為對整個字符串執行操作。例如,將字符串視為一長串位并將其向左旋轉任意數字。我將把這個算法的編碼留給更熱心的讀者。
值得注意的是,本地化所有文本字符串的一個副作用是,為其他語言制作不同版本的軟件非常簡單。
我必須重申并強調,數據混淆遠不是防彈的,充其量只能減緩黑客的攻擊速度。如果沒有其他情況,解讀代碼可能會被分解。這種技術的訣竅是使模糊處理成為難以遵循的軌跡。如果你真的需要更高的安全性,你必須考慮完全加密。
評論