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

📄 debug.cpp

📁 数据加密算法
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	m_mapModule.RemoveKey ( lpAddress ) ;

	delete p ;
}

void CDebugControl::EnableSingleStep ( Thread* pThread )
{
	// set TF bit of CPU flag register

	CONTEXT cnt ;

	cnt.ContextFlags = CONTEXT_CONTROL ;
	GetThreadContext ( pThread->m_hThread , &cnt ) ;
	
	cnt.EFlags |= TF_FLAG ;
	SetThreadContext ( pThread->m_hThread , &cnt ) ;

	SuspendThreadExcept ( pThread ) ;
}

void CDebugControl::BackwardEip ( Thread* pThread )
{
	// sub eip by one after encountering a breakpoint

	CONTEXT cnt ;

	cnt.ContextFlags = CONTEXT_CONTROL ;
	GetThreadContext ( pThread->m_hThread , &cnt ) ;

	cnt.Eip-- ;
	SetThreadContext ( pThread->m_hThread , &cnt ) ;

	FlushInstructionCache ( m_hProcess , NULL , 0 ) ;
}

// followings are helper function for safe-memory-read/write
BYTE CDebugControl::ReadByte ( LPVOID lpBase )
{
	DWORD oldp = 0 ;
	BYTE b = 0 ;

	VirtualProtectEx (
		m_hProcess ,
		lpBase ,
		1 ,
		PAGE_EXECUTE_READWRITE ,
		&oldp ) ;
	ReadProcessMemory (
		m_hProcess ,
		lpBase ,
		&b ,
		1 ,
		NULL ) ;
	VirtualProtectEx (
		m_hProcess ,
		lpBase ,
		1 ,
		oldp ,
		&oldp ) ;

	return b ;
}

BOOL CDebugControl::ReadBlock ( LPVOID lpBase , LPVOID lpBuf , int size )
{
	DWORD oldp = 0 , r;

	ReadProcessMemory (
		m_hProcess ,
		lpBase ,
		lpBuf ,
		size ,
		&r ) ;

	return r == ( DWORD ) size ; 
}

WORD CDebugControl::ReadWord ( LPVOID lpBase )
{
	DWORD oldp = 0 ;
	WORD w = 0 ;

	VirtualProtectEx (
		m_hProcess ,
		lpBase ,
		2 ,
		PAGE_EXECUTE_READWRITE ,
		&oldp ) ;
	ReadProcessMemory (
		m_hProcess ,
		lpBase ,
		&w ,
		2 ,
		NULL ) ;
	VirtualProtectEx (
		m_hProcess ,
		lpBase ,
		2 ,
		oldp ,
		&oldp ) ;

	return w ;
}

DWORD CDebugControl::ReadDWord ( LPVOID lpBase )
{
	DWORD dw = 0 , oldp = 0 ;

	VirtualProtectEx (
		m_hProcess ,
		lpBase ,
		4 ,
		PAGE_EXECUTE_READWRITE ,
		&oldp ) ;
	ReadProcessMemory (
		m_hProcess ,
		lpBase ,
		&dw ,
		4 ,
		NULL ) ;
	VirtualProtectEx (
		m_hProcess ,
		lpBase ,
		4 ,
		oldp ,
		&oldp ) ;

	return dw ;
}

void CDebugControl::WriteByte ( LPVOID lpBase , BYTE b )
{
	DWORD oldp = 0 ;

	VirtualProtectEx (
		m_hProcess ,
		lpBase ,
		1 ,
		PAGE_EXECUTE_READWRITE ,
		&oldp ) ;
	WriteProcessMemory (
		m_hProcess ,
		lpBase ,
		&b ,
		1 ,
		NULL ) ;
	VirtualProtectEx (
		m_hProcess ,
		lpBase ,
		1 ,
		oldp ,
		&oldp ) ;
}

