电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

《Undocumented Windows 2000 Secrets》翻譯 --- 第四章(5)

瀏覽:97日期:2023-08-25 16:01:28

第四章 探索 Windows 2000 的內存管理機制

翻譯: Kendiv( fcczj@263.net )

更新: Sunday, February 17, 2005

聲明:轉載請注明出處,并保證文章的完整性,本人保留譯文的所有權利。

IOCTL 函數 SPY_IO_INTERRUPT

SPY_IO_INTERRUP 類似于 SPY_IO_SEGEMT ,不過該函數僅影響存儲在系統中斷描述符表( IDT )的中斷描述符,不會涉及 LDT 或 GDT 描述符。 IDT 最多可容納 256 個描述符,這些描述符可用來描述任務門、中斷門或陷阱門(參見 Intel 1999c, pp. 5-11ff )。順便說一下,中斷和陷阱在本質上十分相似,二者只存在微小的差異:在進入一個中斷處理例程后,總是會屏蔽其他中斷;而進入陷阱處理例程卻不會修改中斷標志。 SPY_IO_INTERRUPT 的調用者提供一個 0 到 255 之間的中斷號,該中斷號將位于輸入緩沖區中,而一個 SPY_INTERRUPT 結構將作為輸出數據被存放到輸出緩沖區中,如果成功返回,該結構中將包含對應的中斷處理例程的屬性。由 Dispatcher 調用的幫助函數 SpyOutputInterrupt() 只是一個簡單的外包函數,它實際上調用 SpyInterrupt() 函數并且將需要返回的數據復制到輸出緩沖區中。 列表 4-18 給出了這兩個函數,以及它們操作的 SPY_INTERRUPT 結構。稍后一些, SpyInterrupt() 函數將填充如下項目:

l Selector 用來指定一個任務狀態段( Task-State Segment, TSS )或代碼段( Code Segment )的選擇器。代碼段選擇器用來確定中斷或陷阱處理例程所在的段。

l Gate 用來表示一個 64 位的任務門、中斷門或陷阱門描述符,由 Selector 確定其地址。

l Segment 包含段的屬性,該段的地址由前面的 Gate 給出。

l pOffset 指定中斷或陷阱處理例程的入口地址相對基地址的偏移量。這里的基地址是指中斷或陷阱處理例程所在代碼段的起始地址。因為任務門不包含偏移量,所以,如果輸入的選擇器指向一個 TSS ,則忽略該成員。

l fOk 一個標志變量,用來指示 SPY_INTERRUPT 結構中的數據是否有效。

通常情況下, TSS 被用來保證一個錯誤情況可以被一個有效的任務處理。這是一個特殊的系統段類型( system segment type ),它可以保存 104 個字節的進程狀態信息,該信息在任務切換時,用來進行任務的恢復,如 4-3 所示。當與任務相關的中斷發生時, CPU 總是強制切換該任務,并將所有的 CPU 寄存器保存到 TSS 中。 Windows 2000 在中斷位置 0x02 (非屏蔽中斷 [NMI] , 0x08[Double Fault] 和 0x12[ 堆棧段故障 ] )處保存任務門。剩余的位置指向中斷處理例程。不使用的中斷由一個啞元例程 ---KiUnexpectedInterruptNNN() 處理,這里的 NNN 為一個十進制數。這些啞元例程最后都匯集到內部函數 KIEndUnexpectedRange() ,在這里,這些例程將依次進入 KiUnexpectedInterruptTail() 。

typedef struct _SPY_INTERRUPT

{

X86_SELECTOR Selector;

X86_GATE Gate;

SPY_SEGMENT Segment;

PVOID pOffset;

BOOL fOk;

}

SPY_INTERRUPT, *PSPY_INTERRUPT, **PPSPY_INTERRUPT;

#define SPY_INTERRUPT_ sizeof (SPY_INTERRUPT)

// -----------------------------------------------------------------

