2015-01-09 35 views
4

我已經閱讀了這裏的答案:Trigger Kernel Interrupt Handler: How?這是一個很好的,但不是我所需要的。如何才能在Linux內核中生成「人工」中斷?

我在處理中斷方面微基準化RNG函數,所以我需要一個很好的方法來人爲地和可重複地產生中斷。例如,我可以將某些東西重定向到生成300箇中斷或類似事件的Procfs接口。

是否像在內核中運行某種函數那樣容易產生中斷?

是否有某種中斷不會實際執行「任何事情」,但仍會經歷整個中斷處理程序路徑?我意識到我可以只是鍵入鍵或類似的東西,但這不是真正可重複的和用於研究目的的腳本。

我正在使用x86架構。

+1

要模擬硬件中斷或只想系統調用夠嗎?你在內核空間運行嗎?你關心什麼中斷被執行,或者硬件中斷是否正常? – tux3

+0

嗯,它是依賴於體系結構的,但大多數都提供了軟件生成的中斷。這是實現系統調用的一種方式。 –

+0

@ tux3我不積極...... syscalls會通過整個中斷路徑,包括/drivers/char/random.c中的函數嗎?如果是這樣,那很完美。在x86中只是一個「INT」? –

回答

3

這是一個潛在的解決方案,它會產生假鍵盤中斷,從內核的PoV中無法確定這些中斷是不是真實的。

只有使用SA_SAMPLE_RANDOM安裝的中斷處理程序纔會生成熵,這樣可以消除系統調用。但鍵盤中斷確實會產生熵。

我還沒有測試下面的代碼,並且不能提供任何保證,但我相信它應該工作,如果作爲內核模塊的一部分運行。

下面的代碼片段顯示瞭如何強制將鍵注入鍵盤控制器的緩衝區。如果一個真正的PS/2鍵盤(或USB鍵盤,在BIOS傳統USB支持)未插入這將無法正常工作。This code was copied from a SMM keylogger article on Phrack

的代碼在x86彙編,你可以在一個內聯彙編塊asm("");如果把它包你寫你的內核模塊中C.

; write command byte 0xD2 to command port 0x64 
; to re-inject intercepted scan code into keyboard controller buffer 
; so that OS keyboard interrupt can read and display it later 
mov al, 0xd2 
out 0x64, al 
; wait until keyboard controller is ready to read 
_wait: 
in al, 0x64 
test al, 0x2 
jnz _wait 
; re-inject scan code for the key '1' 
mov ax, 1 
out 0x60, al 

然後產生鍵盤中斷做:

int 33 

中斷33通常是PS/2鍵盤。這將導致Linux處理鍵盤中斷,讀取我們的假掃描碼,併爲您產生一些隨機性。 你會想在一個循環中調用它,但要小心,Linux會根據兩個中斷之間的間隔產生部分隨機性,如果以固定的時間間隔強制中斷,那麼這種方法的熵就會很小。

請注意,它也應該工作,如果你只做asm("int $33")而不運行代碼的第一部分,但可能會混淆內核。

+0

謝謝!我會試試這個,並在我做的時候回報。 –

+0

我收到很多錯誤,試圖在inline asm中編寫此代碼。有沒有什麼機會可以幫助我瞭解我在寫這些時做錯了什麼?下面是一個示例行: 'mov%al,$ 0xd2 \ n',並且我得到'不受支持的指令mov' –

+0

啊,AT&T語法和Intel語法顛倒了。 mov al,0xd2轉換爲mov $ 0xD2,%al;'。你是否首先嚐試了'int $ 33'?它可能會自行工作。 – tux3

2

剛開始高分辨率定時器:

struct hrtimer timer; 

hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 
timer.function = my_little_timer; 
hrtimer_start(&timer, ktime_set(0, 500000000 /* ns */), HRTIMER_MODE_REL); 

... 

hrtimer_cancel(&timer); 

... 

enum hrtimer_restart my_little_timer(struct hrtimer *timer) 
{ 
    // either: 
    hrtimer_forward_now(timer, ktime_set(...)); 
    return HRTIMER_RESTART; 
    // or: 
    return HRTIMER_NORESTART; 
} 
+0

今天回到辦公室,我會給你一個鏡頭。謝謝! –

+0

我把這段代碼扔進去了,讓它編譯並運行,但是我沒有看到任何中斷。我錯過了什麼嗎?試圖在線閱讀文檔,但他們並沒有真正幫助。 –