void CDebugControl::WriteDWord ( LPVOID lpBase , DWORD dw )
{
	DWORD oldp = 0 ;

	VirtualProtectEx (
		m_hProcess ,
		lpBase ,
		4 ,
		PAGE_EXECUTE_READWRITE ,
		&oldp ) ;
	WriteProcessMemory (
		m_hProcess ,
		lpBase ,
		&dw ,
		4 ,
		NULL ) ;
	VirtualProtectEx (
		m_hProcess ,
		lpBase ,
		4 ,
		oldp ,
		&oldp ) ;
}

void CDebugControl::ReadString ( LPVOID lpBase , CString& str )
{
	BYTE b ;
	DWORD addr = ( DWORD ) lpBase ;

	str.Empty ( ) ;
	while ( b = ReadByte ( ( LPVOID ) addr ) )
	{
		str += ( CHAR ) b ;
		addr++ ;
	}
}

void CDebugControl::ReadStringW ( LPVOID lpBase , CString& str )
{
	WORD w ;
	DWORD addr = ( DWORD ) lpBase ;

	str.Empty ( ) ;
	while ( w = ReadWord ( ( LPVOID ) addr ) )
	{
		str += ( CHAR ) w ;
		addr += 2 ;
	}
}
DWORD CDebugControl::GetRegister ( Thread* pThread , DWORD dwID )
{
	CONTEXT cnt ;

	cnt.ContextFlags = CONTEXT_FULL ;
	GetThreadContext ( pThread->m_hThread , &cnt ) ;

	switch ( dwID )
	{
	case EAX : return cnt.Eax ;
	case EBX : return cnt.Ebx ;
	case ECX : return cnt.Ecx ;
	case EDX : return cnt.Edx ;
	case ESP : return cnt.Esp ;
	case EBP : return cnt.Ebp ;
	case ESI : return cnt.Esi ;
	case EDI : return cnt.Edi ;
	case EIP : return cnt.Eip ;
	}

	// no more register !
	ASSERT ( FALSE ) ;
	return 0 ;
}

void CDebugControl::SetRegister ( Thread* pThread , DWORD dwID , DWORD v )
{
	CONTEXT cnt ;

	cnt.ContextFlags = CONTEXT_FULL ;
	GetThreadContext ( pThread->m_hThread , &cnt ) ;

	switch ( dwID )
	{
	case EAX : cnt.Eax = v ; break ;
	case EBX : cnt.Ebx = v ; break ;
	case ECX : cnt.Ecx = v ; break ;
	case EDX : cnt.Edx = v ; break ;
	case EBP : cnt.Ebp = v ; break ;
	case ESP : cnt.Esp = v ; break ;
	case ESI : cnt.Esi = v ; break ;
	case EDI : cnt.Edi = v ; break ;
	case EIP : cnt.Eip = v ; break ;
	}
	SetThreadContext ( pThread->m_hThread , &cnt ) ;

	if ( dwID == EIP ) // muse flush instruction cache after eip is changed
		FlushInstructionCache ( m_hProcess , NULL , 0 ) ;
}

DWORD CDebugControl::GetParameter ( Thread* pThread , DWORD dwIndex )
{
	DWORD esp = GetRegister ( pThread , ESP ) ;
	return ReadDWord ( ( LPVOID ) ( esp + 4 * ( dwIndex + 1 ) ) ) ;
}

BOOL CDebugControl::OnBreakpoint ( DWORD dwID , EXCEPTION_RECORD& v ) // auto process logic
{
	Thread* pt = ( Thread* ) QueryThread ( dwID ) ;
	ASSERT ( pt != NULL ) ;

	Breakpoint* pb = QueryBreakpoint ( v.ExceptionAddress ) ;
	if ( pb == NULL ) // additional breakpoints
	{
		if ( ( DWORD ) m_lpMem <= ( DWORD ) v.ExceptionAddress &&
			 ( DWORD ) v.ExceptionAddress < ( DWORD ) m_lpMem + m_arHooked.GetSize ( ) * 8 )
		{
			// in a stub code

			DWORD ind = ( ( DWORD ) v.ExceptionAddress - ( DWORD ) m_lpMem ) / 8 ; // get index
			OnStubNotify ( pt , ind ) ;

			// set a breakpoint at return address
			StopAtReturn ( pt , ( Breakpoint* ) ( 0x80000000 | ind ) ) ; 
			return TRUE ;
		}
		return FALSE ;
	}

	// pass this breakpoint
	PassBreakpoint ( pt , pb ) ;

	return TRUE ;
}

