Windows 内核 I/O 端口操作

    这只是一篇读书笔记。

1. C语言提供的端口函数

    C语言提供了操作I/O端口的函数。这些函数会电泳IN 和OUT 汇编指令。 当然这些函数只能在内核模式下执行。

我们可以自定了如下的函数:

1 #pragma INITCODE
2 ULONG In_32(PULONG port)
3 {
4 ULONG value;
5 _asm
6 {
7 mov edx, port //将端口号传入EDX中
8   in eax, dx //执行32位IO输入
9   mov value,eax
10 //插入几个空指令
11 nop
12 nop
13 }
14 return(value);
15 }
16 #pragma INITCODE
17 void Out_32(PULONG port, ULONG value)
18 {
19 _asm
20 {
21 mov edx, port
22 mov eax, value
23 out dx, eax
24 nop
25 nop
26 }
27 }

2. DDK 的端口操作函数

    DDK 同样提供了类似的端口操作函数。

函数名 描述
READ_PORT_UCHAR 8位输入
READ_PORT_USHORT 16位输入
READ_PORT_ULONG 32位输入
READ_PORT_BUFFER_UCHAR 8位连续输入
READ_PORT_BUFFER_USHORT 16位连续输入
READ_PORT_BUFFER_ULONG 32位连续输入
WRITE_PORT_UCHAR 8位输出
WRITE_PORT_USHORT 16位输出
WRITE_PORT_ULONG 32位输出
WRITE_PORT_BUFFER_UCHAR 8位连续输出
WRITE_PORT_BUFFER_USHORT 16位连续输出
WRITE_PORT_BUFFER_ULONG 32位连续输出

需要注意的是编译的时候需要加入HAL.lib库。

3. WinIo

    WinIo 通过内核模式下设备驱动和其他一些底层的编程技巧绕过了windows安全保护机制,允许32位windows程序直接对I/O端口进行操作。在windows NT/2000/XP下,WinIo库只允许具有管理员权限的应用程序调用。

winIo的使用就非常简单了,如:

1 int main()
2 {
3 //打开WinIO驱动
4 bool bRet = InitializeWinIo();
5 if (bRet)
6 {
7 printf("Load Dirver successfully!\n");
8 //对0x378端口进行输出操作,8位操作
9 SetPortVal(0x378,0,1);
10 //关闭WinIO驱动
11 ShutdownWinIo();
12 }
13 return 0;
14 }

原文地址:https://www.cnblogs.com/sld666666/p/1936717.html