|
段寄存器是什么?Segment Register 也可以稱作 Selector Register 當(dāng)我們用匯編讀寫某個地址時 MOV DWORD PTR DS:[0X00401000],EAX 我們讀寫的地址其實是DS.BASE+0x00401000 0x00401000被稱為讀寫的有效地址 DS.BASE+0x00401000被稱為線性地址,這里做了解即可 段寄存器有自己結(jié)構(gòu) 段寄存器一共96位,但是可見部分只有16位 ![]() Struct SegMent{ WORD Selector; //16位段選擇子 WORD Attributes; //16位屬性 DWORD Base; //32位基址 DWORD Limit; //32位段限長} 其中不可見部分暫不理會,可見部分可以通過OD隨便打開一個程序查看 ![]() 其中紅色部分就是段選擇子Selector 段寄存器 Selector Attribute Base Limit ES 002B 可讀,可寫 0 0xFFFFFFFF CS 0023 可讀,可執(zhí)行 0 0xFFFFFFFF SS 002B 可讀,可寫 0 0xFFFFFFFF DS 002B 可讀,可寫 0 0xFFFFFFFF FS 0053 可讀,可寫 0x7FFDE000 0xFFF GS --- --- --- --- 為了驗證段寄存器的屬性: ---Selector MOV AX,ES 這里的段選擇子為16位,只能使用16位AX寄存器,不能使用32位EAX寄存器 EAX 0000002BECX 00FF0000 通過讀取段寄存器,我們發(fā)現(xiàn)只能讀取16位,這可見部分就是段選擇子 -------------------------------------------------------------------------------------- ---Attribute int var = 0;__asm{ MOV AX,FS //不能換成DS MOV GS,AX MOV EAX,GS:[0] MOV DWORD PTR DS:[VAR],EAX //MOV DWORD PTR DS:[0X7FFDF000]}執(zhí)行上面代碼發(fā)現(xiàn)并沒有什么用,因為DS修飾的段指向了SS,SS段寄存器可讀可寫 如果把SS換成CS,就會發(fā)現(xiàn)訪問錯誤,因為CS可讀可執(zhí)行,但是并不可寫 -------------------------------------------------------------------------------------- ---Base int var = 0;__asm{MOV AX,FS //不能換成DSMOV GS,AXMOV EAX,GS:[0]MOV DWORD PTR DS:[VAR],EAX//MOV DWORD PTR DS:[0X7FFDF000]} 如果訪問地址0會報內(nèi)存訪問錯誤0xC0000005錯誤這是常識,但是由于FS段寄存器的Base為0X7FFDF000 線性地址=FS.Base+有效地址 ---------------------- FS.0X7FFDF000+0x00000000 等于說直接訪問了0X7FFDF000這個位置,雖然我們代碼里寫的是0 如果換成其他Base為0的寄存器就會發(fā)現(xiàn)內(nèi)存訪問錯誤 ------------------------------------------------------------------------------------- ---Limint int var = 0;__asm{MOV AX,FS //不能換成DSMOV GS,AXMOV EAX,GS:[0x1000]MOV EAX,DWORD PTR DS:[0X7FFDF000+0x1000]MOV DWORD PTR DS:[var],EAX}0x0X7FFDF000+0x1000 FS段寄存器的段限長為FFF,但是我們讀取的是0x1000位置的數(shù)據(jù),這就能證明段的Limint真實存在 -------------------------------------------------------------------------------------- 通過以上4個小實驗,證明了一個完整的段描述符具有這4個基本屬性 |
|
|
來自: 喜歡站在山上 > 《匯編語言及內(nèi)核》