⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 baohu.txt

📁 关于黑客的论坛的下载资料
💻 TXT
📖 第 1 页 / 共 5 页
字号:
                                                  ┌┐┌┐∞
【 80386保护模式简介二 】                    ┘└┘└┘
--------------------------------------------------------------------------
    进入保护模式可以得到很多好处 ,让你的程式不再有 640K 限制 ,可以产生虚
拟记忆体、拦 I/O ,所有的应用程式读写系统暂存器 ,产生中断....都可以完全拦
截 ,而且 TSS 工作切换能力可以让你不占用 DOS 下的堆叠区 ,还有很多好处无法
一一叙述 ,因此由笔者来教你如何切入保护模式吧....从简单的开始。
 
    在保护模式下有很多新的名词 ,包含 GDT.LDT.IDT 以及 CR0-CR3 ,笔者对保护
模式并不清楚 ,所以底下资料可能有错误。这里使用大量的线性记忆体观念 ,请您
一定要从头往後看 ,否则很可能会看不懂 ,且必须懂线性记忆体计算方式。
 
--------------------------------------------------------------------------
    在进入保护模式时 ,首先你要先设定 GDT 表格 ,这个表格描述主要是来定义每
个段落的记忆体起始位址与长度、存取权。   这个情形就好像传统 REAL MODE  那
样 ,REAL MODE 每个区段的记忆体开始位址与长度都已经由 CPU 定死了 ,比如说当
我们看到 1000:0000 ,其实它就是指记忆体的第 64K 位址 ,同理看到 2000:0000
就代表是第 128K 位址 ,定址方式就是 Segment:Offset。
 
    而保护模式的段落起始位址与长度却是可程式变动的 ,这个可变动的段落起始
位址与长度就是由 GDT 来设定的 ,根据这个值 ,你可以将每个段落改成64K ,或是
1MB...甚至更多 ,可任意设定 1BYTE~4GB ,所以定址方式变成 Selector:Offset
或许您曾用过 386DEBUG ,看过定址方式为 XXXX:XXXXXXXX ,根据後面这八位数 ,
理论上可定址到 4GB ,其实这是不行的 ,如果你在 GDT 表格设定的记忆体为 1K
则你尝试 DUMP 1K 以後的记忆体都会看到 FF ,就好像没有记忆体一般。
 
---------------------------------------------------------------------------
Gdtadds dw      0018h,GdtTable 32 位元线性位址
GdtTable db     00h,00h,00h,00h,00h,00h,00h,00h         ;
        db      7fh,ffh,00h,08h,0bh,93h,00h,00h         ;B800:0 32K
        db      ffh,ffh,56h,34h,12h,93h,0fh,78h         ;
                ^^^^^^^ ^^^^^^^^^^^ ^^^ ^^^ ^^^
                ↑      ↑          ↑  ↑  ↑
                │      │          └——————93=可读写区段
                │      │              │  │
                └———————————┴————0fffff+1=1MB (Limits)
                        │                  │
                        └—————————┴——12345678 (Base)
 
 
它所代表的意思是如下图所示:(每组 8 byte)
 
        ┌——————————————————————┐
       1│                Limit bit 0-15              │ 0 byte
        ├——————————————————————┤
       3│                Base bit 0-15               │ 2
        ├——————————┬———————————┤
       5│       存取权       │    Base bit 16-23    │ 4
        ├——————————┼———————————┤
       7│   Base bit 24-31   │G│..│limit bit 16-19│ 6
        └——————————┴———————————┘
            "G"代表 Limit 的单位是 Byte 或 PAGE(4K)
 
所以....
 
#0000  Segment not present.
#0008  Base=000B8000  Limit=0000FFFF  Flags=93  USE32  Byte granularity
#0010  Base=12345678  Limit=000FFFFF  Flags=93  USE32  Byte granularity
^^^^^Selector                               ^^存取权
 
 
 
设定完後 ,就是切入保护模式 ,只要将 CR0 暂存器的 Bit0 设为 '1' ,再用一个
跳越指令 ,就进入保护模式了。
 
 
---------------------------------------------------------------------------
讲不懂没关系 ,现在来看看实例 ,这样比较容易懂..
 
