1. 程式人生 > >3.保護模式7-特權級轉移(通過呼叫門轉移目標段-無特權級轉換)

3.保護模式7-特權級轉移(通過呼叫門轉移目標段-無特權級轉換)

在上次的程式碼基礎上,新增一個程式碼段作為通過呼叫門轉移的目標段。瞭解一下呼叫的工作方法,程式碼分析如下:

<<紅色標識部分為新增程式碼>>

; ==========================================
; pmtest4.asm
; 編譯方法:nasm pmtest4.asm -o pmtest4.com
; ==========================================

%include    "pm.inc"    ; 常量, 巨集, 以及一些說明

org    0100h
    jmp    LABEL_BEGIN

[SECTION .gdt]
; GDT
;                           段基址,       段界限     , 屬性
LABEL_GDT:            Descriptor 0,                 0, 0       ; 空描述符
LABEL_DESC_NORMAL:    Descriptor 0,          0ffffh, DA_DRW    ; Normal 描述符
LABEL_DESC_CODE32:    Descriptor 0,  SegCode32Len-1, DA_C+DA_32; 非一致程式碼段,32
LABEL_DESC_CODE16:    Descriptor 0,          0ffffh, DA_C      ; 非一致程式碼段,16
LABEL_DESC_CODE_DEST: Descriptor 0,SegCodeDestLen-1, DA_C+DA_32; 非一致程式碼段,32;目的碼描述符

LABEL_DESC_DATA:      Descriptor 0,       DataLen-1, DA_DRW    ; Data
LABEL_DESC_STACK:     Descriptor 0,      TopOfStack, DA_DRWA+DA_32;Stack, 32 位
LABEL_DESC_LDT:       Descriptor 0,        LDTLen-1, DA_LDT    ; LDT
LABEL_DESC_VIDEO:     Descriptor 0B8000h,    0ffffh, DA_DRW    ; 視訊記憶體首地址

; 門                               目標選擇子,偏移,DCount, 屬性
LABEL_CALL_GATE_TEST: Gate SelectorCodeDest,   0,     0, DA_386CGate+DA_DPL0;呼叫門描述符DPL=0

; GDT 結束

GdtLen        equ    $ - LABEL_GDT    ; GDT長度
GdtPtr        dw    GdtLen - 1    ; GDT界限
                 dd    0        ; GDT基地址

; GDT 選擇子
SelectorNormal        equ    LABEL_DESC_NORMAL    - LABEL_GDT
SelectorCode32        equ    LABEL_DESC_CODE32    - LABEL_GDT
SelectorCode16        equ    LABEL_DESC_CODE16    - LABEL_GDT
SelectorCodeDest    equ    LABEL_DESC_CODE_DEST    - LABEL_GDT;目的碼選擇子
SelectorData        equ    LABEL_DESC_DATA        - LABEL_GDT
SelectorStack        equ    LABEL_DESC_STACK    - LABEL_GDT
SelectorLDT        equ    LABEL_DESC_LDT        - LABEL_GDT
SelectorVideo        equ    LABEL_DESC_VIDEO    - LABEL_GDT

SelectorCallGateTest    equ    LABEL_CALL_GATE_TEST    - LABEL_GDT;呼叫門選擇子
; END of [SECTION .gdt]

[SECTION .data1]     ; 資料段
ALIGN    32
[BITS    32]
LABEL_DATA:
SPValueInRealMode    dw    0
; 字串
PMMessage:        db    "In Protect Mode now. ^-^", 0    ; 進入保護模式後顯示此字串
OffsetPMMessage        equ    PMMessage - $$
StrTest:        db    "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0
OffsetStrTest        equ    StrTest - $$
DataLen            equ    $ - LABEL_DATA
; END of [SECTION .data1]

; 全域性堆疊段
[SECTION .gs]
ALIGN    32
[BITS    32]
LABEL_STACK:
    times 512 db 0

TopOfStack    equ    $ - LABEL_STACK - 1

; END of [SECTION .gs]

