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

📄 dasmcode.cpp

📁 win32 exe程序反汇编
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*		fichier DasmCode.cpp : fichier implementation
 *
 *	descr : classe automate desassembleur
 *	projet : PEDasm
 *	
 *	rq:
 *	Ce programme est libre de droits. Il peut etre distribue et/ou modifie
 *  selon les termes de la licence 'GNU General Public License version 2'.
 *	
 *	Ce programme est distribue sans aucunes garanties, y compris d'utilite 
 *	ni de risques encouru, quelle que soit son utilisation.
 *
 *	lire le fichier licence.txt fourni ou bien ecrire a :
 *	the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *	pour recevoir une copie de la licence.
 *
 *	Copyright (C) 1997 - 1998 Nicolas Witczak <witczak@geocities.com>
 */

#include "Config.h"

#include "DasmCode.h"
#include <algorithm>
#include <cassert>



////////////////////////////////////////////////////////////////////////
// definition des constantes

#include "DasmCte.h"

#define pAllBanksEnd ( pAllBanks + ( sizeof( pAllBanks ) / sizeof(SBank) ) )

	
/** indique si un ensemble d'instructions est disponible*/
bool IsBank( const char* pszBankName ) 
{
	SBank* pCur ; 
	for( pCur = pAllBanks ; pCur != pAllBanksEnd  ; ++ pCur )
	{
		if( strcmp( pCur->m_pszName , pszBankName ) == 0 )
			break ;
	}
	return 	pCur != pAllBanksEnd ;
}
	
/** si bLoad == true : charge le group , le decharge sinon */
void LoadBank( const char* pszBankName , bool bLoad ) 
{
	SBank* pCur ; 
	for( pCur = pAllBanks ; pCur != pAllBanksEnd  ; ++ pCur )
	{
		if( strcmp( pCur->m_pszName , pszBankName ) == 0 )
			break ;
	}
	if( pCur != pAllBanksEnd )
		pCur->m_bIsDefault = bLoad ;
}

void InitBanks() 
{
	vector< SOPContext >* pBuff = new vector< SOPContext >() ;
	for( SBank* pCur = &(pAllBanks[0]) ; pCur != pAllBanksEnd  ; ++ pCur )
	{
		if( pCur->m_bIsDefault )
		{
			for( SOPContext* pCtx = pCur->m_pData ; pCtx->m_pszMask != 0  ; ++ pCtx )
				pBuff->push_back( *pCtx ) ;
		}
	}
	SOPContext nullCtx = { 0 , 0 , 0 } ; 
	pBuff->push_back( nullCtx ) ;
	pfnOPCodeMask = pBuff->begin();
}

////////////////////////////////////////////////////////////////////////
// class CDasmCode : desassemblage d'une portion de code

CDasmCode::CDasmCode( )
{
	m_mode32 = 1 ; // 32bit par defaut
}

void CDasmCode::Reset() 
{
	m_mode32 = 1 ;
}

bool CDasmCode::ScanNext( ) 
{
	bool bSuccess ;
	if( ! ScanPrefix() )
		return false ;
	m_iIP = GetExe()->ptr2va( m_pvPrefix ) ;
	m_OperandSize = ( ( m_mode32 ^ m_oprdSzOverd ) == 0 ) ? 2 : 3 ;
	m_AdresseSize = ( ( m_mode32 ^ m_adrSzOverd ) == 0 )  ? 2 : 3 ;
	if( GetExe()->m_arRelocSymbols.find( &CSymbol( m_iIP ) ) 
		!= GetExe()->m_arRelocSymbols.end() )
		return false ; // reloc en debut d'instr impossible
	bSuccess = ScanOPCode( ) ;
	if( bSuccess )
		m_iIP = GetExe()->ptr2va( m_pvCur ) ;
	return bSuccess  ;
}