C:\>386MICE SAMPLE.EXE
-G 1AE
EAX=00044A1C  EBX=00000003  ECX=00000000  EDX=00000100
ESI=00000000  EDI=00000000  EBP=00000000  ESP=0000FFFE
DS=4A1C  SS=4A1C  ES=4A1C  FS=4A0C  GS=4A0C
-U 1AE
4A1C:000001AE           CLI
4A1C:000001AF           LGDT    CS:[BX]     ——→ DUMP CS:[BX] ——→ 
4A1C:00000003  18 00 C9 A1 04 00 <--- GDT 表放在 0004A1C9 长度 18h
4A1C:000001B3           MOV     
EAX,CR0                                                        │
4A1C:000001B6           OR      
EAX,1                                                          ↓
4A1C:000001BA           MOV     CR0,EAX                                
4A1C:00000009  00 00 00 00 00 00 00 00-FF FF C0 A1 04 9B 00-00
4A1C:000001BD           JMP     01C0                                   
4A1C:00000010  FF FF 00 80 0B 93 00 00 (GDT表)
4A1C:000001BF           NOP
4A1C:000001C0           MOV     AX,0008H
4A1C:000001C3           MOV     DS,AX
4A1C:000001C5           MOV     WORD PTR DS:[0000H],7041h
 
 
由上面的 GDT 表知道 此程式共规划了三个区段 ,其中 0000 区段是不使用
故区段的表示方式如下:
 
#0000  Segment not present.
#0008  Base=0004A1C0  Limit=0000FFFF  Flags=9B  USE32  Byte granularity
#0010  Base=000B8000  Limit=0000FFFF  Flags=93  USE32  Byte granularity
 
 
 
-G 1BD
EAX=00000001  EBX=00000003  ECX=00000000  EDX=00000100
ESI=00000000  EDI=00000000  EBP=00000000  ESP=0000FFFE
DS=4A1C  SS=4A1C  ES=4A1C  FS=4A0C  GS=4A0C
4A1C:000001BD           JMP     01C0
 
-T (这儿就算是进入保护模式了)
EAX=00000001  EBX=00000003  ECX=00000000  EDX=00000100
ESI=00000000  EDI=00000000  EBP=00000000  ESP=0000FFFE
DS=0000  SS=0000  ES=0000  FS=0000  GS=0000
0000:000001C0           MOV     AX,0008H
0000:000001C3           MOV     DS,AX
0000:000001C5           MOV     WORD PTR DS:[0000H],7041h
 
 
 
因为进入保护模式 ,所以 Selector 的区段应该要去查 GDT 表格 ,这个例
子的 Selector 0010 的 Base = B8000 ,所以...
保护模式下的 0010:00000000 = 真实模式下的 B800:0000 ,这样您懂了吗?
 
在行号 1C5 的位址有一行写入 7041 的动作 ,就是在萤幕秀 'A' 反白字元.
 
最後要进入真实模式时 ,只要将 CR0 的 Bit0 设为 '0' ,再用一个跳越指
令就回到真实模式了..
 
--------------------------------------------------------------------------
後记:
    若有问题 ,烦在本站『站内信箱』留信给我....尽量避免使用网路信 ,
且尽快提出 ,否则接下来的课程将会更难懂 ,如果你是完全不懂 ,麻烦也留
信给我 ,我会再把这一章节再细细重新说明。至於对组合语言不懂 ,或是对
保护模式没兴趣的人 ,本人就帮不上忙了。
 
    A:下一次笔者将继续解说 V86 模式下的工作切换
    B:等级权限 / 拦 I/O
 
┌———————————————————————————————————┐
│  Soft Bugger 软体蛀虫 90:90/2                    软体新技术的实行者  │
│  BBS:02-5955461 24HR          ID:Werong Ho               -- 软蛀 --  │
└———————————————————————————————————┘
 
 


                                                    ┌┐┌┐∞
【 80386 保护模式简介三 】                     ┘└┘└┘
==========================================================================
前言:
 
    前面两集主要是要告诉各位有关 IDT.GDT 的用法 ,虽然这样已经可以简单的进