[SECTION .s16]
[BITS    16]
LABEL_BEGIN:
    mov    ax, cs
    mov    ds, ax
    mov    es, ax
    mov    ss, ax
    mov    sp, 0100h

    mov    [LABEL_GO_BACK_TO_REAL+3], ax
    mov    [SPValueInRealMode], sp

    ; 初始化 16 位程式碼段描述符
    mov    ax, cs
    movzx    eax, ax
    shl    eax, 4
    add    eax, LABEL_SEG_CODE16
    mov    word [LABEL_DESC_CODE16 + 2], ax
    shr    eax, 16
    mov    byte [LABEL_DESC_CODE16 + 4], al
    mov    byte [LABEL_DESC_CODE16 + 7], ah

    ; 初始化 32 位程式碼段描述符
    xor    eax, eax
    mov    ax, cs
    shl    eax, 4
    add    eax, LABEL_SEG_CODE32
    mov    word [LABEL_DESC_CODE32 + 2], ax
    shr    eax, 16
    mov    byte [LABEL_DESC_CODE32 + 4], al
    mov    byte [LABEL_DESC_CODE32 + 7], ah

    ; 初始化測試呼叫門的程式碼段描述符
    xor    eax, eax
    mov    ax, cs
    shl    eax, 4
    add    eax, LABEL_SEG_CODE_DEST
    mov    word [LABEL_DESC_CODE_DEST + 2], ax
    shr    eax, 16
    mov    byte [LABEL_DESC_CODE_DEST + 4], al
    mov    byte [LABEL_DESC_CODE_DEST + 7], ah

    ; 初始化資料段描述符
    xor    eax, eax
    mov    ax, ds
    shl    eax, 4
    add    eax, LABEL_DATA
    mov    word [LABEL_DESC_DATA + 2], ax
    shr    eax, 16
    mov    byte [LABEL_DESC_DATA + 4], al
    mov    byte [LABEL_DESC_DATA + 7], ah

    ; 初始化堆疊段描述符
    xor    eax, eax
    mov    ax, ds
    shl    eax, 4
    add    eax, LABEL_STACK
    mov    word [LABEL_DESC_STACK + 2], ax
    shr    eax, 16
    mov    byte [LABEL_DESC_STACK + 4], al
    mov    byte [LABEL_DESC_STACK + 7], ah

    ; 初始化 LDT 在 GDT 中的描述符
    xor    eax, eax
    mov    ax, ds
    shl    eax, 4
    add    eax, LABEL_LDT
    mov    word [LABEL_DESC_LDT + 2], ax
    shr    eax, 16
    mov    byte [LABEL_DESC_LDT + 4], al
    mov    byte [LABEL_DESC_LDT + 7], ah

    ; 初始化 LDT 中的描述符
    xor    eax, eax
    mov    ax, ds
    shl    eax, 4
    add    eax, LABEL_CODE_A
    mov    word [LABEL_LDT_DESC_CODEA + 2], ax
    shr    eax, 16
    mov    byte [LABEL_LDT_DESC_CODEA + 4], al
    mov    byte [LABEL_LDT_DESC_CODEA + 7], ah

    ; 為載入 GDTR 作準備
    xor    eax, eax
    mov    ax, ds
    shl    eax, 4
    add    eax, LABEL_GDT        ; eax <- gdt 基地址
    mov    dword [GdtPtr + 2], eax    ; [GdtPtr + 2] <- gdt 基地址

    ; 載入 GDTR
    lgdt    [GdtPtr]

    ; 關中斷
    cli

    ; 開啟地址線A20
    in    al, 92h
    or    al, 00000010b
    out    92h, al

    ; 準備切換到保護模式
    mov    eax, cr0
    or    eax, 1
    mov    cr0, eax

    ; 真正進入保護模式
    jmp    dword SelectorCode32:0    ; 執行這一句會把 SelectorCode32 裝入 cs, 並跳轉到 Code32Selector:0  處

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

LABEL_REAL_ENTRY:        ; 從保護模式跳回到真實模式就到了這裡
    mov    ax, cs
    mov    ds, ax
    mov    es, ax
    mov    ss, ax

    mov    sp, [SPValueInRealMode]

    in    al, 92h        ; ┓
    and    al, 11111101b    ; ┣ 關閉 A20 地址線
    out    92h, al        ; ┛

    sti            ; 開中斷

    mov    ax, 4c00h    ; ┓
    int    21h        ; ┛回到 DOS
; END of [SECTION .s16]

[SECTION .s32]; 32 位程式碼段. 由真實模式跳入.
[BITS    32]

