IDT系列:(二)中断处理过程,使用bochs调试IDT中的中断服务程序
一、中斷處理的過(guò)程
?
根據(jù)Intel 64 and IA-32 Architectures Software Developer’s Manual 的介紹,在中斷或異常產(chǎn)生是,CPU會(huì)將當(dāng)前執(zhí)行的指令(或下一條指令)在內(nèi)存中的地址,也就是EIP的值,放入棧中,同時(shí)還會(huì)放入CS段寄存器和eflags標(biāo)志寄存器的值等。
根據(jù)當(dāng)前的優(yōu)先級(jí)不同(ring0或ring3,也就是執(zhí)行與用戶態(tài)還是內(nèi)核態(tài))會(huì)有較大的不同。如果異常或中斷發(fā)生時(shí),系統(tǒng)正執(zhí)行在內(nèi)核態(tài),那么CPU不會(huì)切換棧,直接將EFLAGS、CS、EIP和Error Code壓入棧中,如果正執(zhí)行在非內(nèi)核態(tài),那么先切換到內(nèi)核,切換到內(nèi)核棧,然后依次壓入SS、ESP(用戶態(tài)線程的)、EFLAGS、CS、EIP和Error Code。(上述過(guò)程CPU自行完成,操作系統(tǒng)只需要把ISR放到正確的位置等待調(diào)用。)然后通過(guò)IDT找到對(duì)應(yīng)的ISR 開(kāi)始執(zhí)行。
ISR完成處理后通過(guò)IRET(IRETD)指令返回到被中斷的程序中繼續(xù)執(zhí)行即可。
?
?
二、安裝配置Bochs和XP Guest系統(tǒng)
?
在上一篇文章中,說(shuō)了為什么不能使用WinDbg調(diào)試ISR。
?
好在我們還有bochs這個(gè)帶調(diào)試功能的軟件虛擬機(jī)。bochs的調(diào)試功能比起WinDbg這個(gè)專業(yè)調(diào)試器來(lái),功能弱了十萬(wàn)八千里。但是,由于bochs是一個(gè)軟件實(shí)現(xiàn)的CPU(對(duì)Guest系統(tǒng)來(lái)說(shuō)相當(dāng)于硬件),比WinDbg要低一個(gè)層次,在一些特殊的情況下bochs就能出奇制勝了。bochs是CPU,是一切的主宰,不需要你guest系統(tǒng)給我提供任何支持。
?
安裝好bochs以后,可以在bochs中安裝windows xp。bochs運(yùn)行所依賴的一切硬件的配置都是依賴于bxrc配置文件。把安裝目錄下的bochsrc.bxrc復(fù)制一份,雙擊打開(kāi)。在下圖的對(duì)話框里可以編輯配置文件。
如果安裝xp需要將CPU的主頻調(diào)高一些(我用的50000000)memory調(diào)得合適一些,比如512Mb。在這之前還需要使用安裝目錄下的bximage.exe創(chuàng)建一個(gè)growing的硬盤(pán)文件,比如c.img。growing的方式可以避免以后guest系統(tǒng)硬盤(pán)不夠用。
?
?
然后配置“Disk & Boot”選項(xiàng),掛載上c.img
?
?然后配置光盤(pán)。需要一個(gè)windows xp安裝光盤(pán)的iso文件,也可以映射到物理光驅(qū)。
?
?然后配置有cdrom啟動(dòng)。
?
調(diào)試過(guò)程最好log下來(lái),便于后面分析。在“l(fā)ogfile”選項(xiàng)中配置調(diào)試的日志文件。
?
?
然后save,start就可以開(kāi)始運(yùn)行bochs了。
安裝過(guò)程需要比較漫長(zhǎng)的時(shí)間,畢竟軟件CPU的性能和物理CPU不在一個(gè)數(shù)量級(jí)上。打個(gè)球,洗個(gè)澡,再吃個(gè)飯的時(shí)間應(yīng)該差不多了。
安裝好以后注意備份一下,在bochs里安裝xp可是一個(gè)宏大的系統(tǒng)工程了。然后再把boot選項(xiàng)設(shè)置為從disk啟動(dòng)。
安裝好以后,就可以使用bochs調(diào)試器bochsdbg.exe加載配置文件運(yùn)行了。在“Bochs Start Menu”里面load然后start。
bochsdbg會(huì)停在f000:fff0處(這個(gè)時(shí)候CPU還沒(méi)有切換到保護(hù)模式)是bios的起始處。
運(yùn)行命令c(continue)可以繼續(xù)系統(tǒng)運(yùn)行。不久windows系統(tǒng)啟動(dòng)。在console里Ctrl-C可以中斷運(yùn)行輸入各種調(diào)試命令。
?
操作虛擬機(jī)的鼠標(biāo)需要點(diǎn)擊按鈕,釋放時(shí)Ctrl+鼠標(biāo)第三鍵(滾輪)
?
?
三、使用bochs調(diào)試觀察中斷過(guò)程
?
先介紹幾個(gè)調(diào)試指令(不是全部,只是在本文中用的的,其他的可以參考help或Bochs的文檔)
r 查看通用寄存器
sreg 參看段寄存器(idtr被歸到這里了)
creg 參看系統(tǒng)寄存器(cr0等)
x 參看內(nèi)存(線性地址)
xp 參看內(nèi)存(物理地址)
pb 通過(guò)物理地址下執(zhí)行斷點(diǎn)
lb 通過(guò)線性地址下執(zhí)行斷點(diǎn)
setpmem 修改物理內(nèi)存(Bochs只支持通過(guò)物理地址修改內(nèi)存,不過(guò)可以通過(guò)info tab參看整個(gè)分頁(yè)表,手工轉(zhuǎn)換一下,而且單步跟蹤時(shí)Bochs也會(huì)同時(shí)打印指令對(duì)應(yīng)的物理地址和線性地址)
help 幫助
info idt 參看idt信息
?
Crtl-C中斷下XP系統(tǒng)的執(zhí)行,就可以在Console中輸入調(diào)試命令。
?
1、靜態(tài)參看IDT信息
<bochs:5> sreg
es:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=7
?Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
cs:0x0008, dh=0x00cf9b00, dl=0x0000ffff, valid=1
?Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Accessed, 32-bit
ss:0x0010, dh=0x00cf9300, dl=0x0000ffff, valid=7
?Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ds:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=7
?Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
fs:0x0030, dh=0xffc093df, dl=0xf0000001, valid=7
?Data segment, base=0xffdff000, limit=0x00001fff, Read/Write, Accessed
gs:0x0000, dh=0x00001000, dl=0x00000000, valid=0
ldtr:0x0000, dh=0x00008200, dl=0x0000ffff, valid=0
tr:0x0028, dh=0x80008b04, dl=0x200020ab, valid=1
gdtr:base=0x000000008003f000, limit=0x3ff
idtr:base=0x000000008003f400, limit=0x7ff
<bochs:6> x /100w 0x8003f400
[bochs]:
0x000000008003f400 <bogus+?????? 0>:?0x0008f19c?0x80538e00?0x0008f314?0x80538e00
0x000000008003f410 <bogus+????? 16>:?0x0058113e?0x00008500?0x0008f6e4?0x8053ee00
0x000000008003f420 <bogus+????? 32>:?0x0008f864?0x8053ee00?0x0008f9c0?0x80538e00
0x000000008003f430 <bogus+????? 48>:?0x0008fb34?0x80538e00?0x0008019c?0x80548e00
0x000000008003f440 <bogus+????? 64>:?0x00501198?0x00008500?0x000805c0?0x80548e00
0x000000008003f450 <bogus+????? 80>:?0x000806e0?0x80548e00?0x00080820?0x80548e00
0x000000008003f460 <bogus+????? 96>:?0x00080a7c?0x80548e00?0x00080d60?0x80548e00
0x000000008003f470 <bogus+???? 112>:?0x00081450?0x80548e00?0x00081780?0x80548e00
0x000000008003f480 <bogus+???? 128>:?0x000818a0?0x80548e00?0x000819d8?0x80548e00
0x000000008003f490 <bogus+???? 144>:?0x00a01780?0x80548500?0x00081b40?0x80548e00
0x000000008003f4a0 <bogus+???? 160>:?0x00081780?0x80548e00?0x00081780?0x80548e00
... ...
<bochs:3> info idt
Interrupt Descriptor Table (base=0x000000008003f400, limit=2047):
IDT[0x00]=32-Bit Interrupt Gate target=0x0008:0x8053f19c, DPL=0
IDT[0x01]=32-Bit Interrupt Gate target=0x0008:0x8053f314, DPL=0
IDT[0x02]=Task Gate target=0x0058:0x0000113e, DPL=0
IDT[0x03]=32-Bit Interrupt Gate target=0x0008:0x8053f6e4, DPL=3
IDT[0x04]=32-Bit Interrupt Gate target=0x0008:0x8053f864, DPL=3
IDT[0x05]=32-Bit Interrupt Gate target=0x0008:0x8053f9c0, DPL=0
IDT[0x06]=32-Bit Interrupt Gate target=0x0008:0x8053fb34, DPL=0
... ...
<bochs:4> info idt 3
Interrupt Descriptor Table (base=0x000000008003f400, limit=2047):
IDT[0x03]=32-Bit Interrupt Gate target=0x0008:0x8053f6e4, DPL=3
<bochs:8> u 0x8053f6e4 0x8053f6ff
8053f6e4: (??????????????????? ): push 0x00000000?????????? ; 6a00
8053f6e6: (??????????????????? ): mov word ptr ss:[esp+2], 0x0000 ; 66c74424020000
8053f6ed: (??????????????????? ): push ebp????????????????? ; 55
8053f6ee: (??????????????????? ): push ebx????????????????? ; 53
8053f6ef: (??????????????????? ): push esi????????????????? ; 56
8053f6f0: (??????????????????? ): push edi????????????????? ; 57
8053f6f1: (??????????????????? ): push fs?????????????????? ; 0fa0
8053f6f3: (??????????????????? ): mov ebx, 0x00000030?????? ; bb30000000
8053f6f8: (??????????????????? ): mov fs, bx??????????????? ; 668ee3
8053f6fb: (??????????????????? ): mov ebx, dword ptr fs:0x0 ; 648b1d00000000
?
2、ring0 內(nèi)核態(tài)的INT 3中斷
進(jìn)入Console后單步一次,看一下目前運(yùn)行在什么地方。
<bochs:3> s
Next at t=5931168643
(0) [0x04f0833f] 0008:00000000bf80533f (unk. ctxt): pop edi?????????????????? ; 5f
?
線性地址bf80533f大于80000000應(yīng)是在內(nèi)核。
?
反匯編看一下指令
?
<bochs:5> u 0xbf80533f 0xbf805350
bf80533f: (??????????????????? ): pop edi?????????????????? ; 5f
bf805340: (??????????????????? ): pop esi?????????????????? ; 5e
bf805341: (??????????????????? ): leave???????????????????? ; c9
bf805342: (??????????????????? ): ret 0x0004??????????????? ; c20400
bf805345: (??????????????????? ): nop?????????????????????? ; 90
... ...
?
看一下bf805342對(duì)應(yīng)物理內(nèi)存中的數(shù)據(jù)。(s指令時(shí)知道 (0) [0x04f0833f] 0008:00000000bf80533f 的內(nèi)存映射關(guān)系)。
?
<bochs:8> xp /20b 0x04f08342
[bochs]:
0x0000000004f08342 <bogus+?????? 0>:?0xc2?0x04?0x00?0x90?0x90?0x90?0x90?0x90
0x0000000004f0834a <bogus+?????? 8>:?0x8b?0xff?0x55?0x8b?0xec?0x83?0xec?0x10
0x0000000004f08352 <bogus+????? 16>:?0x56?0x8b?0xf1?0x8b
?
將 bf805342: ret 0x0004 修改為int 3
?
<bochs:9> setpmem 0x04f08342 1 0xcc
?
看一下修改的結(jié)果
?
<bochs:11> u 0xbf80533f 0xbf805350
bf80533f: (??????????????????? ): pop edi?????????????????? ; 5f
bf805340: (??????????????????? ): pop esi?????????????????? ; 5e
bf805341: (??????????????????? ): leave???????????????????? ; c9
bf805342: (??????????????????? ): int3????????????????????? ; cc
bf805343: (??????????????????? ): add al, 0x00????????????? ; 0400
... ...
?
中斷之前的棧
<bochs:15> x /100w rsp
[bochs]:
0x00000000f78807b8 <bogus+?????? 0>:?0xf7880808?0xe13b1008?0x00000000?0x00000000
0x00000000f78807c8 <bogus+????? 16>:?0x00000001?0x00000001?0xf7880818?0xbf808ae6
0x00000000f78807d8 <bogus+????? 32>:?0xf78807f8?0xe13b1008?0x81f187d8?0x00000001
0x00000000f78807e8 <bogus+????? 48>:?0x00000000?0x00000000?0x00000001?0x00000001
0x00000000f78807f8 <bogus+????? 64>:?0x00000000?0x00000000?0x00000001?0x00000001
0x00000000f7880808 <bogus+????? 80>:?0x820c92a8?0xe13b1008?0x00000001?0xe183c918
0x00000000f7880818 <bogus+????? 96>:?0xf788084c?0xbf80d31c?0x81f187d8?0xe13b1008
0x00000000f7880828 <bogus+???? 112>:?0x8052890c?0x820c92a8?0xe13b1008?0x00000001
0x00000000f7880838 <bogus+???? 128>:?0xf7880894?0xf7880864?0xe18c5008?0x00000000
... ...
單步到執(zhí)行到int 3
<bochs:20> s
Next at t=5931168646
(0) [0x04f08342] 0008:00000000bf805342 (unk. ctxt): int3????????????????????? ; cc
?
int 3 之前寄存器和棧的情況。
?
<bochs:21> r
rax: 0x00000000:f78807c0 rcx: 0x00000000:00000001
rdx: 0x00000000:00000001 rbx: 0x00000000:e18c5008
rsp: 0x00000000:f78807d4 rbp: 0x00000000:f7880818
rsi: 0x00000000:e13b1008 rdi: 0x00000000:f7880808
r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
r10: 0x00000000:00000000 r11: 0x00000000:00000000
r12: 0x00000000:00000000 r13: 0x00000000:00000000
r14: 0x00000000:00000000 r15: 0x00000000:00000000
rip: 0x00000000:bf805342
eflags 0x00000286: id vip vif ac vm rf nt IOPL=0 of df IF tf SF zf af PF cf
<bochs:22> x /100w rsp
[bochs]:
0x00000000f78807d4 <bogus+?????? 0>:?0xbf808ae6?0xf78807f8?0xe13b1008?0x81f187d8
0x00000000f78807e4 <bogus+????? 16>:?0x00000001?0x00000000?0x00000000?0x00000001
0x00000000f78807f4 <bogus+????? 32>:?0x00000001?0x00000000?0x00000000?0x00000001
0x00000000f7880804 <bogus+????? 48>:?0x00000001?0x820c92a8?0xe13b1008?0x00000001
0x00000000f7880814 <bogus+????? 64>:?0xe183c918?0xf788084c?0xbf80d31c?0x81f187d8
0x00000000f7880824 <bogus+????? 80>:?0xe13b1008?0x8052890c?0x820c92a8?0xe13b1008
0x00000000f7880834 <bogus+????? 96>:?0x00000001?0xf7880894?0xf7880864?0xe18c5008
0x00000000f7880844 <bogus+???? 112>:?0x00000000?0x00000000?0xf788086c?0xbf81f825
0x00000000f7880854 <bogus+???? 128>:?0xe13b1008?0x00000001?0x00000000?0x00000000
0x00000000f7880864 <bogus+???? 144>:?0x0006f2e4?0xbf80cf90?0xf7880888?0xbf80d003
執(zhí)行int 3,程序跳轉(zhuǎn)到了 ISR 3 8053f6e4
<bochs:23> s
Next at t=5931168647
(0) [0x0053f6e4] 0008:000000008053f6e4 (unk. ctxt): push 0x00000000?????????? ; 6a00
?
寄存器和棧變化了:
<bochs:24> r
rax: 0x00000000:f78807c0 rcx: 0x00000000:00000001
rdx: 0x00000000:00000001 rbx: 0x00000000:e18c5008
rsp: 0x00000000:f78807c8 rbp: 0x00000000:f7880818
rsi: 0x00000000:e13b1008 rdi: 0x00000000:f7880808
r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
r10: 0x00000000:00000000 r11: 0x00000000:00000000
r12: 0x00000000:00000000 r13: 0x00000000:00000000
r14: 0x00000000:00000000 r15: 0x00000000:00000000
rip: 0x00000000:8053f6e4
eflags 0x00000086: id vip vif ac vm rf nt IOPL=0 of df if tf SF zf af PF cf
<bochs:25> x /100w rsp
[bochs]:
0x00000000f78807c8 <bogus+?????? 0>:?0xbf805343?0x00000008?0x00000286?0xbf808ae6
0x00000000f78807d8 <bogus+????? 16>:?0xf78807f8?0xe13b1008?0x81f187d8?0x00000001
0x00000000f78807e8 <bogus+????? 32>:?0x00000000?0x00000000?0x00000001?0x00000001
0x00000000f78807f8 <bogus+????? 48>:?0x00000000?0x00000000?0x00000001?0x00000001
0x00000000f7880808 <bogus+????? 64>:?0x820c92a8?0xe13b1008?0x00000001?0xe183c918
0x00000000f7880818 <bogus+????? 80>:?0xf788084c?0xbf80d31c?0x81f187d8?0xe13b1008
... ...
?
?
CPU 在執(zhí)行int 3時(shí)入棧的內(nèi)容為 0xbf805343?0x00000008?0x00000286 共三個(gè)dword 其中 0xbf805343是產(chǎn)生異常的指令的下一條指令(3號(hào)中斷是Trap類型),0x00000008是CS寄存器的值,0x00000286是eflags寄存器的值。
由于int 3指令也是在ring0執(zhí)行的,在這個(gè)異常過(guò)程中沒(méi)有優(yōu)先級(jí)的切換,所以沒(méi)有切換棧,入棧的內(nèi)容只有三個(gè)。
繼續(xù)執(zhí)行可以調(diào)試觀察ISR過(guò)程
<bochs:26> trace on
Tracing enabled for CPU0
<bochs:27> s 100
(0).[5931168647] [0x0053f6e4] 0008:000000008053f6e4 (unk. ctxt): push 0x00000000?????????? ; 6a00
(0).[5931168648] [0x0053f6e6] 0008:000000008053f6e6 (unk. ctxt): mov word ptr ss:[esp+2], 0x0000 ; 66c74424020000
(0).[5931168649] [0x0053f6ed] 0008:000000008053f6ed (unk. ctxt): push ebp????????????????? ; 55
(0).[5931168650] [0x0053f6ee] 0008:000000008053f6ee (unk. ctxt): push ebx????????????????? ; 53
(0).[5931168651] [0x0053f6ef] 0008:000000008053f6ef (unk. ctxt): push esi????????????????? ; 56
(0).[5931168652] [0x0053f6f0] 0008:000000008053f6f0 (unk. ctxt): push edi????????????????? ; 57
(0).[5931168653] [0x0053f6f1] 0008:000000008053f6f1 (unk. ctxt): push fs?????????????????? ; 0fa0
(0).[5931168654] [0x0053f6f3] 0008:000000008053f6f3 (unk. ctxt): mov ebx, 0x00000030?????? ; bb30000000
(0).[5931168655] [0x0053f6f8] 0008:000000008053f6f8 (unk. ctxt): mov fs, bx??????????????? ; 668ee3
(0).[5931168656] [0x0053f6fb] 0008:000000008053f6fb (unk. ctxt): mov ebx, dword ptr fs:0x0 ; 648b1d00000000
(0).[5931168657] [0x0053f702] 0008:000000008053f702 (unk. ctxt): push ebx????????????????? ; 53
(0).[5931168658] [0x0053f703] 0008:000000008053f703 (unk. ctxt): sub esp, 0x00000004?????? ; 83ec04
... ...
略。
?
3、ring3 用戶態(tài)下的INT 3中斷。
?
下面我們可以在ring 3 狀態(tài)下產(chǎn)生中斷,看看優(yōu)先級(jí)變化時(shí)的異常處理。
重啟bochs,啟動(dòng)XP Ctrl-C嘗試停在ring 3(如果不是Ring 3 多嘗試幾次,CPU還是有很大比例的時(shí)間運(yùn)行在ring 3態(tài)的)
如果暫停時(shí)eip線性地址小于0x80000000就是在ring 3態(tài)下
在ring 3態(tài)下的程序重復(fù)上述過(guò)程,觀察int 3前后的變化。
?
<bochs:9> r
rax: 0x00000000:1e7a18d1 rcx: 0x00000000:4d532745
rdx: 0x00000000:13f91976 rbx: 0x00000000:25dc3f3b
rsp: 0x00000000:0063efc8 rbp: 0x00000000:ffffffe0
rsi: 0x00000000:0009f7e0 rdi: 0x00000000:0009f870
r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
r10: 0x00000000:00000000 r11: 0x00000000:00000000
r12: 0x00000000:00000000 r13: 0x00000000:00000000
r14: 0x00000000:00000000 r15: 0x00000000:00000000
rip: 0x00000000:68021d3b
eflags 0x00000202: id vip vif ac vm rf nt IOPL=0 of df IF tf sf zf af pf cf
<bochs:10> x /100w rsp
[bochs]:
0x000000000063efc8 <bogus+?????? 0>:?0x0063efd8?0x00000020?0x0009f7e0?0x0009f7f0
0x000000000063efd8 <bogus+????? 16>:?0x0063f004?0x6802145f?0x0009f7f0?0x25dc3f3b
0x000000000063efe8 <bogus+????? 32>:?0x0009f760?0x00000020?0x0000003b?0x0009f7e0
0x000000000063eff8 <bogus+????? 48>:?0x000a5ef8?0x0009f760?0x0009f6e0?0x0063f05c
0x000000000063f008 <bogus+????? 64>:?0x6802192d?0x0009f660?0x0009f7e0?0x000a5ef8
0x000000000063f018 <bogus+????? 80>:?0x000a4f04?0x000a500c?0x00000021?0x00000020
0x000000000063f028 <bogus+????? 96>:?0x0009f660?0x0009f6e0?0x0009f760?0x0009f7e0
0x000000000063f038 <bogus+???? 112>:?0x00000010?0x00000006?0x00000000?0x000001c5
0x000000000063f048 <bogus+???? 128>:?0x000001c5?0x00000020?0x000a5ff8?0x00000080
... ...
<bochs:12> sreg
es:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=1
?Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
cs:0x001b, dh=0x00cffb00, dl=0x0000ffff, valid=1
?Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Accessed, 32-bit
ss:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=7
?Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ds:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=7
?Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
fs:0x003b, dh=0x7f40f3fd, dl=0xe0000fff, valid=1
?Data segment, base=0x7ffde000, limit=0x00000fff, Read/Write, Accessed
gs:0x0000, dh=0x00001000, dl=0x00000000, valid=0
ldtr:0x0000, dh=0x00008200, dl=0x0000ffff, valid=0
tr:0x0028, dh=0x80008b04, dl=0x200020ab, valid=1
gdtr:base=0x000000008003f000, limit=0x3ff
idtr:base=0x000000008003f400, limit=0x7ff
<bochs:26> s
Next at t=2257012356
(0) [0x05488d4a] 001b:0000000068021d4a (unk. ctxt): int3????????????????????? ; cc
<bochs:27> s
Next at t=2257012357
(0) [0x0053f6e4] 0008:000000008053f6e4 (unk. ctxt): push 0x00000000?????????? ; 6a00
<bochs:28> r
rax: 0x00000000:3edb3b9d rcx: 0x00000000:13f91977
rdx: 0x00000000:13f91977 rbx: 0x00000000:25dc3f3b
rsp: 0x00000000:f8149dcc?rbp: 0x00000000:ffffffe0
rsi: 0x00000000:0009f7e0 rdi: 0x00000000:0009f870
r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
r10: 0x00000000:00000000 r11: 0x00000000:00000000
r12: 0x00000000:00000000 r13: 0x00000000:00000000
r14: 0x00000000:00000000 r15: 0x00000000:00000000
rip: 0x00000000:8053f6e4
eflags 0x00000006: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af PF cf
<bochs:30> x /100w rsp
[bochs]:
0x00000000f8149dcc <bogus+?????? 0>:?0x68021d4b?0x0000001b?0x00000206?0x0063efc8
0x00000000f8149ddc <bogus+????? 16>:?0x00000023?0x00000000?0x00000000?0x00000000
0x00000000f8149dec <bogus+????? 32>:?0x00000000?0x0000027f?0x00000000?0x00000000
0x00000000f8149dfc <bogus+????? 48>:?0x00000000?0x00000000?0x00000000?0x00001f80
0x00000000f8149e0c <bogus+????? 64>:?0x0000ffff?0x00000000?0x00000000?0x00000000
0x00000000f8149e1c <bogus+????? 80>:?0x00000000?0x00000000?0x8a885d04?0x00000048
0x00000000f8149e2c <bogus+????? 96>:?0x00000000?0x77db612a?0x00000002?0x00006148
0x00000000f8149e3c <bogus+???? 112>:?0x00000000?0x00000000?0x00000000?0x00006134
... ...
?
在int 3前后的寄存器和棧都存在變化,首先不是同一棧,int 3之前是用戶棧,int 3之后,切換到了系統(tǒng)棧。esp的值由0063efc8變?yōu)榱薴8149dcc,由于CONTEXT的切換,寄存器的值都發(fā)生了變化。
在int 3的內(nèi)核棧中 0x68021d4b?0x0000001b?0x00000206?0x0063efc8?0x00000023 五個(gè)值是新壓入的,分別是:
(1)0x68021d4b 產(chǎn)生異常的EIP的后一條指令
(2)0x0000001b CS
(3)0x00000206 EFLAGS
(4)0x0063efc8 ESP
(5)0x00000023 SS
與文檔中描述相同。
?
4、TF標(biāo)志和中斷處理
?
調(diào)試器的單步跟蹤(比如WinDbg的t命令)一般是通過(guò)CPU的TF標(biāo)志實(shí)現(xiàn)的。如果TF標(biāo)志被置位,那么在每執(zhí)行一條指令后即產(chǎn)生一個(gè)int 1中斷。
?
<bochs:3> r
rax: 0x00000000:00a18f6a rcx: 0x00000000:ffdffc70
rdx: 0x00000000:00000000 rbx: 0x00000000:ffdffc70
rsp: 0x00000000:8054ac34 rbp: 0x00000000:8054ac50
rsi: 0x00000000:ffdffc50 rdi: 0x00000000:821e7b68
r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
r10: 0x00000000:00000000 r11: 0x00000000:00000000
r12: 0x00000000:00000000 r13: 0x00000000:00000000
r14: 0x00000000:00000000 r15: 0x00000000:00000000
rip: 0x00000000:f871d162
eflags 0x00000246: id vip vif ac vm rf nt IOPL=0 of df IF tf sf ZF af PF cf
?
eflags的第八位是TF標(biāo)志位,也就是將eflag and 0x100即可將TF置位
?
<bochs:38> setpmem 0x006d1d35 4 0x00034668
<bochs:39> setpmem 0x006d1d39 2 0x6600
<bochs:40> setpmem 0x006d1d3b 1 0x9d
<bochs:41> u rip rip+20
806d1d35: (??????????????????? ): push 0x00000346?????????? ; 6846030000
806d1d3a: (??????????????????? ): popf????????????????????? ; 669d
806d1d3c: (??????????????????? ): mov ebp, esp????????????? ; 8bec
806d1d3e: (??????????????????? ): mov dword ptr ss:[esp+68], eax ; 89442444
806d1d42: (??????????????????? ): mov dword ptr ss:[esp+64], ecx ; 894c2440
806d1d46: (??????????????????? ): mov dword ptr ss:[esp+60], edx ; 8954243c
?
由于bochsdbg不支持設(shè)置eflag基礎(chǔ)器的值,只能設(shè)置通用寄存器的值,這就通過(guò)修改代碼將eflags置位。
單步運(yùn)行:
<bochs:43> s
Next at t=36941382598
(0) [0x006d1d3a] 0008:00000000806d1d3a (unk. ctxt): popf????????????????????? ; 669d
<bochs:44> s
Next at t=36941382599
(0) [0x006d1d3c] 0008:00000000806d1d3c (unk. ctxt): mov ebp, esp????????????? ; 8bec
<bochs:46> s
Next at t=36941382600
(0) [0x006d1d3e] 0008:00000000806d1d3e (unk. ctxt): mov dword ptr ss:[esp+68], eax ; 89442444
TF置位是成功了的:
<bochs:47> r
rax: 0x00000000:00a18f6a rcx: 0x00000000:ffdffc70
rdx: 0x00000000:00000000 rbx: 0x00000000:ffdffc70
rsp: 0x00000000:8054ac22 rbp: 0x00000000:8054ac22
rsi: 0x00000000:ffdffc50 rdi: 0x00000000:821e7b68
r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
r10: 0x00000000:00000000 r11: 0x00000000:00000000
r12: 0x00000000:00000000 r13: 0x00000000:00000000
r14: 0x00000000:00000000 r15: 0x00000000:00000000
rip: 0x00000000:806d1d3e
eflags 0x00000346: id vip vif ac vm rf nt IOPL=0 of df IF TF sf ZF af PF cf
<bochs:48> s
Next at t=36941382601
(0) [0x0053f314] 0008:000000008053f314 (unk. ctxt): push 0x00000000?????????? ; 6a00
?
已經(jīng)進(jìn)入ISR 1
(這里不知為是么置位了TF后單步了兩條指令才跳入ISR 1,是bochs的實(shí)現(xiàn)原理問(wèn)題?存疑在此。)
?
<bochs:49> info idt
Interrupt Descriptor Table (base=0x000000008003f400, limit=2047):
IDT[0x00]=32-Bit Interrupt Gate target=0x0008:0x8053f19c, DPL=0
IDT[0x01]=32-Bit Interrupt Gate target=0x0008:0x8053f314, DPL=0
... ...
總結(jié)
以上是生活随笔為你收集整理的IDT系列:(二)中断处理过程,使用bochs调试IDT中的中断服务程序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。