小華的部落格: Direct Hardware Access Under Windows 9x/NT/2000/XP/Vista

搜尋此網誌

星期三, 5月 09, 2007

Direct Hardware Access Under Windows 9x/NT/2000/XP/Vista

今天又多學一樣東西,就是呼叫Undocument API 去開啟I/O 存取權限,這樣子你就可以使用Ring3的應用程式直接存取硬體,例如下面的VC++範例程式中直接使用Assembly 或是IO Funcation call去存取硬體。

EX1: Read I/O Port
_asm {
pushf
mov al, ireg.h
mov dx,0x70
out dx,al
mov dx,0x71
in al, dx
mov mbid, al
popf
}

EX2: Read CMOS
_outp(0x70,ireg.h );
mbid=_inp(0x71);

使用的技巧是先進入Ring0 (也就是掛一個Driver),然後在DriverEntry 時去呼叫API去改變IO權限。
void Ke386SetIoAccessMap(int, IOPM *);
void Ke386QueryIoAccessMap(int, IOPM *);
void Ke386IoSetAccessProcess(PEPROCESS, int);

開剛始是利用修改TSS的來開啟IO存取權限方式,不過改完後DEBUG.COM會無法執行,所以才改成呼叫上面的API的方式,而直接修改TSS方式如下所示:
__asm {
cli // 遮罩中斷
sgdt gdtr // 得到 GDT 基底位址與段界限
str TSSseg // 得到 TSS 選擇子
movzx esi,TSSseg // 擴展到 ESI 中以便計算
add esi,gdtr.dwBase // 得到 TSS 在 GDT 中描述符
mov gdt,esi
}
不管是API還是修改TSS,都是在DriverEntery進去後去執行的。

因此實作部份分成三部份:
1.WDM Driver code(DriverEntery 的地方呼叫API)
2.InstallDriver code(應用程式執行時去動態載入驅動程式)
3.應用程式Application code(直接使用Assembly或是IO Function)

3 則留言:

瑞修 提到...

有關於DRIVER取得I/O權
可以詳加敘述一下嗎?

Harrison 提到...

網路上有一個Sample code...
/*********************************************************************
Author: Dale Roberts
Date: 8/30/95
Program: GIVEIO.SYS
Compile: Use DDK BUILD facility
Purpose: Give direct port I/O access to a user mode process.
*********************************************************************/

我就是用他的方式去取得I/O控制權...
我自己寫了一個Ap,然後利用SCM去載入這個Driver,接著你就可以在你的Src code內使用Assembly或是I/O Funcation call了...

匿名 提到...

giveio.c
http://www.koders.com/c/fid80CCF7BE70B2D2264F9249B23291578EF5A63D76.aspx