二進(jìn)制來寫程序這么反人類的事情,的確是很裝的事情,但是它不但是一件很裝的事情,也是掌握底層知識(shí)的基礎(chǔ)能力之一。聽我慢慢道來。
程序設(shè)計(jì)語言有高級(jí)語言和低級(jí)語言之分,尤其是現(xiàn)在各種編程語言的不斷發(fā)展,掌握高級(jí)程序設(shè)計(jì)語言的人越來越多。
但是是否可以使用二進(jìn)制來寫程序呢?也許最初使用打孔帶來控制機(jī)器的人可以完成,那么現(xiàn)在是否仍然有人可以完成呢?答案是肯定的!
計(jì)算機(jī)可以直接運(yùn)行的指令是二進(jìn)制的機(jī)器碼,所有的代碼在運(yùn)行之前都會(huì)變成 CPU 可以識(shí)別的二進(jìn)制。對(duì)于編譯型的二進(jìn)制語言,其實(shí)都是可以直接使用二進(jìn)制來寫的。
比如,Windows 下使用 C 語言編寫的程序編譯連接后可以生成一個(gè) .exe 的可執(zhí)行程序,生成的這個(gè)可執(zhí)行程序就是一個(gè)二進(jìn)制程序。那么,這個(gè)程序如何用二進(jìn)制編寫呢?
先來考慮幾個(gè)問題!
首先,可執(zhí)行程序中并非只有代碼,而 CPU 要執(zhí)行的只有代碼。
其次,CPU 執(zhí)行的代碼是二進(jìn)制,但是在內(nèi)存中的數(shù)據(jù)也是二進(jìn)制數(shù)據(jù),那么如何知道哪部分是代碼,哪部分是數(shù)據(jù)呢?這是操作系統(tǒng)在加載程序文件進(jìn)入內(nèi)存時(shí),操作系統(tǒng)按照一定規(guī)則把不同二進(jìn)制按照不同的屬性裝入了不同的內(nèi)存分頁(yè)當(dāng)中,并對(duì)內(nèi)存設(shè)置相應(yīng)的屬性。
最后,操作系統(tǒng)如何知道程序文件中的二進(jìn)制哪部分是數(shù)據(jù),哪部分是代碼呢?這是在程序被編譯連接時(shí)不但把代碼和代碼所需的數(shù)據(jù)編譯到了程序中,還把管理代碼的數(shù)據(jù)也放入了程序中,而這部分管理數(shù)據(jù)決定了哪部分是數(shù)據(jù)哪部分是代碼。
因此,用二進(jìn)制寫代碼就需要至少掌握兩方面,一方面是了解可執(zhí)行程序的管理數(shù)據(jù),另一方面就是了解 CPU 的機(jī)器碼。
在 Windows 下的可執(zhí)行程序是 PE 格式的,那么就要了解 PE 格式的數(shù)據(jù)結(jié)構(gòu),和 CPU 的機(jī)器碼;在安卓下的可執(zhí)行程序中,其格式是 DEX 格式,那么就要了解 DEX 格式的數(shù)據(jù)結(jié)構(gòu),以及安卓虛擬機(jī)的字節(jié)碼(這個(gè)字節(jié)碼不是 CPU 的機(jī)器碼,DEX 的字節(jié)碼最終被虛擬機(jī)解釋成機(jī)器碼,因此手寫 DEX 文件時(shí)了解 DEX 格式和其字節(jié)碼即可),同樣的,Java 編譯的 Class 文件也和安卓相同,因?yàn)樗彩腔谔摂M機(jī)執(zhí)行的文件。其中 PE 格式和 DEX 格式就是程序的管理數(shù)據(jù),用于告訴操作系統(tǒng)或虛擬機(jī),整個(gè)文件中代碼、數(shù)據(jù)以及其他資源在文件中的結(jié)構(gòu)。
因?yàn)槎M(jìn)制的閱讀性比較差,因此人們使用了八進(jìn)制和十六進(jìn)制。四位二進(jìn)制可以表示為一位十六進(jìn)制,由于系統(tǒng)是 32 位或 64 位,那么剛好使用 8 個(gè)十六進(jìn)制位表示 32 個(gè)二進(jìn)制位,或者 16 個(gè)十六進(jìn)制位表示 64 個(gè)二進(jìn)制位。因此,在內(nèi)存中查看數(shù)據(jù)時(shí),更多的是使用十六進(jìn)制,其實(shí)從本質(zhì)上十六進(jìn)制和二進(jìn)制是沒有區(qū)別的,只是表示的方式不同。因此,真正使用二進(jìn)制來寫程序時(shí),是使用十六進(jìn)制來完成的。
那么,在使用十六進(jìn)制來編寫 Windows 下的可執(zhí)行程序時(shí),首先需要使用十六進(jìn)制編輯器構(gòu)造 PE 文件結(jié)構(gòu),PE 文件結(jié)構(gòu)主要告訴操作系統(tǒng),程序加載入內(nèi)存后,程序的映射起始地址是多少,程序的入口地址是多少,程序中的代碼和數(shù)據(jù)分別保存在哪里,以及它們的長(zhǎng)度是多少,映射到內(nèi)存中以后其地址是多少,該可執(zhí)行文件調(diào)用了哪些系統(tǒng)函數(shù),這些系統(tǒng)函數(shù)分別在哪些動(dòng)態(tài)鏈接庫(kù)中等信息。構(gòu)造完 PE 文件結(jié)構(gòu)以后,就可以使用機(jī)器碼來寫程序了。只要把機(jī)器代碼寫到 PE 文件結(jié)構(gòu)中標(biāo)識(shí)程序入口的位置處就行了。當(dāng)然了,機(jī)器碼寫程序是比較困難的,但是作為學(xué)習(xí)底層基礎(chǔ)知識(shí)來說,寫一個(gè)簡(jiǎn)單的程序還是可以的,比如寫一個(gè)彈出對(duì)話框的“hello world”這樣的程序。用機(jī)器碼寫這樣的程序,也無需了解太多的知識(shí),有一份 Opcode 的手冊(cè)就可以了。
這就是如何用十六進(jìn)制編輯器來完成一個(gè)可執(zhí)行程序的過程,關(guān)于 PE 文件格式,可以參考 MSDN 或網(wǎng)上的文章,對(duì)于學(xué)習(xí)機(jī)器碼相關(guān)的知識(shí)可以查看 Intel 的指令手冊(cè)。學(xué)習(xí)這些知識(shí)對(duì)于軟件破解、病毒分析、加密解密、內(nèi)核驅(qū)動(dòng)開發(fā)等是相應(yīng)知識(shí)的基礎(chǔ)。
-
cpu
+關(guān)注
關(guān)注
68文章
10829瀏覽量
211194 -
二進(jìn)制
+關(guān)注
關(guān)注
2文章
794瀏覽量
41603 -
WINDOWS
+關(guān)注
關(guān)注
3文章
3526瀏覽量
88451
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論