BOOL CDebugControl::OnSingleStep ( DWORD dwID , EXCEPTION_RECORD& v ) 
{
	// after single-step , restore last breakpoint

	Thread* pt = QueryThread ( dwID ) ;
	ASSERT ( pt != NULL ) ;

	if ( pt->m_pLastBreakpoint == NULL )
		return FALSE ;

	Breakpoint* pb = pt->m_pLastBreakpoint ;
	pt->m_pLastBreakpoint = NULL ;

	WriteByte ( pb->m_lpAddress , INT3 ) ;

	// let other threads go
	ResumeThreadExcept ( pt ) ;

	return TRUE ;
}

Breakpoint* CDebugControl::AddBreakpoint ( Thread* pThread , LPVOID lpAddress )
{
	Breakpoint* p = QueryBreakpoint ( lpAddress ) ;

	if ( p == NULL ) // breakpoint not found - not set yet
	{
		p = new Breakpoint ;

		p->m_lpAddress = lpAddress ;
		p->m_byteCode = ReadByte ( lpAddress ) ;
		p->m_bLimit = TRUE ;

		WriteByte ( lpAddress , INT3 ) ;

		m_arBreakpoint.Add ( p ) ;
		m_mapBreakpoint [ lpAddress ] = p ;
	}
	p->m_arRefThread.Add ( pThread->m_dwID ) ;

	return p ;
}

// additional breakpoint - always vailable
void CDebugControl::AddUnlimitedBreakpoint ( LPVOID lpAddress )
{
	Breakpoint* p = new Breakpoint ;

	p->m_lpAddress = lpAddress ;
	p->m_byteCode = ReadByte ( lpAddress ) ;
	p->m_bLimit = FALSE ;

	WriteByte ( lpAddress , INT3 ) ;

	m_arBreakpoint.Add ( p ) ;
	m_mapBreakpoint [ lpAddress ] = p ;
}

Breakpoint* CDebugControl::QueryBreakpoint ( LPVOID lpAddress )
{
	LPVOID p ;
	
	if ( m_mapBreakpoint.Lookup ( lpAddress , p ) == FALSE )
		return NULL ;

	return ( Breakpoint* ) p ;
}

void CDebugControl::PassBreakpoint ( Thread* pThread , Breakpoint* pBreakpoint )
{
	// restore breakpoint code

	WriteByte ( pBreakpoint->m_lpAddress , pBreakpoint->m_byteCode );
	BackwardEip ( pThread ) ;

	if ( pBreakpoint->m_bLimit == FALSE ) // not limited - normal temp breakpoint
	{
		PreDispatch ( pThread , pBreakpoint ) ;

		EnableSingleStep ( pThread ) ;
		pThread->m_pLastBreakpoint = pBreakpoint ;

		StopAtReturn ( pThread , pBreakpoint ) ;
	}

	BOOL f = FALSE ;

	for ( ; ; ) 
	{
		int i , n = pBreakpoint->m_arRefThread.GetSize ( ) ;
		for ( i = n - 1 ; i >= 0 ; i++ )
		{
			Thread* p = QueryThread ( pBreakpoint->m_arRefThread [ i ] ) ;
			if ( p->m_dwID == pThread->m_dwID)
			{
				f = TRUE ;
				break ;
			}
		}
		
		if ( f == TRUE )
		{
			PostDispatch ( pThread ) ;

			pBreakpoint->m_arRefThread.RemoveAt ( i ) ;
			if ( pBreakpoint->m_bLimit == TRUE &&
				 pBreakpoint->m_arRefThread.GetSize ( ) == 0 ) // no reference
			{
				// remove breakpoint from internal data
				
				REMOVE_IN_PTR_ARRAY ( m_arBreakpoint , pBreakpoint ) ;
				m_mapBreakpoint.RemoveKey ( pBreakpoint->m_lpAddress ) ;
				delete pBreakpoint ; 
				
				return ;
			}
		}
		else break ;
	}
	
	// need single-step debugging
	
	if ( pBreakpoint->m_bLimit == TRUE )
	{
		EnableSingleStep ( pThread ) ;
		pThread->m_pLastBreakpoint = pBreakpoint ;
	}
}