NTSTATUS SpyOutputInterrupt (DWord dInterrupt,

PVOID pOutput,

DWORD dOutput,

PDWORD pdInfo)

{

SPY_INTERRUPT si;

SpyInterrupt (dInterrupt, &si);

return SpyOutputBinary (&si, SPY_INTERRUPT_,

pOutput, dOutput, pdInfo);

}

// -----------------------------------------------------------------

BOOL SpyInterrupt (DWORD dInterrupt,

PSPY_INTERRUPT pInterrupt)

{

BOOL fOk = FALSE;

if (pInterrupt != NULL)

{

if (dInterrupt <= X86_SELECTOR_LIMIT)

{

fOk = TRUE;

if (!SpySelector (X86_SEGMENT_OTHER,

dInterrupt << X86_SELECTOR_SHIFT,

&pInterrupt->Selector))

{

fOk = FALSE;

}

if (!SpyIdtGate (&pInterrupt->Selector,

&pInterrupt->Gate))

{

fOk = FALSE;

}

if (!SpySegment (X86_SEGMENT_OTHER,

pInterrupt->Gate.Selector,

&pInterrupt->Segment))

{

fOk = FALSE;

}

pInterrupt->pOffset = SpyGateOffset (&pInterrupt->Gate);

}

else

{

RtlZeroMemory (pInterrupt, SPY_INTERRUPT_);

}

pInterrupt->fOk = fOk;

}

return fOk;

}

// -----------------------------------------------------------------

PVOID SpyGateOffset (PX86_GATE pGate)

{

return (PVOID) (pGate->Offset1 | (pGate->Offset2 << 16));

}

列表 4-18. 查詢中斷屬性

表 4-3. 任務狀態段( TSS )中的 CPU 狀態域

偏移量

位數

ID

0x00

16

前一個任務的鏈接

0x04

32

ESP0

Ring0 級的堆棧指針寄存器

0x08

16

SS0

Ring0 級的堆棧段寄存器

0x0C

32

ESP1

Ring1 級的堆棧指針寄存器

0x10

16

SS1

Ring1 級的堆棧段寄存器

0x14

32

ESP2

Ring2 級的堆棧指針寄存器

0x18

16

SS2

Ring2 級的堆棧段寄存器

0x1C

32

CR3

頁目錄基址寄存器( PDBR )

0x20

32

EIP

指令指針寄存器

0x24

32

EFLAGS

處理器標志寄存器

0x28

32

EAX

通用寄存器

0x2C

32

ECX

通用寄存器

0x30

32

EDX

通用寄存器

0x34

32

EBX

通用寄存器

0x38

32

ESP

堆棧指針寄存器

0x3C

32

EBP

基地址指針寄存器

0x40

32

ESI

源索引寄存器

0x44

32

EDI

目標索引寄存器

0x48

16

ES

擴展段寄存器

0x4C

16

CS

代碼段寄存器

0x50

16

SS

堆棧段寄存器

0x54

16

DS

數據段寄存器

0x58

16

FS

附加的數據段寄存器 #1

0x5C

16

GS

附加的數據段寄存器 #2

0x60

16

LDT

本地描述符標的段選擇器

0x64

1

1

調試陷阱標志

0x66

16

I/O Map 的基地址

0x68

-

CPU 狀態信息結束

SpyInterrupt() 調用的 SpySegment() 、 SpySelector() 函數已經在 列表 4-5 列表 4-16 中給出。 SpyGateOffset() 位于 列表 4-18 的末尾,它的工作和 SpyDescriptorBase() 、 SpyDescriptorLimit() 類似,從 X86_GATE 結構中取出 Offset1 和 Offset2 位域,并適當的組織它們以構成一個 32 位地址。 SpyIdtGaet() 定義于 列表 4-19 。它與 SpyDescriptor() 十分類似。匯編指令 SIDT 存儲一個 48 位的值,該值就是 CPU 的 IDT 寄存器的內容,它由一個 16 位的表大小限制值和 IDT 的 32 位線性基地址構成。 列表 4-19 中的剩余代碼將選擇器的描述符索引和 IDT 的大小限制值進行比較,如果 OK ,則對應的中斷描述符將被復制到調用者提供的 X86_GATE 結構中。否則,門結構的所有成員都將被設置為 0 。

