網頁

星期三, 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 則留言:

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

    回覆刪除
  2. 網路上有一個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了...

    回覆刪除
  3. giveio.c
    http://www.koders.com/c/fid80CCF7BE70B2D2264F9249B23291578EF5A63D76.aspx

    回覆刪除