LABEL_SEG_CODE32:
    mov    ax, SelectorData
    mov    ds, ax            ; 資料段選擇子
    mov    ax, SelectorVideo
    mov    gs, ax            ; 視訊段選擇子

    mov    ax, SelectorStack
    mov    ss, ax            ; 堆疊段選擇子

    mov    esp, TopOfStack

    ; 下面顯示一個字串
    mov    ah, 0Ch            ; 0000: 黑底    1100: 紅字
    xor    esi, esi
    xor    edi, edi
    mov    esi, OffsetPMMessage    ; 源資料偏移
    mov    edi, (80 * 10 + 0) * 2    ; 目的資料偏移。螢幕第 10 行, 第 0 列。
    cld
.1:
    lodsb
    test    al, al
    jz    .2
    mov    [gs:edi], ax
    add    edi, 2
    jmp    .1
.2:    ; 顯示完畢

    call    DispReturn

    ; 測試呼叫門(無特權級變換),將列印字母 'C'
    call    SelectorCallGateTest:0
    ;call    SelectorCodeDest:0 ---SelectorCallGateTest的選擇子為SelectorCodeDest,偏移為0

    ; Load LDT
    mov    ax, SelectorLDT
    lldt    ax

    jmp    SelectorLDTCodeA:0    ; 跳入區域性任務,將列印字母 'L'。

; ------------------------------------------------------------------------
DispReturn:
    push    eax
    push    ebx
    mov    eax, edi
    mov    bl, 160
    div    bl
    and    eax, 0FFh
    inc    eax
    mov    bl, 160
    mul    bl
    mov    edi, eax
    pop    ebx
    pop    eax

    ret
; DispReturn 結束---------------------------------------------------------

SegCode32Len    equ    $ - LABEL_SEG_CODE32
; END of [SECTION .s32]

[SECTION .sdest]; 呼叫門目標段
[BITS    32]

LABEL_SEG_CODE_DEST:
    ;jmp    $
    mov    ax, SelectorVideo
    mov    gs, ax            ; 視訊段選擇子(目的)

    mov    edi, (80 * 12 + 0) * 2    ; 螢幕第 12 行, 第 0 列。
    mov    ah, 0Ch            ; 0000: 黑底    1100: 紅字
    mov    al, 'C'
    mov    [gs:edi], ax

    retf

SegCodeDestLen    equ    $ - LABEL_SEG_CODE_DEST
; END of [SECTION .sdest]

; 16 位程式碼段. 由 32 位程式碼段跳入, 跳出後到真實模式
[SECTION .s16code]
ALIGN    32
[BITS    16]
LABEL_SEG_CODE16:
    ; 跳回真實模式:
    mov    ax, SelectorNormal
    mov    ds, ax
    mov    es, ax
    mov    fs, ax
    mov    gs, ax
    mov    ss, ax

    mov    eax, cr0
    and    al, 11111110b
    mov    cr0, eax

LABEL_GO_BACK_TO_REAL:
    jmp    0:LABEL_REAL_ENTRY    ; 段地址會在程式開始處被設定成正確的值

Code16Len    equ    $ - LABEL_SEG_CODE16

; END of [SECTION .s16code]

; LDT
[SECTION .ldt]
ALIGN    32
LABEL_LDT:
;                                         段基址       段界限     ,   屬性
LABEL_LDT_DESC_CODEA:    Descriptor           0,     CodeALen - 1,   DA_C + DA_32    ; Code, 32 位

LDTLen        equ    $ - LABEL_LDT

; LDT 選擇子
SelectorLDTCodeA    equ    LABEL_LDT_DESC_CODEA    - LABEL_LDT + SA_TIL
; END of [SECTION .ldt]

; CodeA (LDT, 32 位程式碼段)
[SECTION .la]
ALIGN    32
[BITS    32]
LABEL_CODE_A:
    mov    ax, SelectorVideo
    mov    gs, ax            ; 視訊段選擇子(目的)

    mov    edi, (80 * 13 + 0) * 2    ; 螢幕第 13 行, 第 0 列。
    mov    ah, 0Ch            ; 0000: 黑底    1100: 紅字
    mov    al, 'L'
    mov    [gs:edi], ax

    ; 準備經由16位程式碼段跳回真實模式
    jmp    SelectorCode16:0