BOOL SpyIdtGate (PX86_SELECTOR pSelector,

PX86_GATE pGate)

{

X86_TABLE idt;

PX86_GATE pGates = NULL;

BOOL fOk = FALSE;

if (pGate != NULL)

{

if (pSelector != NULL)

{

__asm

{

sidt idt.wLimit

}

if ((pSelector->wValue & X86_SELECTOR_INDEX)

<= idt.wLimit)

{

pGates = idt.pGates;

}

}

if (pGates != NULL)

{

RtlCopyMemory (pGate,

pGates + pSelector->Index,

X86_GATE_);

fOk = TRUE;

}

else

{

RtlZeroMemory (pGate, X86_GATE_);

}

}

return fOk;

}

列表 4-19. 獲取 IDT 門的值

IOCTL 函數 SPY_IO_PHYSICAL

SPY_IO_PHYSICAL 函數很簡單,它完全依賴于 ntoskrnl.exe 導出的 MmGetPhysicalAddress() 函數。該 IOCTL 函數通過簡單的調用 SpyInputPointer() (參見 列表 4-10 )來獲取需要轉換的線性地址,然后讓 MmGetPhysicalAddress() 查找對應的物理地址,最后將結果作為 PHYSICAL_ADDRESS 結構返回給調用者。注意, PHYSICAL_ADDRESS 是一個 64 位的 LARGE_INTEGER 。在大多數 i386 系統上,其高 32 位總是為 0 。不過,若系統啟用了物理地址擴展( Physical Address Extension, PAE ),并且安裝的內存大于 4GB ,這些位可能就是非 0 值了。

MmGetPhysicalAddress() 使用起始于線性地址 0xC0000000 的 PTE 數組,來進行物理地址的查找。其基本的工作機制如下:

l 如果線性地址位于: 0x80000000----0x9FFFFFFF ,則其高 3 位將被設為零,最后產生的物理地址位于: 0x00000000-----0x1FFFFFFF 。

l 否則,線性地址的高 20 位將作為 PTE 數組(起始于 0xC0000000 )的索引。

l 如果目標 PTE 的 P 位已被設置,這表示其對應得數據頁存在于物理內存中。除了 20 位的 PFN 外,所有的 PTE 位都可以被剝離出來,線性地址最低的 12 位將作為在數據頁中的偏移量被加到最后的 32 位物理地址上去。

l 如果數據頁沒有存在于物理內存中, MmGetPhysicalAddress() 返回 0 。

MmGetPhysicalAddress() 假設內核內存范圍: 0x80000000----0x9FFFFFF 之外的所有線性地址都使用 4KB 的頁。而其他函數,如 MmIsAddressValid() ,會首先加載線性地址的 PDE ,并且檢查該 PDE 的 PS 位,以檢查頁大小是 4KB 還是 4MB 。這是一個非常通用的方法,可以處理任意的內存配置。不過上述兩個函數都會返回正確的結果,這是因為 Windows 2000 僅針對內存范圍: 0x80000000-----0x9FFFFFFF ,使用 4MB 頁。不過某些內核 API 函數,顯然設計的比其它的靈活許多。

IOCTL 函數 SPY_IO_CPU_INFO

