前面介绍了 Shell 下的 IoApic 的读写,这次研究一下 Windows 下面的。在 Windows 下面,我们可以直接使用 RW_Everything 来进行读取,设定如下:

读取结果如下:

我们特别关注 0x12 偏移处的值为 0x980 (这台机器和之前的 WinDBG 调试的不是同一个机器,IoApic 不同)。我猜测这里是PS/2 keyboard 的 IRQ0。参照资料修改 Bit16 (Interrupt Mask),设置为1会 Disable 这个中断。于是 x012 会被写为 0x0001 0980,这时候我发现键盘无法工作了。

测试的这个机器是笔记本,键盘是挂在EC 下面的,EC汇报给系统的是PS/2键盘。

于是,通过这样的方式我阻止了 IRQ1 的产生,因此按键会无效。接下来,再将这个恢复为之前的 0x980,但是笔记本键盘是不工作的。我猜测应该有可能是按键堵住了 Buffer,所以再使用 RW 读取 0x60 IO port(就是打开 0x60 IO Port 页面看一下),键盘即恢复了工作。有兴趣的朋友可以自行尝试,记得需要连接一个 USB 键盘。
结论:我们现在谈论的IRQ 只的是针对 IOAPIC的Number, 比如,IRQ1 位于 I/O Redirection Table Register 1 的位置,同时这个 Register 会给出对应的 Vector。当中断发生时,CPU 会根据 Vector 找到 IDT 中给出来的ISR (Interrupt Service Routine)。
额外的实验,我们可以编写一个 Python Script 来配合 Dbc实现 IoApic 的读取,代码如下:
def Test():
def get_APIC_DAT(index):
_base.mem(0xfec00000 , 1, index)
return _base.mem(0xfec00010, 4)
import common.baseaccess as _baseaccess
_base = _baseaccess.getglobalbase()
print("Script from www.lab-z.com")
for i in range(0,0x77):
print("%02x:%08X %08X" %(i,get_APIC_DAT(0x10+i*2),get_APIC_DAT(0x10+i*2+1)))
上述代码命名为 myscript.py, 运行结果如下:

20220114 RW_Everything 访问 0x60 port 的方法如下:

想请问一下PS2键盘的Memory Address如何获取的?
你的问题是什么?我不明白。 ps/2 键盘鼠标走的是 60/64 端口取得数据的。
在第一步的时候通过RW获取PS2键盘的IRQ,这个是怎么知道 0ffsert 0x12的?
具体需要结合 IoApic 的那个结构体来看, 我猜测 Irq0 对应的是 APIC Redirection Table0 , 然后 Irq1 对应的是 Table 1, 所以我要去看 0x12 处的值。
RW 读取 0x60 IO port(就是打开 0x60 IO Port 页面看一下),这个要怎么操作啊?不太会rw everything
我更新了 RW 访问 60 Port 的方法,在文章最后你可以参考一下。