CodeALen    equ    $ - LABEL_CODE_A
; END of [SECTION .la]

本程式碼只是展示了呼叫的使用方式,即提供了目的碼段的入口地址及相關附加屬性(無特權級的轉移),如果需要特權級的轉移,則需

參照以下規則:

假設我們有程式碼A轉移到程式碼B,使用一個呼叫G,即呼叫門G中的目標選擇子指向程式碼B的段。我們涉及到這麼幾個要素CPL、RPL、

介紹可知A訪問呼叫門G時,相當於訪問一個數據段,要求CPL和RPL都小於或者等於DPL_G.換句話說,CPL和RPL須在更高的特權級上.

除此之外,還需比較CPL和DPL_B,如果是一致程式碼段,則要求DPL_B<=CPL;如果是非一致程式碼段,call和jmp指令又有所不同,使用

CALL時,要求DPL_B<=CPL;使用Jmp時,只能是DPL-B=CPL

規則如下

目的碼段 call jmp
目標是一致程式碼段 CPL<=DPL_G 同CALL
RPL<=DPL_G 同CALL
DPL_B<=CPL 同CALL
目標是非一致程式碼 CPL<=DPL_G CPL<=DPL_G
RPL<=DPL_G RPL<=DPL_G
DPL_B<=CPL DPL_B=CPL

綜上:通過呼叫門和call指令,可以實現從低特權級到高特權級的轉移,無論目的碼是一致的還是非一致的

相關推薦

3.保護模式7-特權轉移(通過呼叫轉移目標-特權轉換)

在上次的程式碼基礎上,新增一個程式碼段作為通過呼叫門轉移的目標段。瞭解一下呼叫的工作方法,程式碼分析如下: <<紅色標識部分為新增程式碼>> ; ========================================== ; pmtest4.asm ; 編譯方法:na

3.保護模式7-特權轉移(通過呼叫轉移目標-有特權轉換-進入ring3-b)

我們在進入ring3後,實現了高特權級到低特權級的轉移,我們在原有程式碼上稍作修改,實現低特權級到高特權級的轉移: 修改的程式碼如下: 1.修改呼叫門描述符和選擇的特權級 ; 門                               目標選擇子,偏移,DCount, 屬性 LABEL_CALL_G

保護模式程式設計——保護的詳盡意義:通過呼叫轉移特權

摘要:在組合語言的程式設計和作業系統的編寫過程中,我們經常能聽說到“保護模式”這個名詞。為什麼要叫“保護模式”呢?保護 二字的含義何在?本文主要探討,“保護模式”下面各種具體的保護機制,這些保護機制產生的原因和具體的影響。閱讀本文之前,讀者需要了解基本的處理器相關知識,知

3.保護模式5----特權概述(轉)

3、DPL,RPL,CPL 之間的聯絡和區別是什麼?RPL和CPL是必須相同嗎?如果相同,為什麼要釆用兩個而不改用一個呢? 答:特權級是保護模式下一個重要的概念,CPL,RPL和DPL是其中的核心概念,查閱資料無數,總結如下:   簡單解釋: ------------------------------

80x86保護模式特權轉移

80386搞的這個保護模式,最大的特點就是加入了安全檢查,不再像真實模式下那樣,程式程式碼可以隨意jmp,隨意call了,受到了特權級的約束,關於特權級的概念我看無數的資料,各種大牛的解釋,反覆理解了好多次,這回我要再次整理一下。CPL:當前CPU正在處理的程式碼段的特權級

第16課 - 保護模式中的特權(中)

pro 啟用 add 應用場景 ima 不同 http == sas 一種新的描述符:門描述符(Gate Descriptor) 通過門描述符在不同特權級的代碼間進行跳轉 根據應用場景的不同,門描述符分為: 調用門(Call Gates)

保護模式總結(二)——任務和特權

       32位保護模式相對真實模式來說,除了記憶體保護,還多了一大功能,那就是多工。今天總結的內容就從多工入手。        程式本質上是指令和資料,任務是程式為了完成某個特定的工作而執行的一個副本。        這是抽象的描述,任務在計算機中具體是由什麼描述的呢

任務和特權保護(一)——《x86組合語言:從真實模式保護模式》讀書筆記27