個別的 CPU 指令僅對運行于 Ring 0 級的代碼有效, Ring 0 是五個特權級( Intel 系列的 CPU 只支持兩個特權級: Ring0 和 Ring3 )中級別最高的一個。用 Windows 術語來說, Ring 0 意味著內核模式( Kernel-mode )。這些被禁止的指令有:讀取控制寄存器 CR0 、 CR2 和 CR3 的內容。因為這些寄存器中保存著非常有趣的信息,應用程序可能想要找到一個辦法來訪問它們,解決方案就是 SPY_IO_CPU_INFO 函數。如 列表 4-20 所示, IOCTL 處理例程調用的 SpyOutputCpuInfo() 函數使用了一些嵌入式匯編來讀取控制寄存器,以及其他一些有價值的信息,比如 IDT 的內容, GDT 和 LDT 寄存器以及存儲在寄存器 CS 、 DS 、 ES 、 FS 、 GS 、 SS 和 TR 中的段選擇器。任務寄存器( Task Register, TR )還包含一個涉及當前任務的 TSS 的選擇器。

typedef struct _SPY_CPU_INFO

{

X86_REGISTER cr0;

X86_REGISTER cr2;

X86_REGISTER cr3;

SPY_SEGMENT cs;

SPY_SEGMENT ds;

SPY_SEGMENT es;

SPY_SEGMENT fs;

SPY_SEGMENT gs;

SPY_SEGMENT ss;

SPY_SEGMENT tss;

X86_TABLE idt;

X86_TABLE gdt;

X86_SELECTOR ldt;

}

SPY_CPU_INFO, *PSPY_CPU_INFO, **PPSPY_CPU_INFO;

#define SPY_CPU_INFO_ sizeof (SPY_CPU_INFO)

// -----------------------------------------------------------------

NTSTATUS SpyOutputCpuInfo (PVOID pOutput,

DWORD dOutput,

PDWORD pdInfo)

{

SPY_CPU_INFO sci;

PSPY_CPU_INFO psci = &sci;

__asm

{

push eax

push ebx

mov ebx, psci

mov eax, cr0

mov [ebx.cr0], eax

mov eax, cr2

mov [ebx.cr2], eax

mov eax, cr3

mov [ebx.cr3], eax

sidt [ebx.idt.wLimit]

mov [ebx.idt.wReserved], 0

sgdt [ebx.gdt.wLimit]

mov [ebx.gdt.wReserved], 0

sldt [ebx.ldt.wValue]

mov [ebx.ldt.wReserved], 0

pop ebx

pop eax

}

SpySegment (X86_SEGMENT_CS, 0, &sci.cs);

SpySegment (X86_SEGMENT_DS, 0, &sci.ds);

SpySegment (X86_SEGMENT_ES, 0, &sci.es);

SpySegment (X86_SEGMENT_FS, 0, &sci.fs);

SpySegment (X86_SEGMENT_GS, 0, &sci.gs);

SpySegment (X86_SEGMENT_SS, 0, &sci.ss);

SpySegment (X86_SEGMENT_TSS, 0, &sci.tss);

return SpyOutputBinary (&sci, SPY_CPU_INFO_,

pOutput, dOutput, pdInfo);

}

列表 4-20. 查詢 CPU 狀態信息

可使用幫助函數 SpySegement() 獲取段選擇器,在前面,我們已討論過該函數。參見 列表 4-15

