天天看點

仿照着寫個bootloader(6) 保護模式下修改代碼段

    标題讓我想起win驅動中修改隻讀頁的内容:新申請一個PTE指向該頁,PTE中的權限改為讀寫,就能修改頁面内容啦。

    現在階段我的bootloader還沒有建立起分頁機制,僅僅開啟分段,是以,通過修改PTE啥的肯定不奏效,能做的隻有修改段描述符了。

    先看下我代碼中的段描述表:

mov dword [bx],0x00000000
mov dword [bx+4],0x00000000
;代碼段 0x7c00 權限 讀執行
add bx,0x08
mov dword [bx],0x7c0001ff 
mov dword [bx+4],0x00409A00
;資料段 0x7c00 權限 讀寫
add bx,0x08
mov dword [bx],0x7c0001ff 
mov dword [bx+4],0x00409200

mov word [cs:gdtSize+0x7c00],0x08*3-1
lgdt [cs:0x7c00+gdtSize]      

讀寫代碼段記憶體的代碼:

Code:
  ;1)直接讀取代碼段
  lea edx,[cs:Code]
  mov eax,[cs:edx]
  
  ;2)直接修改代碼段
  xor eax,eax
  lea edx,[cs:Code]
  mov [cs:edx],eax
  ;3)段選擇子指向代碼段,但是把權限改為資料段
  xor eax,eax
  mov ax,0x10
  mov ds,ax
  lea edx,[cs:Code]
  mov word [edx],0x9090
jmp Code      

運作bochs,執行到1)處時:

仿照着寫個bootloader(6) 保護模式下修改代碼段

【黃色高亮處】反彙編記憶體0x7c76,數值為2e8d1576,執行完mov eax,[cs:edx]後 eax的内容為0x76158d2e (注意是小端機)。可知,代碼成功讀取了0x7c76處的内容

再往下執行到2)處:出錯了,bochs也提示 no write access to seg。

仿照着寫個bootloader(6) 保護模式下修改代碼段

其實,也不算出錯,隻是一個頁面異常,沒被捕獲處理。怪我了,還是個簡單的bootloader。

回過頭看下,進入保護模式時,這個代碼段的權限:

仿照着寫個bootloader(6) 保護模式下修改代碼段

bochs說的很清楚了,代碼段,起始于0x7c00權限是讀執行。當然,如果段描述符的TYPE字段改為0x4096即隻執行,那運作到第一步時也會出現異常。

好吧,到這有個問題:難道在未開啟頁機制前,代碼段不能寫了?再進一步,沒法往代碼段設定int 0x3斷點了(不能實時調試)?

這倒也不是,隻要為該段安裝一個新的描述符,并把其可讀寫的資料段,最後加載該描述符,這樣就可以修改代碼段内的資料了。現在來看下修改後的代碼:

flush:
Code:
  ;段選擇子指向代碼段,但是把權限改為資料段
  xor eax,eax
  mov ax,0x10
  mov ds,ax
  lea edx,[cs:Code]
  mov word [edx],0x9090
jmp Code      

bochs運作起來:

仿照着寫個bootloader(6) 保護模式下修改代碼段

繼續閱讀