用二進制來寫程序這麼反人類的事情,的確是很裝的事情,可是它不可是一件很裝的事情,也是掌握底層知識的基礎能力之一。聽我慢慢道來。編程
程序設計語言有高級語言和低級語言之分,尤爲是如今各類編程語言的不斷髮展,掌握高級程序設計語言的人愈來愈多。微信
可是是否可使用二進制來寫程序呢?也許最初使用打孔帶來控制機器的人能夠完成,那麼如今是否仍然有人能夠完成呢?答案是確定的!數據結構
計算機能夠直接運行的指令是二進制的機器碼,全部的代碼在運行以前都會變成 CPU 能夠識別的二進制。對於編譯型的二進制語言,其實都是能夠直接使用二進制來寫的。編程語言
好比,Windows 下使用 C 語言編寫的程序編譯鏈接後能夠生成一個 .exe 的可執行程序,生成的這個可執行程序就是一個二進制程序。那麼,這個程序如何用二進制編寫呢?編輯器
先來考慮幾個問題!函數
首先,可執行程序中並不是只有代碼,而 CPU 要執行的只有代碼。學習
其次,CPU 執行的代碼是二進制,可是在內存中的數據也是二進制數據,那麼如何知道哪部分是代碼,哪部分是數據呢?這是操做系統在加載程序文件進入內存時,操做系統按照必定規則把不一樣二進制按照不一樣的屬性裝入了不一樣的內存分頁當中,並對內存設置相應的屬性。加密
最後,操做系統如何知道程序文件中的二進制哪部分是數據,哪部分是代碼呢?這是在程序被編譯鏈接時不但把代碼和代碼所需的數據編譯到了程序中,還把管理代碼的數據也放入了程序中,而這部分管理數據決定了哪部分是數據哪部分是代碼。spa
所以,用二進制寫代碼就須要至少掌握兩方面,一方面是瞭解可執行程序的管理數據,另外一方面就是了解 CPU 的機器碼。操作系統
在 Windows 下的可執行程序是 PE 格式的,那麼就要了解 PE 格式的數據結構,和 CPU 的機器碼;在安卓下的可執行程序中,其格式是 DEX 格式,那麼就要了解 DEX 格式的數據結構,以及安卓虛擬機的字節碼(這個字節碼不是 CPU 的機器碼,DEX 的字節碼最終被虛擬機解釋成機器碼,所以手寫 DEX 文件時瞭解 DEX 格式和其字節碼便可),一樣的,Java 編譯的 Class 文件也和安卓相同,由於它也是基於虛擬機執行的文件。其中 PE 格式和 DEX 格式就是程序的管理數據,用於告訴操做系統或虛擬機,整個文件中代碼、數據以及其餘資源在文件中的結構。
由於二進制的閱讀性比較差,所以人們使用了八進制和十六進制。四位二進制能夠表示爲一位十六進制,因爲系統是 32 位或 64 位,那麼恰好使用 8 個十六進制位表示 32 個二進制位,或者 16 個十六進制位表示 64 個二進制位。所以,在內存中查看數據時,更多的是使用十六進制,其實從本質上十六進制和二進制是沒有區別的,只是表示的方式不一樣。所以,真正使用二進制來寫程序時,是使用十六進制來完成的。
那麼,在使用十六進制來編寫 Windows 下的可執行程序時,首先須要使用十六進制編輯器構造 PE 文件結構,PE 文件結構主要告訴操做系統,程序加載入內存後,程序的映射起始地址是多少,程序的入口地址是多少,程序中的代碼和數據分別保存在哪裏,以及它們的長度是多少,映射到內存中之後其地址是多少,該可執行文件調用了哪些系統函數,這些系統函數分別在哪些動態連接庫中等信息。構造完 PE 文件結構之後,就可使用機器碼來寫程序了。只要把機器代碼寫到 PE 文件結構中標識程序入口的位置處就好了。固然了,機器碼寫程序是比較困難的,可是做爲學習底層基礎知識來講,寫一個簡單的程序仍是能夠的,好比寫一個彈出對話框的「hello world」這樣的程序。用機器碼寫這樣的程序,也無需瞭解太多的知識,有一份 Opcode 的手冊就能夠了。
這就是如何用十六進制編輯器來完成一個可執行程序的過程,關於 PE 文件格式,能夠參考 MSDN 或網上的文章,對於學習機器碼相關的知識能夠查看 Intel 的指令手冊。學習這些知識對於軟件破解、病毒分析、加密解密、內核驅動開發等是相應知識的基礎,感興趣的能夠了解一下,瞭解這些知識絕對不單單是用來裝 X 的。
個人微信公衆號:「碼農UP2U」