• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁 > 消費電子 > Windows內核調試器原理淺析(一)

    Windows內核調試器原理淺析(一)

    ——
    作者: 時間:2007-04-18 來源: 收藏
    WinDBG和用戶一點很大不同是內核在一臺機器上啟動,通過串口調試另一個相聯系的以Debug方式啟動的系統,這個系統可以是虛擬機上的系統,也可以是另一臺機器上的系統(這只是微軟推薦和實現的方法,其實象SoftICE這類內核可以實現單機調試)。很多人認為主要功能都是在WinDBG里實現,事實上并不是那么一回事,windows已經把內核調試的機制集成進了內核,WinDBG、kd之類的內核調試器要做的僅僅是通過串行發送特定格式數據包來進行聯系,比如中斷系統、下斷點、顯示內存數據等等。然后把收到的數據包經過WinDBG處理顯示出來。    

        在進一步介紹WinDBG之前,先介紹兩個函數:KdpTrace、KdpStub,我在《windows異常處理流程》一文里簡單提過這兩個函數。現在再提一下,當異常發生于內核態下,會調用KiDebugRoutine兩次,異常發生于用戶態下,會調用KiDebugRoutine一次,而且第一次調用都是剛開始處理異常的時候。

        當WinDBG未被加載時KiDebugRoutine為KdpStub,處理也很簡單,主要是對由int 0x2d引起的異常如DbgPrint、DbgPrompt、加載卸載SYMBOLS(關于int 0x2d引起的異常將在后面詳細介紹)等,把Context.Eip加1,跳過int 0x2d后面跟著的int 0x3指令。

        真正實現了WinDBG功能的函數是KdpTrap,它負責處理所有STATUS_BREAKPOINT和STATUS_SINGLE_STEP(單步)異常。STATUS_BREAKPOINT的異常包括int 0x3、DbgPrint、DbgPrompt、加載卸載SYMBOLS。DbgPrint的處理最簡單,KdpTrap直接向調試器發含有字符串的包。DbgPrompt因為是要輸出并接收字符串,所以先將含有字符串的包發送出去,再陷入循環等待接收來自調試器的含有回復字符串的包。SYMBOLS的加載和卸載通過調用KdpReportSymbolsStateChange,int 0x3斷點異常和int 0x1單步異常(這兩個異常基本上是內核調試器處理得最多的異常)通過調用KdpReportExceptionStateChange,這兩個函數很相似,都是通過調用KdpSendWaitContinue函數。KdpSendWaitContinue可以說是內核調試器功能的大管家,負責各個功能的分派。這個函數向內核調試器發送要發送的信息,比如當前所有寄存器狀態,每次單步后我們都可以發現寄存器的信息被更新,就是內核調試器接受它發出的包含最新機器狀態的包;還有SYMBOLS的狀態,這樣加載和卸載了SYMBOLS我們都能在內核調試器里看到相應的反應。然后KdpSendWaitContinue等待從內核調試器發來的包含命令的包,決定下一步該干什么。讓我們來看看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;

     

    -------------------------------------------------------------------------------- 
     


    評論


    相關推薦

    技術專區

    關閉
    主站蜘蛛池模板: 沙洋县| 奎屯市| 根河市| 丹东市| 永济市| 沭阳县| 铜鼓县| 阿克苏市| 苏尼特右旗| 临漳县| 吉林市| 通山县| 浦县| 西昌市| 新密市| 虎林市| 门源| 枣庄市| 延长县| 容城县| 东明县| 和静县| 浦北县| 类乌齐县| 麻栗坡县| 八宿县| 尼木县| 桂林市| 永顺县| 临安市| 汤原县| 手游| 桃江县| 英德市| 汝南县| 正定县| 柳河县| 中方县| 孙吴县| 乌拉特前旗| 焉耆|