首先本文不是討論P(yáng)E文件格式本身的,這屬于技術(shù)規(guī)范的范疇,大家要是感興趣可以參看上文中提到的微軟的資料。要是不太喜歡E文的朋友也可以在網(wǎng)上找到很多描述PE格式的文章,在就不再這里贅述了。再說,就算我想講,估計(jì)也講不好(受限于本人的語(yǔ)文水平orz)
我們都很清楚,實(shí)際上PE格式文件里面的section這個(gè)東西是個(gè)很自由的玩意兒,你想把神馬數(shù)據(jù),代碼劃分到哪個(gè)section完全是你的自由。我們一般按照數(shù)據(jù)所需的屬性來進(jìn)行section的劃分,比如我們把代碼放到.text section而把數(shù)據(jù)放到.data section里。但是這種劃分并沒有什么約束限制:首先只要你愿意,你完全可以把代碼放在一個(gè)叫做stupid的section里(當(dāng)然這個(gè)名字按照PE標(biāo)準(zhǔn)不能超過8個(gè)字節(jié));其次同一個(gè)section中也不是只能有一種數(shù)據(jù),比如我可以把程序的符號(hào)表同常量數(shù)據(jù)一同放在.data里(當(dāng)然現(xiàn)實(shí)中他們是分開來的)。
section的存在并不是為了以數(shù)據(jù)功能為準(zhǔn)則劃分?jǐn)?shù)據(jù),而是以數(shù)據(jù)屬性為標(biāo)準(zhǔn)來歸類數(shù)據(jù)。哪些屬性?就是可讀性、可寫性以及可執(zhí)行性。為什么代碼放在.text里?那是因?yàn)榇a是可讀可執(zhí)行但不可寫的;為什么我可以將常量數(shù)據(jù)和程序符號(hào)數(shù)據(jù)放在一起?因?yàn)樗麄兌际强勺x但不可寫亦不可執(zhí)行的;為什么常量數(shù)據(jù)和全局?jǐn)?shù)據(jù)卻不能放到一起?那是因?yàn)榍罢咭蟛豢勺x但后者卻要求這個(gè)屬性。
了解了section這個(gè)東西,下面我們就來分析一下Win32程序中常見的一些section吧(說常見也只能說微軟的linker生成的程序是這樣了,而其他諸如Borland的連接器可不一定使用下面這些section名字):
.text - 不多說了,就是保存代碼的節(jié)
.data - 保存數(shù)據(jù)的節(jié),這個(gè)對(duì)應(yīng)C語(yǔ)言中以初始化的全局變量數(shù)據(jù)。想想為什么你在源碼里初始化一個(gè)全局變量后運(yùn)行時(shí)這個(gè)變量的值正是你想要的那個(gè)?int a = 12;并不意味著CRT為你執(zhí)行了一個(gè)賦值語(yǔ)句,而是a在PE文件中保存的位置已經(jīng)被硬編碼了一個(gè)12的值。這樣loader加載程序時(shí),你給的初值被從PE文件讀取到了內(nèi)存中變量a的位置,這樣才使你的變量a有了初值。
.rdata - 保存常量數(shù)據(jù)的節(jié)。這個(gè)可以對(duì)應(yīng)C語(yǔ)言中的常數(shù)和常量字符串,同上面一樣的原因,他們的初值被保存到了PE文件的次Section中,而不是在運(yùn)行時(shí)被賦值。
.bss - (Block Start with Symbol)這個(gè)section對(duì)應(yīng)C程序中的全局未初始化變量。啥?你說C中未初始化的全局變量實(shí)際上全被初始化成了0?這是因?yàn)閷?shí)際上操作系統(tǒng)是這樣干的——你的全局未初始化變量由于沒有初值,所以不需要將值像上面兩個(gè)一樣保存到PE文件中(所以.bss節(jié)除了描述信息之外不占據(jù)磁盤空間),但是.bss會(huì)描述一段內(nèi)存區(qū)域,loader在加載.bss section時(shí)直接開辟這么一塊包括所有未初始化數(shù)據(jù)的內(nèi)存區(qū)域,然后直接將這區(qū)域清零。這就是C中全局未初始化數(shù)據(jù)之所以為零的原因了。
.idata - 這個(gè)是保存程序?qū)氡?Import Table)的節(jié)。
.rsrc - 這個(gè)是保存導(dǎo)處表的(Export Table)的節(jié)。
.reloc - 這個(gè)節(jié)是保存重定位數(shù)據(jù)的
.rsrc - 這節(jié)是保存程序資源的。想你的程序字符串啊、對(duì)話框模板啊、位圖、鼠標(biāo)光標(biāo)什么的都在這里。實(shí)際上這個(gè)節(jié)儲(chǔ)存.resx文件編譯后的結(jié)果。
.textbss - 這節(jié)比較好玩,它是和微軟Incremental Linking(增量鏈接)特性相關(guān)的。關(guān)于Incremental的特性,我在這篇文章中有說明。