⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 seh.cpp

📁 ICEExt for Driver Studio3.2的sourcecode
💻 CPP
字号:
/*++
    This file is mostly derived from mamaich's debugger codename BlindStudio.

    Copyleft  (c) 2002 Sten
    Contact information:
        mail: stenri@mail.ru

    Copyright (c) 2001 mamaich
    Contact information:
    	web: www.reversing.net/mamaich
        mail: mamaich@reversing.net
        ICQ# 70241285

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

 
Module Name:
    seh.cpp

Abstract:  Exception handler 

Revision History:

 Sten        05/06/2002
      The file is fully rewritten for better understanding.
 mamaich     14/06/2001
      Initial release

--*/

extern "C"{
#pragma warning ( push, 3 )
#include <ntddk.h>
#pragma warning ( pop )
}

#pragma warning ( disable: 4514 ) // unreferenced inline function has been removed
#pragma warning ( disable: 4127 ) // conditional expression is constant

#include "defs.h"
#include "undoc.h"
#include <stdio.h>

#define MAX_HANDLERS 0x12

static void *OldHandlers[MAX_HANDLERS];
static int  SehInited=0;

static int  IntNo=0;

static char *IntrDescr[MAX_HANDLERS+1]=
{
     "Divide by zero",                 // #00
     "Debug exception",                // #01
     "NMI",                            // #02
     "Breakpoint exception",           // #03
     "Overflow exception",             // #04
     "BOUND range exceeded",           // #05
     "Invalid opcode",                 // #06
     "Coprocessor not available",      // #07
     "Double fault",                   // #08
     "Coprocessor segment overrun",    // #09
     "Invalid TSS",                    // #0A
     "Segment not present",            // #0B
     "Stack fault",                    // #0C
     "General protection exception",   // #0D
     "Page-fault exception",           // #0E
     "Floating point error",           // #0F 
     "Alignment check",                // #10
     "Machine-check exception",        // #11
     "KeBugCheckEx called"             // Bug Check
}; 

void InstallBugCheckHandler(void *Handler);


///////////////////////////////////////////////////////////////////////////
//
// Handler for all processor-generated exceptions & KeBugCheckEx
//
///////////////////////////////////////////////////////////////////////////

void __declspec(naked) MyIntr(void)
{
     __asm
     {
           pushad
           push       fs
           push       ds
           push       es

           mov        eax,23h
           mov        ds,ax
           mov        es,ax

           mov        ebp,esp
//           sub        esp,__LOCAL_SIZE         

           sti
     }

     static int Dbg;
     Dbg = 0;

     if (IntNo == MAX_HANDLERS)
     {    // BugCheckEx called
          static int BCC;  // Bug Check Code
          static int BC1;  // Param 1
          static int BC2;  // Param 2
          static int BC3;  // Param 3
          static int BC4;  // Param 4
          __asm
          {
                mov        eax,[esp+12+32+4]
                mov        BCC, eax
                mov        eax,[esp+12+32+8]
                mov        BC1, eax
                mov        eax,[esp+12+32+12]
                mov        BC2, eax
                mov        eax,[esp+12+32+16]
                mov        BC3, eax
                mov        eax,[esp+12+32+20]
                mov        BC4, eax        
          }    

          DbgPrint("SEH: Warning! BugCheckEx %08X: %08X, %08X, %08X, %08X\n",
                           BCC, BC1,BC2,BC3,BC4);
          DbgPrint("SEH: Warning! System is unstable.\n");
     }

     if (Dbg) 
              DbgPrint("SEH: Exception %02x (%s) caught!\n", IntNo, IntrDescr[IntNo%(MAX_HANDLERS+1)]);
     
     if (0) // IntNo==0xE)  // TODO: if this is a page fault - try to resolve if myself
     {
       //*! Not implemented
     }

     static EXCEPTION_REGISTRATION_RECORD *FirstRec;
     static EXCEPTION_REGISTRATION_RECORD *Rec;
     __asm
     {
           mov        eax,fs:[0]
           mov        Rec,eax
     }
     FirstRec=Rec;

     while ((ULONG)Rec!=-1)
     {
           if(Dbg)
                   DbgPrint("SEH: Exception Handler: %08X\n", Rec->Handler);
           static CONTEXT Ctx;
           static EXCEPTION_RECORD Er;

           Er.ExceptionCode=0xc0000005;
           Er.ExceptionFlags=0;
           Er.ExceptionRecord=(EXCEPTION_RECORD*)-1;
           Er.ExceptionAddress=(void*)Ctx.Eip;
           Er.NumberParameters=0;

           __asm 
           {
                 mov        eax, [esp+12+8]
                 mov        Ctx.Ebp,eax

                 mov        eax,[esp+12+12]
                 add        eax,8
                 mov        Ctx.Esp,eax

                 mov        eax,[esp+12+32] // This is one handler for all exceptions, so
                 cmp        eax,0x80000000  // skip error code on stack if it is present
                 ja         Ok
                 mov        eax,[esp+12+32+4]
Ok:              mov        Ctx.Eip,eax
           }
         
           if (Dbg)
           {
               static bool DblFault=false;
               if(!DblFault)
               {
                  DblFault=true;
                  DbgPrint("SEH: Exception at Eip=%08X, Esp=%08X\n",Ctx.Eip,Ctx.Esp);
                  DbgPrint("Stack trace: (not implemented)\n");
//                DisplayStackTrace(Ctx.Eip, Ctx.Ebp);
                  DbgPrint("Stack trace finished.\n");
                  DblFault=false;
               }
           }

           if (Rec->Handler(&Er, Rec, &Ctx, &Ctx)!=ExceptionContinueSearch)
           {
               while(FirstRec!=Rec)
               {
                     static CONTEXT CtxUw;
                     static EXCEPTION_RECORD ErUw;

                     if (Dbg) DbgPrint("SEH: Unwinding...\n");

                     ErUw.ExceptionCode=0xC0000027; // Unwind
                     ErUw.ExceptionFlags=2;
                     ErUw.ExceptionRecord=(EXCEPTION_RECORD*)-1;
                     ErUw.ExceptionAddress=(void*)Ctx.Eip;
                     ErUw.NumberParameters=0;

                     FirstRec=FirstRec->Next;

                     FirstRec->Handler(&ErUw, FirstRec, &CtxUw, &CtxUw);
               }
    
               DbgPrint("SEH: Exception handled. Resuming execution from %08X\n", Ctx.Eip);
               DbgPrint("SEH: Hanging up... Continuing exceptions is not implemented!\n");
               __asm sti;
               a: goto a;
           }
           
           Rec=Rec->Next;
     }

     DbgPrint("SEH: Internal error! This code should never be executed!\n");
     // this function never returns
     __asm sti;
     b: goto b;
}

