欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

怎么截獲Linux操作系統(tǒng)異常處理

本篇內(nèi)容介紹了“怎么截獲Linux操作系統(tǒng)異常處理”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

創(chuàng)新互聯(lián)建站是一家專業(yè)提供確山企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、H5場(chǎng)景定制、小程序制作等業(yè)務(wù)。10年已為確山眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站設(shè)計(jì)公司優(yōu)惠進(jìn)行中。

在某些情況下,我們可能需要去截獲Linux操作系統(tǒng)的一些異常處理,比如截獲page fault異常處理。

可以修改內(nèi)核的情況下:

如果我們能夠修改內(nèi)核,那么截獲page fault異常處理就會(huì)非常簡(jiǎn)單。以linux 3.8.0內(nèi)核為例,系統(tǒng)中發(fā)生page fault之后,會(huì)進(jìn)入page fault異常處理,調(diào)用do_page_fault函數(shù)。do_page_fault的代碼如下:

dotraplinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) { exception_enter(regs); __do_page_fault(regs, error_code); exception_exit(regs); }

我們把do_page_fault函數(shù)的內(nèi)容提取出來,寫成一個(gè)新的函數(shù)default_do_page_fault。再增加一個(gè)函數(shù)指針do_page_fault_handler,初始化為default_do_page_fault。將原來的do_page_fault內(nèi)部改為調(diào)用函數(shù)指針do_page_fault_handler。修改之后的代碼如下:

void default_do_page_fault(struct pt_regs *regs, unsigned long error_code) { exception_enter(regs); __do_page_fault(regs, error_code); exception_exit(regs); } EXPORT_SYMBOL(default_do_page_fault); typedef void (*do_page_fault_handler_t)(struct pt_regs *, unsigned long); do_page_fault_handler_t do_page_fault_handler = default_do_page_fault; EXPORT_SYMBOL(do_page_fault_handler); dotraplinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code){ do_page_fault_handler(regs, error_code); }

由于do_page_fault_handler被EXPORT_SYMBOL導(dǎo)出,我們?cè)趦?nèi)核模塊中可以很方便地訪問它。只要將do_page_fault_handler的值設(shè)置為自定義的page fault異常處理函數(shù),就能完成截獲功能。如果想要恢復(fù)原來的異常處理函數(shù),只需要再次把do_page_fault_handler設(shè)置為default_do_page_fault即可。

不能修改內(nèi)核的情況下:

但是有些情況下,我們不能直接修改內(nèi)核代碼,需要在已經(jīng)編譯好的內(nèi)核上完成截獲功能。

開始的時(shí)候,我考慮在do_page_fault函數(shù)開始處插入跳轉(zhuǎn)代碼,跳轉(zhuǎn)到自定義的page fault處理函數(shù)中。但是實(shí)踐的時(shí)候發(fā)現(xiàn),內(nèi)核不允許直接修改do_page_fault的代碼。

經(jīng)過一番調(diào)查,又想到一個(gè)新的辦法,即通過更改IDT表的方式來截獲page fault。

內(nèi)核原有的IDT表肯定是不能直接寫的,所以我申請(qǐng)了一個(gè)頁,將原來的IDT表復(fù)制過來,再更改頁面異常對(duì)應(yīng)的ISR(Interrupt Service Routine)。page fault的ISR名稱為page_fault,它將寄存器壓棧,將error number壓棧,然后調(diào)用do_page_fault,待do_page_fault返回之后再恢復(fù)寄存器,退出異常處理。

在Linux內(nèi)核中,ISR是用匯編寫的。例如,x86_64 Linux的ISR源碼位于內(nèi)核源碼arch/x86/kernel/entry_64.S中,X86_32的位于arch/x86/kernel/entry_32.S中。如果去讀entry_64.S或者entry_32.S,你會(huì)發(fā)現(xiàn)這兩個(gè)文件非常復(fù)雜,利用了很多的匯編宏和宏定義,無法方便地基于它們寫一個(gè)自定義的ISR出來。

我的解決辦法是將內(nèi)核編譯出來,反匯編vmlinux.o,然后查找page_fault,找到其匯編代碼。下面的匯編代碼就是linux-3.8.0 X86_64內(nèi)核的:

ffffffff8136f6f0 <page_fault>: ffffffff8136f6f0:       66 66 90                data32 xchg %ax,%ax ffffffff8136f6f3:       ff 15 07 0a 2b 00       callq  *0x2b0a07(%rip)        # ffffffff81620100 <pv_irq_ops+0x30> ffffffff8136f6f9:       48 83 ec 78             sub    $0x78,%rsp ffffffff8136f6fd:       e8 ae 01 00 00          callq  ffffffff8136f8b0 <error_entry> ffffffff8136f702:       48 89 e7                mov    %rsp,%rdi ffffffff8136f705:       48 8b 74 24 78          mov    0x78(%rsp),%rsi ffffffff8136f70a:       48 c7 44 24 78 ff ff    movq   $0xffffffffffffffff,0x78(%rsp) ffffffff8136f711:       ff ff ffffffff8136f713:       e8 1f 2e 00 00          callq  ffffffff81372537 <do_page_fault> 11 ffffffff8136f718:       e9 33 02 00 00          jmpq   ffffffff8136f950 <error_exit> 12 ffffffff8136f71d:       0f 1f 00                nopl   (%rax)