入保护模式 ,但是它还不足以让你撰写程式 ,因此笔者还必需往下继续叙说 ,不过再
往下讲之前 ,又有一票烦且杂的观念要说 ,本篇还是继续在"观念"上打转 ,读者千万
不要以为本篇又是「干古」 ,如果本篇不懂的话 ,後面的精彩文章您大概也看不懂 ,
笔者会尽量把文章写到容易懂的范围。
 
--------------------------------------------------------------------------
┌————————┐
│80386 暂存器介绍│
└————————┘
 
    80386 的暂存器除了扩充成 32 位元以外 ,亦增加了许多新的暂存器 ,除了一般
使用者暂存器(AX.BX....SI.DI)各位已经了解以外 ,也增加了系统暂存器、以及扩充
的旗标 暂存器....等等。
 
 
A.使用者暂存器   → EAX.EBX.ECX.EDX.ESI,EDI.EBP.ESP
 
B.指令指标暂存器 → CS.EIP 两个暂存器
 
C.区段暂存器     → CS.SS.DS.ES.FS.GS
    虽然 80386 已经进入 32 位元时代 ,但是这几个暂存器仍是 16 位元的 ,且多
    了 FS.GS 两个暂存器 ,这两个暂存器并无特殊意义 ,各位可以把它当做 DS.ES
    来看待。
 
D.系统暂存器
    A. 控制暂存器:包含 CR0.CR2.CR3 三个 ,各位可能看到漏了一个 CR1 ,原因是
       386.486.586 都没有此暂存器
    B. 除错暂存器:包含 DR0.DR1.DR2.DR3.DR6.DR7 共六个 ,也是漏了 DR4.DR5 两
       个 ,原因同上
    C. 保护模式分段控制:IDT.GDT.LDT.TR
 
--------------------------------------------------------------------------
┌————┐
│工作切换│
└————┘
 
    当您设定某些系统暂存器以後 ,电脑并不会马上反应所设定的工作 ,必需透过工
作切换的动作才会起动 ,这个工作切换很难难用文字表达 ,笔者认为工作切换就是等
级切换的动作。可造成工作切换的指令包含 INT_X 、JMP TSS区段...等 ,其中INT_X
是指在 V86 下的程式若发生中断 ,电脑会自动切换至保护模式 ,并呼叫保护模式下的
中断处理程式 ,再由保护模式下的程式决定是否呼叫原来 V86  下的中断向量表 ,而
这切换到保护模式、再切回 V86 下 , 共发生两次工作切换......
 
┌——┐
│等级│
└——┘
 
    保护模式下 ,等级共有 0.1.2.3 四个等级 ,其中第0级等级最高 ,第3级最低 ,
而0级因为是最高等级 ,因此也有人称为「特权等级」 ,而应用程式的等级为多少呢?
这表示在 EFLAG 的 IOPL (BIT12.13) 里 ,在 V86 下的等级多半是最低的第3级 ,所
以此值为 '11'。
 
    或许各位会认为自己去修改这个旗标将自己的等级调高就好了 ,事实上改好後还
要经过工作切换的动作 ,等级才能被修改 ,而经过工作切换的动作後 ,你的程式控制
权将转交给别人 ;再简单的说 ,发生 INT_X 时 ,电脑会将等级切换成最高等级(事实
上是由中断表上决定的) ,并进入保护模式 ,之後保护模式的程式再来决定将使用者的
EFLAG 切成什麽等级 ,然後再 IRETD切回 V86 ,於是应用程式根本抢不过最早进入保
护模式的家伙。(这样你有办法在V86下抢到最高等级吗....不可能嘛)
 
    等级的高低可以决定自己有多少控制权 ,例如等级最高的人才可以读写系统暂存
器 ,其馀的人想读写系统暂存器都会发生 General Protection Error 0D ,你可以把
它想像成等级不够 ,却要读取系统资源 ,会发生 INT_0D ,而原本这行指令将不会被
执行 ,而堆叠里所摆的 EIP 值也停在这行上面 ,如果 INT_0D 的处理程式不去跳过
这个指令 ,则会永远停在这个指令里(形同当机)。
 
    在 V86 下发生中断时 ,会自动 PUSH EIP.CS.EFLAG.ESP.SS......数个暂存器 ,