本文及後面的幾篇文章是原書第14章的讀書筆記。 1.LDT(區域性描述符表) 在之前的學習中,不管是核心程式還是使用者程式,我們都是把段描述符放在GDT中。但是,為了有效實施任務間的隔離,處理器建議每個任務都應該有自己的描述符表,稱為區域性描述符表LDT

32位保護模式學習小結(3)---任務切換

兩種基本的任務切換方式 協同式:從一個任務切換到另一個任務,需要當前任務主動地請求暫時放棄執行權,或者在通過呼叫門請求作業系統服務時,由作業系統”趁機”將控制轉移到另一個任務.這種方式依賴於每個任務的”自律”性,當一個任務失控時,其他任務可能得不到執行的機會

新手上路——hadoop2.7.3單機模式環境搭建

目的 本人是一隻hadoop新手,本篇文章主要是個人學習hadoop的學習筆記,內容是搭建單機模式下hadoop2.7.3開發環境。 搭建環境及所需軟體 VMWare 12(64位),ubuntu-16.04(64位),hadoop2.7.3.tar H

通過retf和呼叫實現特權轉換

不打算按別人的思路來,因為在我學的過程中上網查,發現網上的部落格都是互相抄的,最終還是抄書的。 Intel 64 和 IA-32架構處理器在進入保護模式之後,就會有一些列保護機制。其中出現了三個特別重要的東西:CPL、DPL、RPL。 CPL表示當前

【原創 Hadoop&Spark 動手實踐 3】Hadoop2.7.3 MapReduce理論與動手實踐

pack license 讀取 rgs 理論 程序員開發 -s 接口 pri 開始聊MapReduce,MapReduce是Hadoop的計算框架,我學Hadoop是從Hive開始入手,再到hdfs,當我學習hdfs時候,就感覺到hdfs和mapreduce關系的緊密。這個

CentOS7.3安裝MySQL5.7

blog 錯誤 com 原因 rpm /var/ inux rep 問題 Linux和Mysql版本更新後,由於已知的mysql被收購的原因,導致mysql不會再發布於centos默認的yum源中。 而使用rpm的安裝方式,又會有蠻多的依賴問題,因此本次嘗試使用官方提供的

x86CPU 實模式 保護模式 傻傻分不清楚? 基於Xv6-OS 分析CR0 寄存器

獲取 ack oot pop -o sdn 行程 model 保護 基於Xv6-OS 分析CR0 寄存器 之前一直認為暈乎乎的...啥?什麽時候切換real model,怎麽切換,為什麽要切換? -----------------------------------

c++ 設計模式7 (Bridge 橋模式

設計模式 play 復制代碼 復用性 ict 只有一個 mage 單一職責原則 sea 4.2 Bridge 橋模式 動機: 由於某些類型的固有的實現邏輯,使得它們具有兩個變化的維度,乃至多個變化的維度。 代碼示例: 實現一個Messager,含有基本功能PlaySo

Centos7.3,mysql5.7環境,數據存儲空間加大調整方案。

mysqlCentos7.3Mysql 5.7分區信息如下df -hFilesystem Size Used Avail Use% Mounted on /dev/mapper/cl_gr61-root 50G 6.6G 44G 14% / devtmpfs

Centos7.3 安裝Mysql5.7並修改初始密碼

centos7.3 安裝mysql5.7並修改初始密碼Centos7.3 安裝Mysql5.7並修改初始密碼1、官方安裝文檔http://dev.mysql.com/doc/mysql-yum-repo-quick-guide/en/2、下載 Mysql yum包http://dev.mysql.com/do

十一. 圖形、圖像與多媒體3.繪圖模式

ava 多媒體 etx 一個 可見 出現 圖像 load 混合 繪圖模式是指後繪制的圖形與早先繪制的圖形有重疊時,如何確定重疊部分的顏色。例如,後繪制的覆蓋早先繪制的;或者後繪制與早先繪制的兩種顏色按某種規則混合。主要有正常模式和異或模式兩種:正常模式是後繪制的圖形覆蓋在早

JavaScript設計模式-3.原型模式

掛載 r+ eof style 數據 默認 per blog script 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"&g

JavaScript設計模式-7.單例模式

閉包 cname XML 數據庫 模式 inf 設計模式 分支 col 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"