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

📄 mindbg.cpp

📁 学习WinDBG的好东西
💻 CPP
字号:
/*----------------------------------------------------------------------
The world抯 simplest debugger for Win32 programs
----------------------------------------------------------------------*/

/*//////////////////////////////////////////////////////////////////////
                           The Usual Includes
//////////////////////////////////////////////////////////////////////*/
#include "stdafx.h"

/*//////////////////////////////////////////////////////////////////////
                               Prototypes
//////////////////////////////////////////////////////////////////////*/
// Shows the minimal help.
void ShowHelp ( void ) ;

// Display functions
void DisplayCreateProcessEvent ( CREATE_PROCESS_DEBUG_INFO & stCPDI ) ;
void DisplayCreateThreadEvent ( CREATE_THREAD_DEBUG_INFO & stCTDI ) ;
void DisplayExitThreadEvent ( EXIT_THREAD_DEBUG_INFO & stETDI ) ;
void DisplayExitProcessEvent ( EXIT_PROCESS_DEBUG_INFO & stEPDI ) ;
void DisplayDllLoadEvent ( LOAD_DLL_DEBUG_INFO & stLDDI ) ;
void DisplayDllUnLoadEvent ( UNLOAD_DLL_DEBUG_INFO & stULDDI ) ;
void DisplayODSEvent ( HANDLE                     hProcess ,
                       OUTPUT_DEBUG_STRING_INFO & stODSI    ) ;
void DisplayExceptionEvent ( EXCEPTION_DEBUG_INFO & stEDI ) ;

/*//////////////////////////////////////////////////////////////////////
                              Entry Point!
//////////////////////////////////////////////////////////////////////*/
void main ( int argc , char * argv[ ] )
{
    // Check that there is a command-line argument.
    if ( 1 == argc )
    {
        ShowHelp ( ) ;
        return ;
    }

    // Concatenate the command-line parameters.
    TCHAR szCmdLine[ MAX_PATH ] ;
    szCmdLine[ 0 ] = '\0' ;

    for ( int i = 1 ; i < argc ; i++ )
    {
        strcat ( szCmdLine , argv[ i ] ) ;
        if ( i < argc )
        {
            strcat ( szCmdLine , " " ) ;
        }
    }

    // Try to start the debuggee process.  The function call looks
    // like a normal CreateProcess call except for the special start
    // option flag DEBUG_ONLY_THIS_PROCESS.
    STARTUPINFO         stStartInfo     ;
    PROCESS_INFORMATION stProcessInfo   ;

    memset ( &stStartInfo   , NULL , sizeof ( STARTUPINFO         ) ) ;
    memset ( &stProcessInfo , NULL , sizeof ( PROCESS_INFORMATION ) ) ;

    stStartInfo.cb = sizeof ( STARTUPINFO ) ;

    BOOL bRet = CreateProcess ( NULL                      ,
                                szCmdLine                 ,
                                NULL                      ,
                                NULL                      ,
                                FALSE                     ,
                                CREATE_NEW_CONSOLE |
                                  DEBUG_ONLY_THIS_PROCESS ,
                                NULL                      ,
                                NULL                      ,
                                &stStartInfo              ,
                                &stProcessInfo             ) ;

    // See whether the debuggee process started.
    if ( FALSE == bRet )
    {
        printf ( "Unable to start %s\n" , szCmdLine ) ;
        return ;
    }

    // The debuggee started, so let's enter the debug loop.
    DEBUG_EVENT stDE                      ;
    BOOL        bSeenInitialBP   = FALSE  ;
    BOOL        bContinue        = TRUE   ;
    HANDLE      hProcess         = INVALID_HANDLE_VALUE ;
    DWORD       dwContinueStatus          ;

    // Loop until told to stop.
    while ( TRUE == bContinue )
    {
        // Pause until a debug event notification happens.
        bContinue = WaitForDebugEvent ( &stDE , INFINITE ) ;

        // Handle the particular debug events.  Because MinDBG is only a
        // minimal debugger, it handles only a few events.
        switch ( stDE.dwDebugEventCode )
        {
            case CREATE_PROCESS_DEBUG_EVENT   :
            {
                DisplayCreateProcessEvent ( stDE.u.CreateProcessInfo ) ;
                // Save the handle information needed for later.
                hProcess = stDE.u.CreateProcessInfo.hProcess ;
                dwContinueStatus = DBG_CONTINUE ;
            }
            break ;
            case EXIT_PROCESS_DEBUG_EVENT   :
            {
                DisplayExitProcessEvent ( stDE.u.ExitProcess ) ;
                bContinue = FALSE ;
                dwContinueStatus = DBG_CONTINUE ;
            }
            break ;

            case LOAD_DLL_DEBUG_EVENT    :
            {
                DisplayDllLoadEvent ( stDE.u.LoadDll ) ;
                dwContinueStatus = DBG_CONTINUE ;
            }
            break ;
            case UNLOAD_DLL_DEBUG_EVENT  :
            {
                DisplayDllUnLoadEvent ( stDE.u.UnloadDll ) ;
                dwContinueStatus = DBG_CONTINUE ;
            }
            break ;

            case CREATE_THREAD_DEBUG_EVENT  :
            {
                DisplayCreateThreadEvent ( stDE.u.CreateThread ) ;
                dwContinueStatus = DBG_CONTINUE ;
            }
            break ;
            case EXIT_THREAD_DEBUG_EVENT    :
            {
                DisplayExitThreadEvent ( stDE.u.ExitThread ) ;
                dwContinueStatus = DBG_CONTINUE ;
            }
            break ;

            case OUTPUT_DEBUG_STRING_EVENT  :
            {
                DisplayODSEvent ( hProcess , stDE.u.DebugString ) ;
                dwContinueStatus = DBG_CONTINUE ;
            }
            break ;

            case RIP_EVENT  :
            {
                dwContinueStatus = DBG_CONTINUE ;
            }
            break ;

            case EXCEPTION_DEBUG_EVENT      :
            {
                DisplayExceptionEvent ( stDE.u.Exception ) ;

                // The only exception that I have to treat specially is
                // the initial breakpoint the loader provides.
                switch ( stDE.u.Exception.ExceptionRecord.ExceptionCode)
                {
                    case EXCEPTION_BREAKPOINT :
                    {

                        // If a breakpoint exception occurs and it's the
                        // first seen, I continue on my merry way;
                        // otherwise, I pass the exception on to the
                        // debuggee.
                        if ( FALSE == bSeenInitialBP )
                        {
                            bSeenInitialBP = TRUE ;
                            dwContinueStatus = DBG_CONTINUE ;
                        }
                        else
                        {
                            // Houston, we have a problem!
                            dwContinueStatus =
                                             DBG_EXCEPTION_NOT_HANDLED ;
                        }
                    }
                    break ;

                    // Just pass on any other exceptions to the
                    //  debuggee.
                    default                         :
                    {
                        dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED ;
                    }
                    break ;
                }
            }
            break ;

            // For any other events, just continue on.
            default                         :
            {
                dwContinueStatus = DBG_CONTINUE ;
            }
            break ;
        }

        // Pass on to the operating system.
        ContinueDebugEvent ( stDE.dwProcessId ,
                             stDE.dwThreadId  ,
                             dwContinueStatus  ) ;

    }
}