并自动将 SS.ESP 的值替换 ,以免发生中断时 ,会动用到 V86 的堆叠 ,可是如果发
生的是 General Protection Error(俗称异常),则会在 PUSH EIP 之前再多摆入一
个DWORD 的错误代码 ,如果您的程式在 IRETD 前不减去这个可能存在的错误代码 ,
则会发生不可预知的後果。这也是保护模式下的程式不好写的原因之一。 而SS与ESP
所替换的值 ,则是最初进入保护模式後 ,由最高等级的人决定的(摆於TSS区段)。
 
    第二集里笔者有介绍 GDT 表 ,其中有个 93 代表可写区段 ,如果设成 89 ,则表
示此区段是 TSS 表格 ,再由 TR 暂存器来指定发生中断时 ,取用那一个区段的表格.
 
举例来说 ,下面是 GDT 表格
 
gdttab  db      000h,000h,000h,000h,000h,000h,000h,000h ;00
        db      0ffh,0ffh,000h,000h,000h,09bh,000h,000h ;08
        db      0ffh,0ffh,000h,000h,000h,093h,08fh,000h ;10
        db      0ffh,0ffh,000h,000h,000h,089h,000h,000h ;18
        db      0ffh,0ffh,000h,000h,000h,089h,000h,000h ;20
        db      0ffh,0ffh,000h,000h,000h,093h,000h,000h ;28
        db      0ffh,007h,000h,000h,000h,093h,000h,000h ;30
        db      0ffh,0ffh,000h,080h,00bh,093h,000h,000h ;38
        db      0ffh,0ffh,000h,000h,000h,093h,000h,000h ;40
 
  我们可以看到 18.20 两个 Selector 正好就是 89h ,也就是说它们俩个都可以是
TSS 描述表格 ,如果 MOV AX,0018、LTR AX ,则表示发生工作切换时 ,取用 0018 的
描述表格。
 
--------------------------------------------------------------------------
┌——————┐
│TSS 表格简介│
└——————┘
    TSS 也有人称为「工作切换」 ,其表格设定如下 ,详情可看书比较详细。
 
tssltr  dd      00000000h
        dd      0000ff00h       ;ESP
        dw      0028h,0000h     ;SS.0
        dd      0,0,0,0,0
        dw      offset enter_v86,0000h      ;EIP
        dd      00000200h       ;EFlag
        dd      0,0,0,0
        dd      0000ff00h       ;ESP
        dd      0,0,0
        dw      0010h,0000h     ;ES.0
        dw      0008h,0000h     ;CS.0
        dw      0028h,0000h     ;SS.0
        dw      0010h,0000h     ;DS,0
        dw      0010h,0000h     ;FS.0
        dw      0010h,0000h     ;GS.0
        dw      0000h,0000h     ;LDT.0
        dw      0000h,0068h     ;0.IOMAP起点
        db      1000h dup (0)   ;4K IOMAP 表
        dw      0ffffh
 
 
    如果您的程式使用 JMP XXXX:YYYYYYYY 的方式跳到本区节的话 ,原本指定的
YYYYYYYY 将无用途 ,因为所有的暂存器将被替换成此表格的数值(含CS.EIP) ,并
完成等级切换的动作。
 
 
--------------------------------------------------------------------------
┌———————┐
│进入 V86  模式│
└———————┘
 
        cli
        lgdt    fword ptr cs:gdtadds
        lidt    fword ptr cs:idtadds
        mov     eax,cr0
        or      al,01h
        mov     cr0,eax
        mov     bx,0018h
        ltr     bx            ;发生工作切换时 ,SS:ESP 将参考 0018 的区段表格
        jmp     0020h:0000h   ;进入工作切换 ,会跳到此表格内指定的 CS:EIP
                               (LTR.JMP 不可指向同一表格)
 
enter_v86 :                   ;假设您已将 CS:EIP 指向此处继续执行
        xor     eax,eax
        mov     ax,code
        push    eax             ;GS
        push    eax             ;FS
        push    eax             ;DS
        push    eax             ;ES
        push    eax             ;SS
        mov     ax,0f000h
        push    eax             ;ESP
        mov     eax,00023000h   ;设定VM=1    等级=3
        push    eax             ;Eflag
        xor     eax,eax
        mov     ax,code
        push    eax             ;CS

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -