How to Access I/O Ports in WindowsNT/2K/X

| | 评论(0)

有点忙。。。还是贴篇旧文以免空白太多吧。

How to Access I/O Ports in WindowsNT/2K/XP
Mach, April 14, 2003 

People can not use _inp() and _outp() in Windows NT Ring3 application. An exception will return from OS while these two functions were called in Ring3.

To access I/O ports on Windows NT and x86 platform (Alpha platform does not have I/O ports, forget that), some undocumented APIs will be utilized. They are:

// ke386... are functions in ntoskrnl.lib (ntoskrnl.exe)
// They are undocumented, thus list here

void Ke386SetIoAccessMap(int, IOPM *); // int: 1 Copy buffer, 0 fill with 0xff
void Ke386QueryIoAccessMap(int, IOPM *);
void Ke386IoSetAccessProcess(PEPROCESS, int); // int: 1 enable I/O, 0 disable I/O

You can find these functions in ntoskrnl.exe with Dependency Walker (a utility in VC 6.0). To find the definition of these APIs, come to google or "Undocumented NT Secrets". I can give a short description here.

// IOPM is a 8192 bytes array, each bits represent one port,
// thus 8192*8 = 65536 = [All the I/O ports]
// If the bit is zero, the correspond I/O access is enabled

#define IOPM_SIZE 0x2000
typedef char IOPM[IOPM_SIZE];
IOPM *pIOPM = NULL;

In short, NT use a mask array of 8192 bytes to describe the 65535 I/O ports on x86 platform. Each bits of the array represent an I/O port. If the bit is 0, the correspond I/O access is enabled, otherwise the access is disabled. To enable I/O ports, we must set the privilege in Ring0, that is, of course, the usual way is writing a driver. Call the fowling sequence in driver:

pIOPM = MmAllocateNonCachedMemory(sizeof(IOPM));

if (pIOPM)
{
     RtlZeroMemory(pIOPM, sizeof(IOPM));

     Ke386IoSetAccessProcess(PsGetCurrentProcess(), 1); // 1 is enable 
     Ke386SetIoAccessMap(1, pIOPM);
}

The Ke386IoSetAccessProcess enabled I/O access of the current process, while Ke386SetIoAccessMap set the I/O access map to pIOPM.

To stop access to I/O ports:

if (pIOPM)
{
     Ke386IoSetAccessProcess(PsGetCurrentProcess(), 0);
     Ke386SetIoAccessMap(1, pIOPM);

     MmFreeNonCachedMemory(pIOPM, sizeof(IOPM));
     pIOPM = NULL;
}

Yariv Kaplan has published WinIO source code on his website: www.internals.com

posted 2004.07.21 Wednesday

分类

发表评论

关于此日记

此日记由mach发表于July 21, 2004 12:36 PM

此Blog上的上一篇日记茭白的秘密

此Blog上的下一篇日记录诗三首

主索引归档页可以看到最新的日记和所有日记。

Powered by Movable Type 4.23-en