/*//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////*/
void ShowHelp ( void )
{
    printf ( "MinDBG <program to debug> "
             "<program's command-line options>\n" ) ;
}


void DisplayCreateProcessEvent ( CREATE_PROCESS_DEBUG_INFO & stCPDI )
{
    printf ( "Create Process Event      :\n" ) ;
    printf ( "   hFile                  : 0x%08X\n" ,
             stCPDI.hFile                            ) ;
    printf ( "   hProcess               : 0x%08X\n" ,
             stCPDI.hProcess                         ) ;
    printf ( "   hThread                : 0x%08X\n" ,
             stCPDI.hThread                          ) ;
    printf ( "   lpBaseOfImage          : 0x%08X\n" ,
             stCPDI.lpBaseOfImage                    ) ;
    printf ( "   dwDebugInfoFileOffset  : 0x%08X\n" ,
             stCPDI.dwDebugInfoFileOffset            ) ;
    printf ( "   nDebugInfoSize         : 0x%08X\n" ,
             stCPDI.nDebugInfoSize                   ) ;
    printf ( "   lpThreadLocalBase      : 0x%08X\n" ,
             stCPDI.lpThreadLocalBase                ) ;
    printf ( "   lpStartAddress         : 0x%08X\n" ,
             stCPDI.lpStartAddress                   ) ;
    printf ( "   lpImageName            : 0x%08X\n" ,
             stCPDI.lpImageName                      ) ;
    printf ( "   fUnicode               : 0x%08X\n" ,
             stCPDI.fUnicode                         ) ;
}