void CDebugControl::StopAtReturn ( Thread* pThread , Breakpoint* pBreakpoint )
{
	LPVOID addr = ( LPVOID ) 
		ReadDWord ( ( LPVOID ) GetRegister ( pThread , ESP ) ) ;
	
	AddBreakpoint ( pThread , addr ) ;
	pThread->m_stBreakpoint.AddTail ( pBreakpoint ) ; // associated with a single thread
}

void CDebugControl::SnapModule ( ) 
{
	MODULEINFO mi ;
	CHAR buf [ MAX_PATH ] ;

	int i , n = m_arModule.GetSize ( ) ;
	for ( i = 0 ; i < n ; i++ )
	{
		Module2* p = ( Module2* ) m_arModule [ i ] ;

		if ( p->m_dwSize != 0 ) continue ;

		if ( TRUE == GetModuleInformation ( // get information about this module
			m_hProcess ,
			( HMODULE ) p->m_lpBase ,
			&mi ,
			sizeof ( MODULEINFO ) ) )
		{
			GetModuleFileNameEx (
				m_hProcess ,
				( HMODULE ) p->m_lpBase ,
				buf ,
				MAX_PATH ) ;

			p->m_strPathName = buf ;
			p->m_dwSize = mi.SizeOfImage ;

			if ( i != 0 )
			{
				CString msg ;
				msg.Format ( 
					IDS_DEBUG_LOAD_DLL , 
					p->m_strPathName , 
					p->m_lpBase , 
					( DWORD ) p->m_lpBase + p->m_dwSize ) ;
				m_pDancerDoc->m_pRecordManager->AddDebugMsg ( msg , 0 ) ;
			}
			
			PatchModule ( p ) ; // patch this moudle to install hooks
		}
	}
}

void CDebugControl::PreDispatch ( Thread* pThread , Breakpoint* pBreakpoint )
{
	CMainApp* p = ( CMainApp* ) AfxGetApp ( ) ;
	if ( p->m_pfnGetProcAddress == pBreakpoint->m_lpAddress )
	{
		LPVOID addr = ( LPVOID ) GetParameter ( pThread , 1 ) ,
			base1 = ( LPVOID ) GetReturnAddress ( pThread ) ,
			base2 = ( LPVOID ) GetParameter ( pThread , 0 ) ;

		WORD n ;
		Module2* pm1 = QueryModule ( base1 ) ,
			*pm2 = QueryModule ( base2 ) ;

		BOOL f = FALSE ;
		while ( pm1 == NULL || pm2 == NULL || 
			    pm1->m_dwSize == 0 || pm2->m_dwSize == 0 )
		{
			SnapModule ( ) ;

			pm1 = QueryModule ( base1 ) ;
			pm2 = QueryModule ( base2 ) ;

			if ( f == FALSE ) f = TRUE ;
			else break ;
		}
		if  ( pm1 == NULL || pm2 == NULL || 
			  pm1->m_dwSize == 0 || pm2->m_dwSize == 0 )
		{
			pThread->m_stDelay.AddTail ( -1 ) ;
			  return ;

⌨️ 快捷键说明

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