bool CDasmCode::ScanPrefix() 
{
	int iNumPrefix = 0 ; 
	m_segPrefix = 0xff ;
	m_repPrefix = 0 ;
	m_oprdSzOverd = 0 ;
	m_adrSzOverd = 0 ;
	while( true )
	{
		if( iNumPrefix > 4 )	// - de 4 prefix
			return false; 
		switch( *m_pvCur )
		{
			case cteLockPrefix :
			case cteRepNENZPrefix :
			case cteRepPrefix :	
				m_repPrefix = *m_pvCur ;
				m_pvCur ++ ;
				iNumPrefix ++ ; 
				break ;
			case cteCSSRegPrefix : 
				m_segPrefix = 0x01 ;
				m_pvCur ++ ;
				iNumPrefix ++ ; 
				break ;
			case cteSSSRegPrefix : 
				m_segPrefix = 0x02 ;
				m_pvCur ++ ;
				iNumPrefix ++ ; 
				break ;
			case cteDSSRegPrefix : 
				m_segPrefix = 0x03 ;
				m_pvCur ++ ;
				iNumPrefix ++ ; 
				break ;
			case cteESSRegPrefix : 
				m_segPrefix = 0x00 ;
				m_pvCur ++ ;
				iNumPrefix ++ ; 
				break ;
			case cteFSSRegPrefix : 
				m_segPrefix = 0x04 ;
				m_pvCur ++ ;
				iNumPrefix ++ ; 
				break ;
			case cteGSSRegPrefix : 
				m_segPrefix = 0x05 ;
				m_pvCur ++ ;
				iNumPrefix ++ ; 
				break ;
			case cteOpSzOvrPrefix :
				m_oprdSzOverd = 1 ;
				m_pvCur ++ ;
				iNumPrefix ++ ;
				break ;
			case cteAdrSZOvrPrefix :
				m_adrSzOverd = 1 ;
				m_pvCur ++ ;
				iNumPrefix ++ ;
				break ; 
			default : //plus de prefixes
				m_pvPrefix = m_pvCur ;
				return true;
		}
	}
}

void CDasmCode::SortInstr() 
{
	static int iInstrCount = 0 ; // sert de ref pour la reorganisation du tableau pfnOPCodeMask
	static SOPContext* pEnd = 0 ; // pointe juste apres la fin du tableau pfnOPCodeMask
	
	++ iInstrCount ;
	if( iInstrCount >= 1024 )
	{
		iInstrCount = 0 ;
		if( pEnd == 0 ) 
		{	// initialise cette variable 1 fois
			for( pEnd = pfnOPCodeMask ; pEnd->m_pszMask != 0  ; ++ pEnd )	/*vide*/ ;
		}
		sort( pfnOPCodeMask , pEnd ) ;
	}
}

bool CDasmCode::ScanOPCode(  )
{
	for( SOPContext* pfnHandlerCur = pfnOPCodeMask ; pfnHandlerCur->m_pszMask != 0 ; pfnHandlerCur ++ )
	{
		if( ProcessMask( pfnHandlerCur->m_pszMask ) )
		{
			m_pszFormat = pfnHandlerCur->m_pszCodeOP ;
			++ ( pfnHandlerCur->m_iStat ) ; // mise a jour des stat d'utilisation
			SortInstr() ;
			return true ;
		}
		else
		{
			m_pvCur = m_pvPrefix ;
			continue ; // non reconnu	: on passe au masque suivant
		}
	}
	return false;	// aucunes instructions reconnues
}