void DisplayCreateThreadEvent ( CREATE_THREAD_DEBUG_INFO & stCTDI )
{
    printf ( "Create Thread Event       :\n" ) ;
    printf ( "   hThread                : 0x%08X\n" ,
             stCTDI.hThread                          ) ;
    printf ( "   lpThreadLocalBase      : 0x%08X\n" ,
             stCTDI.lpThreadLocalBase                ) ;
    printf ( "   lpStartAddress         : 0x%08X\n" ,
             stCTDI.lpStartAddress                   ) ;
}

void DisplayExitThreadEvent ( EXIT_THREAD_DEBUG_INFO & stETDI )
{
    printf ( "Exit Thread Event         :\n" ) ;
    printf ( "   dwExitCode             : 0x%08X\n" ,
             stETDI.dwExitCode                       ) ;
}

void DisplayExitProcessEvent ( EXIT_PROCESS_DEBUG_INFO & stEPDI )
{
    printf ( "Exit Process Event        :\n" ) ;
    printf ( "   dwExitCode             : 0x%08X\n" ,
             stEPDI.dwExitCode                       ) ;
}

void DisplayDllLoadEvent ( LOAD_DLL_DEBUG_INFO & stLDDI )
{
    printf ( "DLL Load Event            :\n" ) ;
    printf ( "   hFile                  : 0x%08X\n" ,
             stLDDI.hFile                            ) ;
    printf ( "   lpBaseOfDll            : 0x%08X\n" ,
             stLDDI.lpBaseOfDll                      ) ;
    printf ( "   dwDebugInfoFileOffset  : 0x%08X\n" ,
             stLDDI.dwDebugInfoFileOffset            ) ;
    printf ( "   nDebugInfoSize         : 0x%08X\n" ,
             stLDDI.nDebugInfoSize                   ) ;
    printf ( "   lpImageName            : 0x%08X\n" ,
             stLDDI.lpImageName                      ) ;
    printf ( "   fUnicode               : 0x%08X\n" ,
             stLDDI.fUnicode                         ) ;
}

void DisplayDllUnLoadEvent ( UNLOAD_DLL_DEBUG_INFO & stULDDI )
{
    printf ( "DLL Unload Event          :\n" ) ;
    printf ( "   lpBaseOfDll            : 0x%08X\n" ,
             stULDDI.lpBaseOfDll                     ) ;
}

void DisplayODSEvent ( HANDLE                     hProcess ,
                       OUTPUT_DEBUG_STRING_INFO & stODSI    )
{
    printf ( "OutputDebugString Event   :\n" ) ;
    printf ( "   lpDebugStringData      : 0x%08X\n" ,
             stODSI.lpDebugStringData                ) ;
    printf ( "   fUnicode               : 0x%08X\n" ,
             stODSI.fUnicode                         ) ;
    printf ( "   nDebugStringLength     : 0x%08X\n" ,
             stODSI.nDebugStringLength               ) ;
    printf ( "   String                 :\n" ) ;

    char szBuff[ 512 ] ;
    if ( stODSI.nDebugStringLength > 512 )
    {
        return ;
    }

    DWORD dwRead ;
    BOOL bRet ;
    bRet = ReadProcessMemory ( hProcess                  ,
                                stODSI.lpDebugStringData  ,
                                szBuff                    ,
                                stODSI.nDebugStringLength ,
                                &dwRead                    ) ;
    printf ( "%s" , szBuff ) ;
}

void DisplayExceptionEvent ( EXCEPTION_DEBUG_INFO & stEDI )
{
    printf ( "Exception Event           :\n" ) ;
    printf ( "   dwFirstChance          : 0x%08X\n" ,
             stEDI.dwFirstChance                     ) ;
    printf ( "   ExceptionCode          : 0x%08X\n" ,
             stEDI.ExceptionRecord.ExceptionCode     ) ;
    printf ( "   ExceptionFlags         : 0x%08X\n" ,
             stEDI.ExceptionRecord.ExceptionFlags    ) ;
    printf ( "   ExceptionRecord        : 0x%08X\n" ,
             stEDI.ExceptionRecord.ExceptionRecord   ) ;
    printf ( "   ExceptionAddress       : 0x%08X\n" ,
             stEDI.ExceptionRecord.ExceptionAddress  ) ;
    printf ( "   NumberParameters       : 0x%08X\n" ,
             stEDI.ExceptionRecord.NumberParameters  ) ;
}

⌨️ 快捷键说明

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