📄 dasmcode.cpp
字号:
/* 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 + -