Windows內核調試器原理淺析(一)
——
在進(jìn)一步介紹WinDBG之前,先介紹兩個(gè)函數:KdpTrace、KdpStub,我在《windows異常處理流程》一文里簡(jiǎn)單提過(guò)這兩個(gè)函數?,F在再提一下,當異常發(fā)生于內核態(tài)下,會(huì )調用KiDebugRoutine兩次,異常發(fā)生于用戶(hù)態(tài)下,會(huì )調用KiDebugRoutine一次,而且第一次調用都是剛開(kāi)始處理異常的時(shí)候。
當WinDBG未被加載時(shí)KiDebugRoutine為KdpStub,處理也很簡(jiǎn)單,主要是對由int 0x2d引起的異常如DbgPrint、DbgPrompt、加載卸載SYMBOLS(關(guān)于int 0x2d引起的異常將在后面詳細介紹)等,把Context.Eip加1,跳過(guò)int 0x2d后面跟著(zhù)的int 0x3指令。
真正實(shí)現了WinDBG功能的函數是KdpTrap,它負責處理所有STATUS_BREAKPOINT和STATUS_SINGLE_STEP(單步)異常。STATUS_BREAKPOINT的異常包括int 0x3、DbgPrint、DbgPrompt、加載卸載SYMBOLS。DbgPrint的處理最簡(jiǎn)單,KdpTrap直接向調試器發(fā)含有字符串的包。DbgPrompt因為是要輸出并接收字符串,所以先將含有字符串的包發(fā)送出去,再陷入循環(huán)等待接收來(lái)自調試器的含有回復字符串的包。SYMBOLS的加載和卸載通過(guò)調用KdpReportSymbolsStateChange,int 0x3斷點(diǎn)異常和int 0x1單步異常(這兩個(gè)異?;旧鲜莾群苏{試器處理得最多的異常)通過(guò)調用KdpReportExceptionStateChange,這兩個(gè)函數很相似,都是通過(guò)調用KdpSendWaitContinue函數。KdpSendWaitContinue可以說(shuō)是內核調試器功能的大管家,負責各個(gè)功能的分派。這個(gè)函數向內核調試器發(fā)送要發(fā)送的信息,比如當前所有寄存器狀態(tài),每次單步后我們都可以發(fā)現寄存器的信息被更新,就是內核調試器接受它發(fā)出的包含最新機器狀態(tài)的包;還有SYMBOLS的狀態(tài),這樣加載和卸載了SYMBOLS我們都能在內核調試器里看到相應的反應。然后KdpSendWaitContinue等待從內核調試器發(fā)來(lái)的包含命令的包,決定下一步該干什么。讓我們來(lái)看看KdpSendWaitContinue都能干些什么:
case DbgKdReadVirtualMemoryApi:
KdpReadVirtualMemory(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdReadVirtualMemory64Api:
KdpReadVirtualMemory64(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdWriteVirtualMemoryApi:
KdpWriteVirtualMemory(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdWriteVirtualMemory64Api:
KdpWriteVirtualMemory64(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdReadPhysicalMemoryApi:
KdpReadPhysicalMemory(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdWritePhysicalMemoryApi:
KdpWritePhysicalMemory(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdGetContextApi:
KdpGetContext(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdSetContextApi:
KdpSetContext(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdWriteBreakPointApi:
KdpWriteBreakpoint(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdRestoreBreakPointApi:
KdpRestoreBreakpoin(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdReadControlSpaceApi:
KdpReadControlSpace(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdWriteControlSpaceApi:
KdpWriteControlSpace(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdReadIoSpaceApi:
KdpReadIoSpace(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdWriteIoSpaceApi:
KdpWriteIoSpace(&ManipulateState,&MessageData,ContextRecord);
break;
--------------------------------------------------------------------------------
評論