Windows 核心Hook之IOAPIC程式設計

2021-09-30 05:26:08 字數 1811 閱讀 9447

hook

系列中,包括應用程式

hook

程式設計、idt

和ioapic

程式設計,其中

iopic

顧名思義

i/o advanced programmable interrupt controller

中斷控制器。在

windows

中有固定的兩個位址進行操作,第一、

i/o暫存器選擇暫存器,其位址是

0xfec00000

;另乙個是

i/o視窗暫存器,位址是

0xfec00010

。這兩個位址不像通用暫存器一樣能直接訪問,必須對映大一片虛擬記憶體中操作。

idt是中斷描述符列表,

ioapic

的目的就是告訴指定的

cpu的

irq號,用於

idt查詢中斷服務位址。

因此如果想修改中斷的處理過程,首先需要修改

ioapic

的中斷號,在通過

idt修改中斷服務函式,這樣就可以達到過濾和獲取資料的目的,如下**;

// 選擇暫存器。選擇暫存器雖然是

32位的暫存器,但是只使用

// 低

8位,其他的位都被保留。

p2c_u8 *io_reg_sel;

// 視窗暫存器,用來讀寫被選擇暫存器選擇的值,是

32位的。

p2c_u32 *io_win;

p2c_u32 ch,ch1;

// 定義乙個實體地址,這個位址為

0xfec00000

。正是ioapic

// 暫存器組在

windows

上的開始位址

physical_addressphys ;

pvoid paddr;

rtlzeromemory(&phys,sizeof(physical_address));

phys.u.lowpart = 0xfec00000;

// 實體地址是不能直接讀寫的。

mmmapiospace

把物理位址對映

// 為系統空間的虛擬位址。

0x14

是這片空間的長度。

paddr = mmmapiospace(phys, 0x14, mmnoncached);

// 如果對映失敗了就返回0.

if (!mmisaddressvalid(paddr))

return 0;

// 選擇暫存器的偏移為0

io_reg_sel = (p2c_u8 *)paddr;

// 視窗暫存器的偏移為

0x10.

io_win = (p2c_u32 *)((p2c_u8 *)(paddr) + 0x10);

// 選擇第0x12

,剛好是

irq1

的項*io_reg_sel = 0x12;

ch = *io_win;

// 如果new_ch不為0

,我們就設定新值。並返回舊值。

if(new_ch != 0)

// 視窗暫存器裡讀出的值是

32位的,但是我們只需要

// 乙個位元組就可以了。這個位元組就是中斷向量的值。

// 一會我們要修改這個值。

ch &= 0xff;

mmunmapiospace(paddr, 0x14);

kdprint(("p2cseachorsetirq1: the old vec of irq1 is %2x./r/n",(p2c_u8)ch));

return (p2c_u8)ch;

linux核心hook技術之跳轉指令偏移值

在另一篇博文中提到了指令覆蓋和指令注入的hook方式,使用覆蓋和注入方式完成核心函式hook,需要有很多的注意事項,而且容易被檢測工具檢測。這篇博文則聊一下如何通過替換跳轉指令偏移值來完成核心函式的hook,這種hook技術也可以稱為inline hook。事先做個準備工作,手頭正好有centos ...

linux核心hook技術之函式位址替換

函式位址替換是一種更為簡單 常見的hook方式,比如對security ops sys call table等結構中的函式進行替換,來完成自己的安全許可權控制。其中security ops是lsm框架中所使用的,sys call table是系統呼叫表結構。當然了,這些結構目前在核心中都已經是唯讀資...

linux 核心 hook函式介紹

在編寫linux核心中的網路模組時,用到了鉤子函式也就是hook函式。現在來看看linux是如何實現hook函式的。先介紹乙個結構體 struct nf hook ops,這個結構體是實現鉤子函式必須要用到的結構體,所在檔案 linux netfilter.h 定義為 typedef unsigne...