📄 mindbg.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 + -