void InitSEH()
{
#include <pshpack1.h> // turn one byte packing of structures on
        static struct Intr
        {
                UCHAR Bytes[2];  // 0xc7, 0x05 - mov IntNo,_number_
                VOID *IntNoPtr;
                ULONG IntNum;
                UCHAR Push;      // 0x68 - push MyIntr
                VOID *FuncAddr;
                UCHAR Retn;      // 0xc3 - retn
        } Handlers[MAX_HANDLERS+1];
#include <poppack.h> // turn packing of structures off


        if (SehInited) return;

        for(int i=0; i<MAX_HANDLERS+1; i++)
        {
                Handlers[i].Bytes[0]=(UCHAR)0xc7;
                Handlers[i].Bytes[1]=(UCHAR)0x05;
                Handlers[i].IntNoPtr=&IntNo;
                Handlers[i].IntNum=i;
                Handlers[i].Push=(UCHAR)0x68;
                Handlers[i].FuncAddr=MyIntr;
                Handlers[i].Retn=(UCHAR)0xc3;
        }


//        for(i=0; i<MAX_HANDLERS; i++)
//        {  
//           OldHandlers[i]=SetInterruptHandler(i, &Handlers[i]);
//        }

          // Under NtIce don't hook anything except page faults
          OldHandlers[0xE] = SetInterruptHandler(0xE, &Handlers[0xE]);

          InstallBugCheckHandler(&Handlers[MAX_HANDLERS]);
          SehInited++;
}

////////////////////////////////////////////////////////////////////////////
//
// Cleanup SEH
//
////////////////////////////////////////////////////////////////////////////


void CleanupSEH()
{
//          for(int i=0; i<MAX_HANDLERS; i++)
//          {
//              SetInterruptHandler(i,OldHandlers[i]);
//          }

            SetInterruptHandler(0xE, OldHandlers[0xE]);

            RemoveBugCheckHandler();

            SehInited--;
}

////////////////////////////////////////////////////////////////////////////
//
// Internal. Installs the KeBugCheckEx hook 
//
////////////////////////////////////////////////////////////////////////////

static bool KEBInit=false;
static char PrevKEBBytes[6];

void InstallBugCheckHandler(void *Handler)
{
     char *KB = (char*)KeBugCheckEx;              // Get the start address of KeBugCheckEx

     if (KEBInit) return;

     for(int i=0; i<6; i++) PrevKEBBytes[i]=KB[i];

     KEBInit=true;

     KB[0]=0x68;                      // Push MyIntr
     *(PULONG)(KB+1)=(ULONG)Handler;
     KB[5]=(UCHAR)0xc3;                // Ret    
}

////////////////////////////////////////////////////////////////////////////
//
// Internal. Uninstalls the KeBugCheckEx hook 
//
////////////////////////////////////////////////////////////////////////////

void RemoveBugCheckHandler()
{
     if (KEBInit)
     {
          char *KB=(char*)KeBugCheckEx; // Get the start address of KeBugCheckEx

          for (int i=0; i<6; i++)
             KB[i]=PrevKEBBytes[i];

          KEBInit=false;
     }
}

////////////////////////////////////////////////////////////////////////////
//
// Internal. Used in PageIn 
//
////////////////////////////////////////////////////////////////////////////

void HookKeBugCheckEx()
{
#include <pshpack1.h> // turn one byte packing of structures on
        static struct Intr
        {
                char Bytes[2];    // 0xc7, 0x05 - mov IntNo,_number_
                void *IntNoPtr;
                int  IntNum;
                char Push;        // 0x68       - push MyIntr
                void *FuncAddr;
                char Retn;        // 0xc3       - retn
           
        }Handler;
#include <poppack.h>  // turn packing of structures off

        Handler.Bytes[0]=(UCHAR)0xc7;
        Handler.Bytes[1]=(UCHAR)0x05;
        Handler.IntNoPtr=&IntNo;
        Handler.IntNum=MAX_HANDLERS;
        Handler.Push=(UCHAR)0x68;
        Handler.FuncAddr=MyIntr;
        Handler.Retn=(UCHAR)0xc3;

        InstallBugCheckHandler(&Handler);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -