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

📄 debug.cpp

📁 数据加密算法
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include "pch.h"
#include "util.h"
#include "main.h"
#include "doc.h"
#include "debug.h"
#include "type.h"
#include "record.h"

Record::Record ( )
{
}

Record::~Record ( )
{
	if ( m_nType == HOOK_MSG &&
		 m_pDispatch->m_bPending == FALSE ) // this call is finished
		delete m_pDispatch ;
}

void Record::Present ( CString& msg ) // output to a string
{
	if ( m_nType != HOOK_MSG )
	{
		xTranslateTime ( m_dwTime , msg ) ;
		msg += ' ' ;
		msg += m_strMsg ; 
	}
	else
	{
		if ( m_pDispatch->m_bHasName == TRUE  )
		{
			msg = m_pDispatch->m_strFunction ;
		}
		else msg.Format ( "0x%08x" , m_pDispatch->m_wOrdinal ) ;
	}
}

void Record::Present2 ( CString& msg ) // another output function
{
	CString str ;

	msg = m_pDispatch->m_strImportName ;
	msg += " - " ;

	if ( m_pDispatch->m_bHasName == TRUE  )
	{
		msg += m_pDispatch->m_strFunction ;
	}
	else 
	{
		str.Format ( "0x%08x" , m_pDispatch->m_wOrdinal ) ;
		msg += str ;
	}

	msg += '!' ;
	msg += m_pDispatch->m_strExportName ;
}

Thread::Thread ( )
{
	m_hThread = NULL ;
	m_pLastBreakpoint = NULL ;

	m_dwDepth = 0 ;
}

Thread::~Thread ( )
{
}

CDebugControl::CDebugControl ( )
{
	m_bDebugging = FALSE ;
	m_bPause = FALSE ;
	InitializeCriticalSection ( &m_csSync ) ;
}

CDebugControl::~CDebugControl ( )
{
	if ( m_bDebugging == TRUE )
		Stop ( ) ;

	DeleteCriticalSection ( &m_csSync ) ;
}

void CDebugControl::AttachTo ( CDancerDoc* pDancerDoc )
{
	m_pDancerDoc = pDancerDoc ;
}

void CDebugControl::Start ( )
{
	PreProcess ( ) ;

	m_pDebugThread = AfxBeginThread ( DebugThread , this ) ; // create debug thread
}

void CDebugControl::Stop ( )
{
	TerminateProcess ( m_hProcess , -1 ) ;
}

void CDebugControl::PreProcess ( )
{
	// reset internal data

	m_bDebugging = TRUE ;
	m_bPause = FALSE ;
	m_bInitialBreakpoint = TRUE ;
	m_bExited = FALSE ;

	m_pDancerDoc->m_pImgFile->GetHooked ( m_arHooked ) ;

	// load type information 

	m_pDancerDoc->m_pRecordManager->Start ( ) ;

	m_pTypeManager = new CTypeManager ;
	m_pTypeManager->AttachTo ( this ) ;
	m_pTypeManager->LoadType ( m_arHooked ) ;
	m_pTypeManager->LoadDecoder ( ) ;
}

void CDebugControl::PostProcess ( )
{
	m_bDebugging = FALSE ;
	m_bPause = FALSE ;

	// prepare for all safe attribute ( reset )

	RELEASE_PTR_ARRAY ( m_arThread , Thread ) ;
	RELEASE_PTR_ARRAY ( m_arModule , Module2 ) ;
	RELEASE_PTR_ARRAY ( m_arHooked , Hooked ) ;
	RELEASE_PTR_ARRAY ( m_arBreakpoint , Breakpoint ) ;

	m_mapBreakpoint.RemoveAll ( ) ;
	m_mapModule.RemoveAll ( ) ;
	m_mapThread.RemoveAll ( ) ;

	m_pDancerDoc->m_pRecordManager->Stop ( ) ;
	m_pTypeManager->UnloadDecoder ( ) ;

	if ( m_pTypeManager != NULL )
	{
		delete m_pTypeManager ;
		m_pTypeManager = NULL ;
	}
}

UINT CDebugControl::DebugThread ( LPVOID lpParam ) // debug core
{
	TRY
	{
		CDebugControl* p = ( CDebugControl* ) lpParam ;
		CString pn = p->m_pDancerDoc->GetPathName ( ) ;
		pn += ' ' ;
		pn += p->m_pDancerDoc->m_strParameter ;

		STARTUPINFO si ;
		PROCESS_INFORMATION pi ;

		ZeroMemory ( &si , sizeof ( STARTUPINFO ) ) ;
		si.cb = sizeof ( STARTUPINFO ) ;

		// create target process and get ready

		BOOL ret = CreateProcess (
			NULL ,
			pn.LockBuffer ( ) ,
			NULL ,
			NULL ,
			FALSE ,
			DEBUG_ONLY_THIS_PROCESS ,
			NULL ,
			p->m_pDancerDoc->m_strPath ,
			&si ,
			&pi ) ;
		pn.UnlockBuffer ( ) ;

		if ( ret == TRUE )
		{
			DEBUG_EVENT de ;
			DWORD ret ;
			BOOL fTimeout ;

			CloseHandle ( pi.hThread ) ;
			CloseHandle ( pi.hProcess ) ;

			p->m_dwProcessID = pi.dwProcessId ;
			
			for ( ; ; )
			{
				for ( ; ; )
				{
					fTimeout = !WaitForDebugEvent ( &de , UPDATE_INTERVAL_TIME ) ;
					
					if ( fTimeout ) // time out
					{
						p->SnapModule ( ) ;
						p->m_pDancerDoc->m_pRecordManager->Update ( ) ;	
					}
					else break ;
				}

				// dispatch debug events
				
				switch ( de.dwDebugEventCode ) 
				{
				case CREATE_PROCESS_DEBUG_EVENT :
					ret = p->OnCreateProcess ( de.dwThreadId , de.u.CreateProcessInfo ) ;
					break ;
				case EXIT_PROCESS_DEBUG_EVENT :
					ret = p->OnExitProcess ( de.dwThreadId , de.u.ExitProcess ) ;
					break ;
				case CREATE_THREAD_DEBUG_EVENT :
					ret = p->OnCreateThread ( de.dwThreadId , de.u.CreateThread ) ;
					break ;
				case EXIT_THREAD_DEBUG_EVENT :
					ret = p->OnExitThread ( de.dwThreadId , de.u.ExitThread ) ;
					break ;
				case EXCEPTION_DEBUG_EVENT :
					ret = p->OnException ( de.dwThreadId , de.u.Exception ) ;
					break ;
				case LOAD_DLL_DEBUG_EVENT :
					ret = p->OnLoadDll ( de.u.LoadDll ) ;
					break ;
				case UNLOAD_DLL_DEBUG_EVENT :
					ret = p->OnUnloadDll ( de.u.UnloadDll ) ;
					break ;
				}
				
				ContinueDebugEvent ( de.dwProcessId , de.dwThreadId , ret ) ;
				
				if ( de.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT )
					break ;
			}
		}
		
		p->PostProcess ( ) ; // terminate
	}
	CATCH_ALL ( CException )
	{
		// should not come here !
	}
	END_CATCH_ALL ;
	
	return 0 ;
}

DWORD CDebugControl::OnCreateProcess ( DWORD dwID , CREATE_PROCESS_DEBUG_INFO& v )
{
	m_hProcess = v.hProcess ;
	
	AddThread ( dwID , v.lpStartAddress , v.hThread ) ;
	AddModule ( v.lpBaseOfImage ) ;
	
	CloseHandle ( v.hFile ) ;
	
	// send debug message
	
	CString msg ;
	msg.Format ( IDS_DEBUG_CREATE_PROCESS , m_dwProcessID , v.lpBaseOfImage ) ;
	m_pDancerDoc->m_pRecordManager->AddDebugMsg ( msg , 0 ) ;
	
	return DBG_CONTINUE ;
}

DWORD CDebugControl::OnExitProcess ( DWORD dwID , EXIT_PROCESS_DEBUG_INFO& v )
{
	// send debug message

	CString msg ;
	msg.Format ( IDS_DEBUG_EXIT_PROCESS , dwID , v.dwExitCode ) ;
	m_pDancerDoc->m_pRecordManager->AddDebugMsg ( msg , 0 ) ;

	RemoveThread ( dwID ) ;	

	int i , n = m_arModule.GetSize ( ) ;
	for ( i = 0 ; i < n ; i++ )
	{
		Module2* pModule = ( Module2* ) m_arModule [ i ] ;
		delete pModule ;
	}
	m_mapModule.RemoveAll ( ) ;
	m_mapThread.RemoveAll ( ) ;
	m_arModule.RemoveAll ( ) ;
	m_arThread.RemoveAll ( ) ;
	
	CloseHandle ( m_hProcess ) ;

	return DBG_CONTINUE ;
}

DWORD CDebugControl::OnCreateThread ( DWORD dwID , CREATE_THREAD_DEBUG_INFO& v )
{
	AddThread ( dwID , v.lpStartAddress , v.hThread ) ;
	
	NotifyCreateThread ( dwID , v.lpStartAddress ) ;
	
	return DBG_CONTINUE ;
}

DWORD CDebugControl::OnExitThread ( DWORD dwID , EXIT_THREAD_DEBUG_INFO& v )
{
	RemoveThread ( dwID ) ;

	// send debug message
	
	CString msg ;
	msg.Format ( IDS_DEBUG_EXIT_THREAD , dwID , v.dwExitCode ) ;
	m_pDancerDoc->m_pRecordManager->AddDebugMsg ( msg , 0 ) ;
	
	return DBG_CONTINUE ;
}

DWORD CDebugControl::OnException ( DWORD dwID , EXCEPTION_DEBUG_INFO& v )
{
	if ( m_bInitialBreakpoint == TRUE )
	{
		// prepare stub code 
		
		int i , n = m_arHooked.GetSize ( ) ;
		
		m_lpMem = VirtualAllocEx (
			m_hProcess ,
			NULL ,
			n * 8 ,
			MEM_COMMIT ,
			PAGE_EXECUTE_READWRITE ) ;
		
		for ( i = 0; i < n ; i++ )
		{
			WriteByte ( ( LPVOID ) ( ( DWORD ) m_lpMem + 8 * i ) , INT3 ) ;
			WriteByte ( ( LPVOID ) ( ( DWORD ) m_lpMem + 8 * i + 1 ) , JMP ) ;
			WriteDWord ( ( LPVOID ) ( ( DWORD ) m_lpMem + 8 * i + 2 ) , 0 ) ;
		}

		// hook additional functions , which is needed for me not user

		CMainApp* p = ( CMainApp* ) AfxGetApp ( ) ;

		if ( p->m_appOption.m_bHookExplicit == TRUE )
		{
			AddUnlimitedBreakpoint ( p->m_pfnGetProcAddress ) ; // break at GetProcAddress
			AddUnlimitedBreakpoint ( p->m_pfnLoadLibraryExW ) ; // break at LoadLibraryExW
		}

		if ( p->m_appOption.m_bCheckDebugger == TRUE )
		{
			AddUnlimitedBreakpoint ( p->m_pfnIsDebuggerPresent ) ;  // break at IsDebuggerPresent
		}
		
		SnapModule ( ) ; // catch all modules
		
		CMainFrame* pf = ( CMainFrame* ) AfxGetMainWnd ( ) ;
		pf->SetMessageText ( AFX_IDS_IDLEMESSAGE ) ;
		
		Thread* pt = ( Thread* ) m_arThread [ 0 ] ;
		NotifyCreateThread ( pt->m_dwID , pt->m_lpStartAddress ) ;
		
		m_bInitialBreakpoint = FALSE ;
		return DBG_CONTINUE ;
	}

	// continue dispatching

	if ( v.dwFirstChance != 0 ) // first chance
	{
		if ( v.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT )
		{
			if ( OnBreakpoint ( dwID , v.ExceptionRecord ) == TRUE )
				return DBG_CONTINUE ;
		}
		else if ( v.ExceptionRecord.ExceptionCode == EXCEPTION_SINGLE_STEP )
		{
			if ( OnSingleStep ( dwID , v.ExceptionRecord ) == TRUE )
				return DBG_CONTINUE ;
		}
	}
	else // second chance , target is error !
	{
		CString msg ;
		msg.Format ( 
			IDS_BAD_EXCEPTION , 
			v.ExceptionRecord.ExceptionCode , 
			v.ExceptionRecord.ExceptionAddress ) ;
		AfxMessageBox ( msg , MB_ICONSTOP ) ;
	}

	return DBG_EXCEPTION_NOT_HANDLED ;
}

DWORD CDebugControl::OnLoadDll ( LOAD_DLL_DEBUG_INFO& v )
{
	AddModule ( v.lpBaseOfDll ) ;
	CloseHandle ( v.hFile ) ;

	return DBG_CONTINUE ;
}

DWORD CDebugControl::OnUnloadDll ( UNLOAD_DLL_DEBUG_INFO& v )
{
	// refresh all modules

	Module2* pm = QueryModule ( v.lpBaseOfDll ) ;
	if ( pm == NULL )
	{
		SnapModule ( ) ;
		pm = QueryModule ( v.lpBaseOfDll ) ;
	}
	if ( pm != NULL )
	{
		CString msg ;
		msg.Format ( IDS_DEBUG_UNLOAD_DLL , pm->m_strPathName ) ;
		m_pDancerDoc->m_pRecordManager->AddDebugMsg ( msg , 0 ) ;
	}

	RemoveModule ( v.lpBaseOfDll ) ;

	return DBG_CONTINUE ;
}

void CDebugControl::AddThread ( DWORD dwID , LPVOID lpStartAddress , HANDLE hThread )
{
	Thread* p = new Thread ;

	p->m_dwID = dwID ;
	p->m_lpStartAddress = lpStartAddress ;
	p->m_hThread = hThread ;
	
	m_arThread.Add ( p ) ;
	m_mapThread [ ( LPVOID ) dwID ] = p ; // map it
}

Thread* CDebugControl::QueryThread ( DWORD dwID )
{
	LPVOID p ;

	if ( m_mapThread.Lookup ( ( LPVOID ) dwID , p ) == FALSE )
		return NULL ;

	return ( Thread* ) p ;
}

void CDebugControl::RemoveThread ( DWORD dwID )
{
	Thread* p = QueryThread ( dwID ) ;
	ASSERT ( p != NULL ) ;

	REMOVE_IN_PTR_ARRAY ( m_arThread , p ) ;
	m_mapThread.RemoveKey ( ( LPVOID ) dwID ) ;

	CloseHandle ( p->m_hThread ) ;
	delete p ;
}

void CDebugControl::AddModule ( LPVOID lpBase )
{
	Module2* p = new Module2 ;

	p->m_lpBase = lpBase ;
	p->m_dwSize = 0 ;
	
	m_arModule.Add ( p ) ;
	m_mapModule [ lpBase ] = p ; // map it
}

Module2* CDebugControl::QueryModule ( LPVOID lpAddress )
{
	if ( lpAddress == NULL ) // get the main module - the first one
		return ( Module2* ) m_arModule [ 0 ] ;

	LPVOID p ;
	if ( m_mapModule.Lookup ( lpAddress , p ) == FALSE )
	{ 
		DWORD e1 , e2 ;
		int i , n = m_arModule.GetSize ( ) ;
		for ( i = 0 ; i < n ; i++ )
		{
			Module2* p = ( Module2* ) m_arModule [ i ] ;
			e1 = ( DWORD ) p->m_lpBase ;
			e2 = e1 + p->m_dwSize ; 

			if ( e1 <= ( DWORD ) lpAddress &&
				 e2 > ( DWORD ) lpAddress )
				 return p ;
		}
		return NULL ; // nothing matched
	}

	return ( Module2* ) p ;
}

void CDebugControl::RemoveModule ( LPVOID lpAddress )
{
	Module2* p = QueryModule ( lpAddress ) ;
	if ( p == NULL ) return ;

	REMOVE_IN_PTR_ARRAY ( m_arModule , p ) ;

⌨️ 快捷键说明

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