標簽: Windows系統
主站蜘蛛池模板: 冷却塔减速机器_冷却塔皮带箱维修厂家_凉水塔风机电机更换-广东康明冷却塔厂家 | sfp光模块,高速万兆光模块工厂-性价比更高的光纤模块制造商-武汉恒泰通 | 通用磨耗试验机-QUV耐候试验机|久宏实业百科 | 沈飞防静电地板__机房地板-深圳市沈飞防静电设备有限公司 | 超声波成孔成槽质量检测仪-压浆机-桥梁预应力智能张拉设备-上海硕冠检测设备有限公司 | 贵州成人高考网_贵州成考网| 安徽净化工程设计_无尘净化车间工程_合肥净化实验室_安徽创世环境科技有限公司 | 压接机|高精度压接机|手动压接机|昆明可耐特科技有限公司[官网] 胶泥瓷砖胶,轻质粉刷石膏,嵌缝石膏厂家,腻子粉批发,永康家德兴,永康市家德兴建材厂 | 茅茅虫AI论文写作助手-免费AIGC论文查重_写毕业论文降重 | 上海防爆真空干燥箱-上海防爆冷库-上海防爆冷柜?-上海浦下防爆设备厂家? | 东莞爱加真空科技有限公司-进口真空镀膜机|真空镀膜设备|Polycold维修厂家 | 生鲜配送系统-蔬菜食材配送管理系统-连锁餐饮订货配送软件-挪挪生鲜供应链管理软件 | 自动化展_机器人展_机床展_工业互联网展_广东佛山工博会 | 包塑软管|金属软管|包塑金属软管-闵彬管业 | 沉降天平_沉降粒度仪_液体比重仪-上海方瑞仪器有限公司 | 哈希余氯测定仪,分光光度计,ph在线监测仪,浊度测定仪,试剂-上海京灿精密机械有限公司 | 上海律师事务所_上海刑事律师免费咨询平台-煊宏律师事务所 | 硬度计_影像测量仪_维氏硬度计_佛山市精测计量仪器设备有限公司厂家 | 强效碱性清洗剂-实验室中性清洗剂-食品级高纯氮气发生器-上海润榕科学器材有限公司 | 万博士范文网-您身边的范文参考网站Vanbs.com| 防爆暖风机_防爆电暖器_防爆电暖风机_防爆电热油汀_南阳市中通智能科技集团有限公司 | 合肥展厅设计-安徽展台设计-合肥展览公司-安徽奥美展览工程有限公司 | 杰福伦_磁致伸缩位移传感器_线性位移传感器-意大利GEFRAN杰福伦-河南赉威液压科技有限公司 | 酸度计_PH计_特斯拉计-西安云仪 纯水电导率测定仪-万用气体检测仪-低钠测定仪-米沃奇科技(北京)有限公司www.milwaukeeinst.cn | 防爆暖风机_防爆电暖器_防爆电暖风机_防爆电热油汀_南阳市中通智能科技集团有限公司 | 铜镍-康铜-锰铜-电阻合金-NC003 - 杭州兴宇合金有限公司 | 江西自考网-江西自学考试网| 生物风-销售载体,基因,质粒,ATCC细胞,ATCC菌株等,欢迎购买-百风生物 | 宜兴紫砂壶知识分享 - 宜兴壶人 医用空气消毒机-医用管路消毒机-工作服消毒柜-成都三康王 | 二氧化碳/活性炭投加系统,次氯酸钠发生器,紫外线消毒设备|广州新奥 | 知企服务-企业综合服务(ZiKeys.com)-品优低价、种类齐全、过程管理透明、速度快捷高效、放心服务,知企专家! | 液压扳手-高品质液压扳手供应商 - 液压扳手, 液压扳手供应商, 德国进口液压拉马 | 同学聚会纪念册制作_毕业相册制作-成都顺时针宣传画册设计公司 | 青岛代理记账_青岛李沧代理记账公司_青岛崂山代理记账一个月多少钱_青岛德辉财税事务所官网 | 中矗模型-深圳中矗模型设计有限公司| 扫地车厂家-山西洗地机-太原电动扫地车「大同朔州吕梁晋中忻州长治晋城洗地机」山西锦力环保科技有限公司 | 暖气片十大品牌厂家_铜铝复合暖气片厂家_暖气片什么牌子好_欣鑫达散热器 | 汽车润滑油厂家-机油/润滑油代理-高性能机油-领驰慧润滑科技(河北)有限公司 | 消泡剂_水处理消泡剂_切削液消泡剂_涂料消泡剂_有机硅消泡剂_广州中万新材料生产厂家 | 小威小说网 - 新小威小说网 - 小威小说网小说搜索引擎 | 气象监测系统_气象传感器_微型气象仪_气象环境监测仪-山东风途物联网 |