bool CDasmCode::ProcessMask( const char* pszMask )
{
	BYTE  bBytePtr = 8 ; // position ds l'octet
	char_buff* ppszCurOprd = m_pszOperand ;
	DWORD dwData ;
	DWORD vaRef ;
	BYTE  cCur ;
	m_sFlag = false ;
	m_dFlag = false ;
	m_mmxPack = 0xff ;
while(true)	
	switch( cCur = *pszMask++ )
	{
	case '\0' : 
		return true ;
	case ' ' : continue ;
	case ':' :
		bBytePtr = 8 ;
		++ m_pvCur ;
		continue ;
	case '0' :
	case '1' :		
		if( ( ( cCur - '0' ) ^ ( ( (*m_pvCur) >> --bBytePtr ) & 1 ) ) != 0 )
			return false ;
		continue ;
	case 's' :
		m_sFlag = ( ( ( (*m_pvCur) >> --bBytePtr ) & 1 ) == 1 ) ? true : false ;
		continue ;	
	case 'd' :
		m_dFlag = ( ( ( (*m_pvCur) >> --bBytePtr ) & 1 ) == 1 ) ? true : false ;
		continue ;	
	case 'w' :
		if( ( ( (*m_pvCur) >> --bBytePtr ) & 1 ) == 0 )
			m_OperandSize = 1 ; // 8 bits
		continue ;	
	case 't' :	// condition flags
		bBytePtr -= 4 ;
		m_tttnFlag = ((*m_pvCur) >> bBytePtr ) & 15 ;
		pszMask += 3 ;
		continue ;
	case 'm' :	// mod
		ByteSplit3( *m_pvCur , m_Mod , m_regOpCode , m_RM ) ;
		bBytePtr = 8 - 2 ;
		pszMask += 2 ;
		continue ;
	case 'r' :	// rm (inclue le terminateur d'octet : )
		++m_pvCur ;
		if( ! ModMProcess( *ppszCurOprd++ ) )
			return false;
		bBytePtr = 8 ;
		++ pszMask ;
		continue;
	case '2' :	// 2sg
		bBytePtr -= 2 ;
		strcpy( *ppszCurOprd++ , cteSegReg[ ((*m_pvCur) >> bBytePtr ) & 3 ] ) ;		
		pszMask += 2 ;
		continue ;
	case '3' :  // 3sg
		bBytePtr -= 3 ;
		strcpy( *ppszCurOprd++ , cteSegReg[ ((*m_pvCur) >> bBytePtr ) & 7 ] ) ;		
		pszMask += 2 ;
		continue ;
	case 'x':	// registre mmx
		bBytePtr -= 3 ;
		strcpy( *ppszCurOprd++ , cteMmxReg[ ((*m_pvCur) >> bBytePtr ) & 7 ] ) ;		
		pszMask += 2 ;		
		continue ;
	case 'f':	// registre fpu
		bBytePtr -= 3 ;
		strcpy( *ppszCurOprd++ , cteFpuReg[ ((*m_pvCur) >> bBytePtr ) & 7 ] ) ;		
		pszMask += 2 ;		
		continue ;
	case 'p':	// empacketage mmx
		bBytePtr -= 2 ;
		m_mmxPack = ((*m_pvCur) >> bBytePtr ) & 3 ;
		pszMask += 1 ;		
		continue ;
	case 'g' :	// grg
		bBytePtr -= 3 ;
		if( pszMask[0] == 'r' )
			strcpy( *ppszCurOprd , cteGenReg[m_OperandSize][ ((*m_pvCur) >> bBytePtr ) & 7 ] ) ;
		else if( pszMask[0] == '0')
			strcpy( *ppszCurOprd , cteGenReg[1][ ((*m_pvCur) >> bBytePtr ) & 7 ] ) ;
		else if( pszMask[0] == '1' )
			strcpy( *ppszCurOprd , cteGenReg[2][ ((*m_pvCur) >> bBytePtr ) & 7 ] ) ;
		else
		{
			strcpy( *ppszCurOprd , cteGenReg[3][ ((*m_pvCur) >> bBytePtr ) & 7 ] ) ;
			assert( pszMask[0] == '3' );
		}
		ppszCurOprd++ ;
		pszMask += 2 ;	
		continue ;
	case '_' :	// control debug reg
		bBytePtr -= 3 ;
		if( *pszMask == 'c' )
		{
			if( cteCtrlReg[ ((*m_pvCur) >> bBytePtr ) & 7 ] == 0 )
				return false ;
			else
				strcpy( *ppszCurOprd++ , cteCtrlReg[ ((*m_pvCur) >> bBytePtr ) & 7 ] ) ;
		}
		else if( *pszMask == 'd' )
		{
			if( cteDebReg[ ((*m_pvCur) >> bBytePtr ) & 7 ] == 0 )
				return false ;
			else
				strcpy( *ppszCurOprd++ , cteDebReg[ ((*m_pvCur) >> bBytePtr ) & 7 ] ) ;
		}
		else 
			assert(0) ;
		pszMask += 2 ;	
		continue ;
	case 'e' :	// eax
		strcpy( *ppszCurOprd++ , cteGenReg[m_OperandSize][0] ) ;
		pszMask += 2 ;
		continue ;
	case 'o' :		// operand /adress size override
	case 'n' :
		pszMask += 2 ;
		if( pszMask[-2] == 'o')
		{
			if( ( m_oprdSzOverd ^ ( pszMask[-3] == 'n') )== 0 )
				return false ;
		}

⌨️ 快捷键说明

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