我仿照著寫了一個(gè),名為my_page_fault:

asmlinkage void my_page_fault(void); asm("   .text"); asm("   .type my_page_fault,@function"); asm("my_page_fault:"); //the first 3 bytes of the routine basically do nothing, //but I decide to keep them because kernel may rely on them for some special purpose asm("   .byte 0x66"); asm("   xchg %ax, %ax"); asm("   callq *addr_adjust_exception_frame"); asm("   sub $0x78, %rsp"); asm("   callq *addr_error_entry"); asm("   mov %rsp, %rdi"); asm("   mov 0x78(%rsp), %rsi"); asm("   movq $0xffffffffffffffff, 0x78(%rsp)"); asm("   callq my_do_page_fault"); asm("   jmpq *addr_error_exit"); asm("   nopl (%rax)");

其中第9行addr_adjust_exception_frame是(pv_irq_ops+0x30)地址處存儲(chǔ)的值;第11行addr_error_entry是error_entry的地址;第16行addr_error_exit是error_exit的地址。這幾個(gè)值需要從System.map文件中查詢,然后用內(nèi)核模塊參數(shù)的形式傳入。而my_do_page_fault則是我們自己定義的page fault處理函數(shù)。

如果需要截獲X86_32的page fault,可以參考這個(gè)C文件。不過需要注意的是,新版內(nèi)核有所變動(dòng),這里的代碼需要根據(jù)自己的情況做一些調(diào)整。

有了自定義的ISR之后,就可以將這個(gè)ISR填到IDT中,加載新的IDT表之后,自定義的page fault處理函數(shù)就開始發(fā)揮作用了。這個(gè)過程主要有以下幾個(gè)步驟:

  • 用store_idt(&default_idtr)保存現(xiàn)有的IDT寄存器值

  • 從default_idtr中讀出IDT表首地址和表的大小

  • 申請(qǐng)一個(gè)頁面

  • 將原來的idt表拷貝到新申請(qǐng)的頁面中

  • 利用pack_gate將my_page_fault(注意不是my_do_page_fault)填入到對(duì)應(yīng)的IDT項(xiàng)中

  • 在idtr中填寫新的IDT表地址和大小,用load_idt(&idtr)加載新的IDT表到當(dāng)前CPU

  • 利用smp_call_function,將新的IDT表加載到其他CPU上。

如果想恢復(fù)原來的IDT表,則用load(&default_idtr)和smp_call_function加載原來的IDT表,釋放申請(qǐng)的頁面。

“怎么截獲Linux操作系統(tǒng)異常處理”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

當(dāng)前題目:怎么截獲Linux操作系統(tǒng)異常處理
分享URL:http://aaarwkj.com/article14/iijhde.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營(yíng)銷、虛擬主機(jī)網(wǎng)站設(shè)計(jì)、搜索引擎優(yōu)化自適應(yīng)網(wǎng)站、微信公眾號(hào)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站
在线观看免费在线观看免费| 国产一级黄色性生活片| 亚洲日本欧美在线一区| 精品特色国产自在自线拍| 日韩欧美二区三区在线| 日韩二区三区在线视频| 日本大型午夜福利视频| 日本女优中文字幕久久| 日韩精品亚洲一区二区三区免费| 日韩精品电影一区在线观看| 欧美 日本国产一区| 国产精品偷拍自拍视频| 亚洲精品色婷婷一区二区| 欧美日韩亚洲中文字幕| 日韩视频专区一区二区| 人人妻夜夜天天俺去添噜| 久草福利资源在线观看视频| 欧美激情网页一区三区| 日韩中字在线一区二区| 国产三级三级三级三级三级| 五月爱婷婷六月爱丁香色| 欧美精品黑人三级精品| 久久中文字幕人妻熟av| 国产精品日韩欧美久久久| 一区二区三区在线观看美女视频| 日韩av亚洲一区二区三区| 凹凸国产精品熟女视频| 国产婷婷成人久久av免费高清| 欧美国产激情一区二区| 久久这里只有精品视频| av国产剧情在线观看| 亚洲 综合 久久久| 亚洲综合欧美日韩一区| 国产午夜福利av在线麻豆| 国产精品自产拍在线网站| 欧美国产日韩一区二区三区视频| 亚洲欧美一级二级三级| 蜜臀一区二区三区精品免费| 亚洲国产香蕉视频在线播放| 美女在线视频一区二区三区| 久久免费看少妇高潮免费|