home *** CD-ROM | disk | FTP | other *** search
/ Programming Win32 Under the API / ProgrammingWin32UnderTheApiPatVillani.iso / pedasm.zip / DasmCode.cpp < prev    next >
C/C++ Source or Header  |  1998-10-23  |  17KB  |  669 lines

  1. /*        fichier DasmCode.cpp : fichier implementation
  2.  *
  3.  *    descr : classe automate desassembleur
  4.  *    projet : PEDasm
  5.  *    
  6.  *    rq:
  7.  *    Ce programme est libre de droits. Il peut etre distribue et/ou modifie
  8.  *  selon les termes de la licence 'GNU General Public License version 2'.
  9.  *    
  10.  *    Ce programme est distribue sans aucunes garanties, y compris d'utilite 
  11.  *    ni de risques encouru, quelle que soit son utilisation.
  12.  *
  13.  *    lire le fichier licence.txt fourni ou bien ecrire a :
  14.  *    the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15.  *    pour recevoir une copie de la licence.
  16.  *
  17.  *    Copyright (C) 1997 - 1998 Nicolas Witczak <witczak@geocities.com>
  18.  */
  19.  
  20. #include "Config.h"
  21.  
  22. #include "DasmCode.h"
  23. #include <algorithm>
  24. #include <cassert>
  25.  
  26.  
  27.  
  28. ////////////////////////////////////////////////////////////////////////
  29. // definition des constantes
  30.  
  31. #include "DasmCte.h"
  32.  
  33. #define pAllBanksEnd ( pAllBanks + ( sizeof( pAllBanks ) / sizeof(SBank) ) )
  34.  
  35.     
  36. /** indique si un ensemble d'instructions est disponible*/
  37. bool IsBank( const char* pszBankName ) 
  38. {
  39.     SBank* pCur ; 
  40.     for( pCur = pAllBanks ; pCur != pAllBanksEnd  ; ++ pCur )
  41.     {
  42.         if( strcmp( pCur->m_pszName , pszBankName ) == 0 )
  43.             break ;
  44.     }
  45.     return     pCur != pAllBanksEnd ;
  46. }
  47.     
  48. /** si bLoad == true : charge le group , le decharge sinon */
  49. void LoadBank( const char* pszBankName , bool bLoad ) 
  50. {
  51.     SBank* pCur ; 
  52.     for( pCur = pAllBanks ; pCur != pAllBanksEnd  ; ++ pCur )
  53.     {
  54.         if( strcmp( pCur->m_pszName , pszBankName ) == 0 )
  55.             break ;
  56.     }
  57.     if( pCur != pAllBanksEnd )
  58.         pCur->m_bIsDefault = bLoad ;
  59. }
  60.  
  61. void InitBanks() 
  62. {
  63.     vector< SOPContext >* pBuff = new vector< SOPContext >() ;
  64.     for( SBank* pCur = &(pAllBanks[0]) ; pCur != pAllBanksEnd  ; ++ pCur )
  65.     {
  66.         if( pCur->m_bIsDefault )
  67.         {
  68.             for( SOPContext* pCtx = pCur->m_pData ; pCtx->m_pszMask != 0  ; ++ pCtx )
  69.                 pBuff->push_back( *pCtx ) ;
  70.         }
  71.     }
  72.     SOPContext nullCtx = { 0 , 0 , 0 } ; 
  73.     pBuff->push_back( nullCtx ) ;
  74.     pfnOPCodeMask = pBuff->begin();
  75. }
  76.  
  77. ////////////////////////////////////////////////////////////////////////
  78. // class CDasmCode : desassemblage d'une portion de code
  79.  
  80. CDasmCode::CDasmCode( )
  81. {
  82.     m_mode32 = 1 ; // 32bit par defaut
  83. }
  84.  
  85. void CDasmCode::Reset() 
  86. {
  87.     m_mode32 = 1 ;
  88. }
  89.  
  90. bool CDasmCode::ScanNext( ) 
  91. {
  92.     bool bSuccess ;
  93.     if( ! ScanPrefix() )
  94.         return false ;
  95.     m_iIP = GetExe()->ptr2va( m_pvPrefix ) ;
  96.     m_OperandSize = ( ( m_mode32 ^ m_oprdSzOverd ) == 0 ) ? 2 : 3 ;
  97.     m_AdresseSize = ( ( m_mode32 ^ m_adrSzOverd ) == 0 )  ? 2 : 3 ;
  98.     if( GetExe()->m_arRelocSymbols.find( &CSymbol( m_iIP ) ) 
  99.         != GetExe()->m_arRelocSymbols.end() )
  100.         return false ; // reloc en debut d'instr impossible
  101.     bSuccess = ScanOPCode( ) ;
  102.     if( bSuccess )
  103.         m_iIP = GetExe()->ptr2va( m_pvCur ) ;
  104.     return bSuccess  ;
  105. }
  106.  
  107. bool CDasmCode::ScanPrefix() 
  108. {
  109.     int iNumPrefix = 0 ; 
  110.     m_segPrefix = 0xff ;
  111.     m_repPrefix = 0 ;
  112.     m_oprdSzOverd = 0 ;
  113.     m_adrSzOverd = 0 ;
  114.     while( true )
  115.     {
  116.         if( iNumPrefix > 4 )    // - de 4 prefix
  117.             return false; 
  118.         switch( *m_pvCur )
  119.         {
  120.             case cteLockPrefix :
  121.             case cteRepNENZPrefix :
  122.             case cteRepPrefix :    
  123.                 m_repPrefix = *m_pvCur ;
  124.                 m_pvCur ++ ;
  125.                 iNumPrefix ++ ; 
  126.                 break ;
  127.             case cteCSSRegPrefix : 
  128.                 m_segPrefix = 0x01 ;
  129.                 m_pvCur ++ ;
  130.                 iNumPrefix ++ ; 
  131.                 break ;
  132.             case cteSSSRegPrefix : 
  133.                 m_segPrefix = 0x02 ;
  134.                 m_pvCur ++ ;
  135.                 iNumPrefix ++ ; 
  136.                 break ;
  137.             case cteDSSRegPrefix : 
  138.                 m_segPrefix = 0x03 ;
  139.                 m_pvCur ++ ;
  140.                 iNumPrefix ++ ; 
  141.                 break ;
  142.             case cteESSRegPrefix : 
  143.                 m_segPrefix = 0x00 ;
  144.                 m_pvCur ++ ;
  145.                 iNumPrefix ++ ; 
  146.                 break ;
  147.             case cteFSSRegPrefix : 
  148.                 m_segPrefix = 0x04 ;
  149.                 m_pvCur ++ ;
  150.                 iNumPrefix ++ ; 
  151.                 break ;
  152.             case cteGSSRegPrefix : 
  153.                 m_segPrefix = 0x05 ;
  154.                 m_pvCur ++ ;
  155.                 iNumPrefix ++ ; 
  156.                 break ;
  157.             case cteOpSzOvrPrefix :
  158.                 m_oprdSzOverd = 1 ;
  159.                 m_pvCur ++ ;
  160.                 iNumPrefix ++ ;
  161.                 break ;
  162.             case cteAdrSZOvrPrefix :
  163.                 m_adrSzOverd = 1 ;
  164.                 m_pvCur ++ ;
  165.                 iNumPrefix ++ ;
  166.                 break ; 
  167.             default : //plus de prefixes
  168.                 m_pvPrefix = m_pvCur ;
  169.                 return true;
  170.         }
  171.     }
  172. }
  173.  
  174. void CDasmCode::SortInstr() 
  175. {
  176.     static int iInstrCount = 0 ; // sert de ref pour la reorganisation du tableau pfnOPCodeMask
  177.     static SOPContext* pEnd = 0 ; // pointe juste apres la fin du tableau pfnOPCodeMask
  178.     
  179.     ++ iInstrCount ;
  180.     if( iInstrCount >= 1024 )
  181.     {
  182.         iInstrCount = 0 ;
  183.         if( pEnd == 0 ) 
  184.         {    // initialise cette variable 1 fois
  185.             for( pEnd = pfnOPCodeMask ; pEnd->m_pszMask != 0  ; ++ pEnd )    /*vide*/ ;
  186.         }
  187.         sort( pfnOPCodeMask , pEnd ) ;
  188.     }
  189. }
  190.  
  191. bool CDasmCode::ScanOPCode(  )
  192. {
  193.     for( SOPContext* pfnHandlerCur = pfnOPCodeMask ; pfnHandlerCur->m_pszMask != 0 ; pfnHandlerCur ++ )
  194.     {
  195.         if( ProcessMask( pfnHandlerCur->m_pszMask ) )
  196.         {
  197.             m_pszFormat = pfnHandlerCur->m_pszCodeOP ;
  198.             ++ ( pfnHandlerCur->m_iStat ) ; // mise a jour des stat d'utilisation
  199.             SortInstr() ;
  200.             return true ;
  201.         }
  202.         else
  203.         {
  204.             m_pvCur = m_pvPrefix ;
  205.             continue ; // non reconnu    : on passe au masque suivant
  206.         }
  207.     }
  208.     return false;    // aucunes instructions reconnues
  209. }
  210.  
  211. bool CDasmCode::ProcessMask( const char* pszMask )
  212. {
  213.     BYTE  bBytePtr = 8 ; // position ds l'octet
  214.     char_buff* ppszCurOprd = m_pszOperand ;
  215.     DWORD dwData ;
  216.     DWORD vaRef ;
  217.     BYTE  cCur ;
  218.     m_sFlag = false ;
  219.     m_dFlag = false ;
  220.     m_mmxPack = 0xff ;
  221. while(true)    
  222.     switch( cCur = *pszMask++ )
  223.     {
  224.     case '\0' : 
  225.         return true ;
  226.     case ' ' : continue ;
  227.     case ':' :
  228.         bBytePtr = 8 ;
  229.         ++ m_pvCur ;
  230.         continue ;
  231.     case '0' :
  232.     case '1' :        
  233.         if( ( ( cCur - '0' ) ^ ( ( (*m_pvCur) >> --bBytePtr ) & 1 ) ) != 0 )
  234.             return false ;
  235.         continue ;
  236.     case 's' :
  237.         m_sFlag = ( ( ( (*m_pvCur) >> --bBytePtr ) & 1 ) == 1 ) ? true : false ;
  238.         continue ;    
  239.     case 'd' :
  240.         m_dFlag = ( ( ( (*m_pvCur) >> --bBytePtr ) & 1 ) == 1 ) ? true : false ;
  241.         continue ;    
  242.     case 'w' :
  243.         if( ( ( (*m_pvCur) >> --bBytePtr ) & 1 ) == 0 )
  244.             m_OperandSize = 1 ; // 8 bits
  245.         continue ;    
  246.     case 't' :    // condition flags
  247.         bBytePtr -= 4 ;
  248.         m_tttnFlag = ((*m_pvCur) >> bBytePtr ) & 15 ;
  249.         pszMask += 3 ;
  250.         continue ;
  251.     case 'm' :    // mod
  252.         ByteSplit3( *m_pvCur , m_Mod , m_regOpCode , m_RM ) ;
  253.         bBytePtr = 8 - 2 ;
  254.         pszMask += 2 ;
  255.         continue ;
  256.     case 'r' :    // rm (inclue le terminateur d'octet : )
  257.         ++m_pvCur ;
  258.         if( ! ModMProcess( *ppszCurOprd++ ) )
  259.             return false;
  260.         bBytePtr = 8 ;
  261.         ++ pszMask ;
  262.         continue;
  263.     case '2' :    // 2sg
  264.         bBytePtr -= 2 ;
  265.         strcpy( *ppszCurOprd++ , cteSegReg[ ((*m_pvCur) >> bBytePtr ) & 3 ] ) ;        
  266.         pszMask += 2 ;
  267.         continue ;
  268.     case '3' :  // 3sg
  269.         bBytePtr -= 3 ;
  270.         strcpy( *ppszCurOprd++ , cteSegReg[ ((*m_pvCur) >> bBytePtr ) & 7 ] ) ;        
  271.         pszMask += 2 ;
  272.         continue ;
  273.     case 'x':    // registre mmx
  274.         bBytePtr -= 3 ;
  275.         strcpy( *ppszCurOprd++ , cteMmxReg[ ((*m_pvCur) >> bBytePtr ) & 7 ] ) ;        
  276.         pszMask += 2 ;        
  277.         continue ;
  278.     case 'f':    // registre fpu
  279.         bBytePtr -= 3 ;
  280.         strcpy( *ppszCurOprd++ , cteFpuReg[ ((*m_pvCur) >> bBytePtr ) & 7 ] ) ;        
  281.         pszMask += 2 ;        
  282.         continue ;
  283.     case 'p':    // empacketage mmx
  284.         bBytePtr -= 2 ;
  285.         m_mmxPack = ((*m_pvCur) >> bBytePtr ) & 3 ;
  286.         pszMask += 1 ;        
  287.         continue ;
  288.     case 'g' :    // grg
  289.         bBytePtr -= 3 ;
  290.         if( pszMask[0] == 'r' )
  291.             strcpy( *ppszCurOprd , cteGenReg[m_OperandSize][ ((*m_pvCur) >> bBytePtr ) & 7 ] ) ;
  292.         else if( pszMask[0] == '0')
  293.             strcpy( *ppszCurOprd , cteGenReg[1][ ((*m_pvCur) >> bBytePtr ) & 7 ] ) ;
  294.         else if( pszMask[0] == '1' )
  295.             strcpy( *ppszCurOprd , cteGenReg[2][ ((*m_pvCur) >> bBytePtr ) & 7 ] ) ;
  296.         else
  297.         {
  298.             strcpy( *ppszCurOprd , cteGenReg[3][ ((*m_pvCur) >> bBytePtr ) & 7 ] ) ;
  299.             assert( pszMask[0] == '3' );
  300.         }
  301.         ppszCurOprd++ ;
  302.         pszMask += 2 ;    
  303.         continue ;
  304.     case '_' :    // control debug reg
  305.         bBytePtr -= 3 ;
  306.         if( *pszMask == 'c' )
  307.         {
  308.             if( cteCtrlReg[ ((*m_pvCur) >> bBytePtr ) & 7 ] == 0 )
  309.                 return false ;
  310.             else
  311.                 strcpy( *ppszCurOprd++ , cteCtrlReg[ ((*m_pvCur) >> bBytePtr ) & 7 ] ) ;
  312.         }
  313.         else if( *pszMask == 'd' )
  314.         {
  315.             if( cteDebReg[ ((*m_pvCur) >> bBytePtr ) & 7 ] == 0 )
  316.                 return false ;
  317.             else
  318.                 strcpy( *ppszCurOprd++ , cteDebReg[ ((*m_pvCur) >> bBytePtr ) & 7 ] ) ;
  319.         }
  320.         else 
  321.             assert(0) ;
  322.         pszMask += 2 ;    
  323.         continue ;
  324.     case 'e' :    // eax
  325.         strcpy( *ppszCurOprd++ , cteGenReg[m_OperandSize][0] ) ;
  326.         pszMask += 2 ;
  327.         continue ;
  328.     case 'o' :        // operand /adress size override
  329.     case 'n' :
  330.         pszMask += 2 ;
  331.         if( pszMask[-2] == 'o')
  332.         {
  333.             if( ( m_oprdSzOverd ^ ( pszMask[-3] == 'n') )== 0 )
  334.                 return false ;
  335.         }
  336.         else if( pszMask[-2] == 'a' )
  337.         {
  338.             if( ( m_adrSzOverd ^ ( pszMask[-3] == 'n') ) == 0 )
  339.                 return false ;
  340.         }
  341.         else
  342.             assert(0) ;
  343.         continue ;
  344.     case 'j' :    // jmp
  345.     case 'c' :
  346.         if( pszMask[1] == '8' )
  347.         {
  348.             dwData = (signed int)*(signed char*)m_pvCur ;
  349.             dwData += GetExe()->ptr2va( m_pvCur ) + 1; // rel a l'instr suivante
  350.             if( m_iPass == ctePassScan )
  351.                 GetExe()->AddSymbol( dwData ,0,true , cSymJmp ) ;
  352.             m_pvCur ++ ;
  353.         }
  354.         else    // == 32
  355.         {
  356.             dwData = *(DWORD*)m_pvCur ;
  357.             dwData += GetExe()->ptr2va( m_pvCur ) + 4 ; // rel a l'instr suivante
  358.             if( m_iPass == ctePassScan )
  359.             {
  360.                 if( cCur == 'j' )
  361.                     GetExe()->AddSymbol( dwData ,0,true , cSymJmp ) ;
  362.                 else
  363.                     GetExe()->AddSymbol( dwData ,0,true , cSymFunc ) ;
  364.             }
  365.             m_pvCur += 4 ;
  366.         }
  367.         if( m_iPass == ctePassEcho )
  368.             strcpy( *ppszCurOprd++ , GetExe()->GetSymbName( dwData , 0 , true , 0 ) ) ;
  369.         pszMask += 2 ;
  370.         bBytePtr = 8 ;
  371.         continue ;
  372.     case 'a' :
  373.     case 'i' : // donnees ou adresse 
  374.         BYTE bSize ;
  375.         bool bAdress ;
  376.         bool sFlag ;
  377.         vaRef = GetExe()->ptr2va( m_pvCur ) ;
  378.         bAdress = ( cCur == 'a' ) ;
  379.         if( pszMask[1] == '0' )    // determination par context
  380.         {
  381.             sFlag = m_sFlag ;
  382.             bSize = m_OperandSize ;
  383.         }
  384.         else
  385.         {
  386.             sFlag = ( pszMask[0] == 's' ) ;
  387.             if( pszMask[1] == '8'  )
  388.                 bSize = 1 ; 
  389.             else if( pszMask[1] == '6' )
  390.                 bSize = 2 ; 
  391.             else
  392.                 bSize = 3 ; 
  393.         };
  394.         if(sFlag)
  395.         {
  396.             dwData = (signed int)*(signed char*)m_pvCur ;
  397.             m_pvCur ++ ;
  398.             if( m_iPass == ctePassEcho )
  399.                 strcpy( *ppszCurOprd , GetExe()->GetValue(dwData ,0 ) ) ;
  400.         }
  401.         else if( bSize == 1 )
  402.         {
  403.  
  404.             dwData = *m_pvCur ;    
  405.             m_pvCur ++ ;
  406.             if( m_iPass == ctePassEcho )
  407.                 strcpy( *ppszCurOprd , GetExe()->GetValue(dwData , 0 ) ) ;
  408.         }
  409.         else if( bSize == 2 )    
  410.         {
  411.             dwData = *(WORD*)m_pvCur ;
  412.             m_pvCur += 2 ;
  413.             if( m_iPass == ctePassEcho )
  414.                 strcpy( *ppszCurOprd , GetExe()->GetValue(dwData, 0 ) ) ;
  415.         }
  416.         else
  417.         {
  418.             dwData = *(DWORD*)m_pvCur ;
  419.             if( ( m_iPass == ctePassScan ) && ( m_segPrefix == 0xff ) )
  420.                 GetExe()->AddSymbol( dwData ,vaRef,bAdress, cSymData );  // symbol ou constante ?
  421.             if( m_iPass == ctePassEcho )    
  422.             {
  423.                 if( bAdress )
  424.                 {
  425.                     if( m_segPrefix != 0xff )
  426.                         sprintf( *ppszCurOprd, "%s:[%s]" ,cteSegReg[m_segPrefix]
  427.                             ,GetExe()->GetValue( dwData , cteDecorate ) ) ;
  428.                     else
  429.                         strcpy( *ppszCurOprd 
  430.                         , GetExe()->GetSymbName( dwData , vaRef , true , cteDecorate ) ) ;                
  431.                 }
  432.                 else
  433.                     strcpy( *ppszCurOprd 
  434.                     , GetExe()->GetSymbName( dwData , vaRef , false , cteDecorate | cteDecOffset ) ) ;
  435.             }
  436.             ppszCurOprd ++ ;
  437.             m_pvCur += 4;
  438.         }
  439.         ++ ppszCurOprd ;
  440.         pszMask += 2 ;
  441.         bBytePtr = 8 ;
  442.         continue ;
  443.     default :
  444.         assert(0) ;
  445.     }
  446. }
  447.  
  448. void CDasmCode::PrintInstr(  )
  449. {
  450.     static char_buff pszTemp ;
  451.     char* pszOut = m_pszInstr ;
  452.     const char* pszCurFmt  ;
  453.     const char* pszCur ;
  454.     bool bPtrQualif = false;
  455.  
  456. // 1ere passe recuperation operandes
  457.     for( pszCurFmt = m_pszFormat ; *pszCurFmt != '\0'; pszCurFmt ++ )
  458.     {
  459.         if( *pszCurFmt == '%' )
  460.         {
  461.             pszCurFmt++ ;
  462.             switch( *pszCurFmt )
  463.             {
  464.                 case '0':
  465.                 case '1':
  466.                 case '2':
  467.                     if( bPtrQualif )
  468.                     {
  469.                         strcpy( pszTemp ,  m_pszOperand[ *pszCurFmt - '0']  );
  470.                         sprintf( m_pszOperand[ *pszCurFmt - '0'] ,"%s %s" , cteOperandQualif[ m_OperandSize ] , (const char*)pszTemp) ;
  471.                     }
  472.                     bPtrQualif = false ;
  473.                     break ;
  474.                 case 'p':
  475.                     bPtrQualif = true ;            
  476.                     break ;
  477.             }
  478.         }
  479.     }
  480. // inversion des operandes %0 et %1 si besoin
  481.     if( m_dFlag )                        
  482.     {    
  483.         strcpy( pszTemp , m_pszOperand[ 0 ] ) ;
  484.         strcpy( m_pszOperand[ 0 ] , m_pszOperand[ 1 ] ) ;
  485.         strcpy( m_pszOperand[ 1 ] , pszTemp ) ;
  486.     }
  487.  
  488. // 2eme passe emission du source
  489.     for(  pszCurFmt = m_pszFormat ; *pszCurFmt != '\0'; pszCurFmt ++ )
  490.     {
  491.         if( *pszCurFmt == '%' )
  492.         {
  493.             pszCurFmt++ ;
  494.             switch( *pszCurFmt )
  495.             {
  496.                 case '0':
  497.                 case '1':
  498.                 case '2':
  499.                     pszCur = m_pszOperand[ *pszCurFmt - '0'] ;
  500.                     for(  ; *pszCur != '\0' ; ++pszCur ) 
  501.                         *pszOut++ =    *pszCur    ;
  502.                     break ;
  503.                 case 'p':        
  504.                     break ;
  505.                 case 'c':
  506.                     for( pszCur = cteConditions[ m_tttnFlag ] ; *pszCur != '\0' ; ++pszCur ) 
  507.                         *pszOut++ =    *pszCur    ;
  508.                     break ;
  509.                 case 'g':
  510.                     for( pszCur = cteMmxPack[ m_mmxPack ] ; *pszCur != '\0' ; ++pszCur ) 
  511.                         *pszOut++ =    *pszCur    ;
  512.                     break ;
  513.                 case 'r':
  514.                     pszCurFmt++ ;
  515.                     if( m_repPrefix != 0 )
  516.                     {                        
  517.                         const char* pszPrefix = 0 ;
  518.                         if( *pszCurFmt == '_' )
  519.                             pszPrefix = cteRep[ m_repPrefix - 0xf0 ] ;
  520.                         else if(*pszCurFmt == 'z' )
  521.                             pszPrefix = cteRepZ[ m_repPrefix - 0xf0 ] ;
  522.                         else 
  523.                             assert(0);
  524.                         for( pszCur = pszPrefix ; *pszCur != '\0' ; ++pszCur ) 
  525.                             *pszOut++ =    *pszCur    ;
  526.  
  527.                     }
  528.                     break ;
  529.                 default:
  530.                     assert(0) ;
  531.             }
  532.         }
  533.         else
  534.             *pszOut++ = *pszCurFmt ;
  535.     }
  536.     *pszOut = '\0' ;
  537.     fprintf( m_pFileOut ,"\t%s", m_pszInstr ) ;
  538. }
  539.  
  540. //////////////////////////////////////////////////////////////////
  541. // fonctions d'aides
  542.  
  543. bool CDasmCode::ModMProcess( char* pszBuff )
  544. {
  545.     bool bRet = true ;
  546.     unsigned int uDisp , uVARef ;
  547.  
  548. // on exclue le mode registre : traite a part 
  549.     if( m_Mod ==0x03 )
  550.         return false ;
  551.     
  552.     char* pszIdx = pszBuff ;
  553.     uVARef = GetExe()->ptr2va( m_pvCur ) ;
  554.  
  555. // registre segment override
  556.     if( ( m_iPass == ctePassEcho ) && ( m_segPrefix != 0xff ) )
  557.     {
  558.         sprintf( pszIdx, "%s:" ,cteSegReg[m_segPrefix] ) ;
  559.         pszIdx = pszBuff + strlen( pszBuff ) ;
  560.     }
  561.  
  562. // utilisation du SIB    
  563.     if( m_RM == 0x04 )
  564.         return SIBProcess( pszIdx ) ;
  565.     else if( m_Mod == 0x00 )
  566.     {
  567.         if( m_RM == 0x05 )    // cas particulier [ variable ]
  568.         {
  569.             uDisp = *(DWORD*)m_pvCur ;
  570.             if( ( m_iPass == ctePassScan ) && ( m_segPrefix == 0xff ) )        
  571.                 GetExe()->AddSymbol( uDisp , 0 , true ,cSymData );
  572.             if( m_iPass == ctePassEcho )
  573.             {                    
  574.                 if( m_segPrefix != 0xff )
  575.                     sprintf( pszIdx ,"[%s]",GetExe()->GetValue( uDisp , cteDecorate ) ) ;
  576.                 else                    
  577.                     strcpy( pszIdx , GetExe()->GetSymbName(uDisp,0,true ,cteDecorate ) );
  578.             }
  579.             m_pvCur += 4 ;
  580.         }
  581.         else                // [reg]
  582.             if( m_iPass == ctePassEcho )
  583.                 sprintf( pszIdx , "[%s]" , cteGenReg[3][m_RM] ) ;
  584.     }
  585.     else if( m_Mod == 0x01 )
  586.     {        // disp8[reg]
  587.         uDisp = (signed int)(*((signed char*)m_pvCur++));
  588.         if( m_iPass == ctePassEcho )
  589.             sprintf( pszIdx , "[ %s %s ]" , cteGenReg[3][m_RM] 
  590.                 , GetExe()->GetValue( uDisp , cteFmtInteger | cteFmtSign ) ) ;
  591.     }
  592.     else 
  593.     {    // disp32[reg]
  594.         assert( m_Mod == 0x02 ) ;
  595.         uDisp = *(DWORD*)m_pvCur ;
  596.         if( m_iPass == ctePassScan )        
  597.             GetExe()->AddSymbol( uDisp , uVARef , false , cSymData ) ;
  598.         if( m_iPass == ctePassEcho )
  599.             sprintf( pszIdx , "[ %s + %s ]" , cteGenReg[3][m_RM] 
  600.             , GetExe()->GetSymbName(uDisp, uVARef , false , 0) ) ;
  601.         m_pvCur += 4 ;    
  602.     }
  603.     return bRet ;
  604. }
  605.  
  606. bool CDasmCode::SIBProcess( char* pszBuff )
  607. {
  608.     char* pszIdx = pszBuff ;
  609.     BYTE    Scale , Index , Base ;
  610.     unsigned int uDisp = 0 ;
  611.     ByteSplit3( *m_pvCur++ , Scale , Index , Base ) ;
  612.     unsigned int uVARef = GetExe()->ptr2va( m_pvCur ) ;
  613.  
  614. //base
  615.     if( ( Base == 0x05 ) && ( m_Mod == 0x00 ) )
  616.     {    // cas particulier : pas de registre de base
  617.         if( Index == 0x04 )    // pas d'index non plus -> quit
  618.             return false ;
  619.         if( m_iPass == ctePassEcho )
  620.             strcpy( pszIdx , "[ " );        
  621.     }
  622.     else if( m_iPass == ctePassEcho )
  623.     {
  624.         if(  Index == 4  )
  625.             sprintf( pszIdx , "[ %s" , cteGenReg[3][Base] ) ;
  626.         else
  627.             sprintf( pszIdx , "[ %s + " , cteGenReg[3][Base] ) ;
  628.     };
  629.     if( m_iPass == ctePassEcho )
  630.         pszIdx = pszBuff + strlen( pszBuff ) ;
  631.  
  632. // scale index        
  633.     if( ( Index != 4 ) && ( m_iPass == ctePassEcho ) )        //sinon pas d'index
  634.     {
  635.         if( Scale == 0 ) // pas d'echelle
  636.             sprintf( pszIdx , "%s" , cteGenReg[3][Index]);
  637.         else
  638.             sprintf( pszIdx , "%i * %s" , 1 << Scale , cteGenReg[3][Index] );
  639.     }
  640.     pszIdx = pszBuff + strlen( pszBuff ) ;
  641.  
  642. // offset 
  643.     if( m_Mod == 0x01 )                    // disp8
  644.         uDisp = (signed int)(*((signed char*)m_pvCur++)) ;
  645.     else if( ( m_Mod == 0x02 ) || ( ( Base == 0x05 ) && ( m_Mod == 0x00 )  )) //disp32
  646.     {
  647.         uDisp = *(DWORD*)m_pvCur ;
  648.         if( m_iPass == ctePassScan )    
  649.             GetExe()->AddSymbol( uDisp , uVARef , false , cSymData  );
  650.         m_pvCur += 4 ;
  651.     }
  652.     
  653.     if( m_iPass == ctePassEcho )
  654.     {
  655.         if( uDisp == 0 )
  656.             strcpy( pszIdx ," ]" ) ;
  657.         else if( ( m_Mod == 0x00 ) || ( m_Mod == 0x02 ) )    //disp32
  658.             sprintf( pszIdx , " + %s ]" , GetExe()->GetSymbName( uDisp , uVARef , false , 0 ) ) ;
  659.         else                                            // disp8
  660.             sprintf( pszIdx , " %s ]" , GetExe()->GetValue( uDisp , cteFmtInteger | cteFmtSign ) ) ;                
  661.     }        
  662.     return true ;
  663. }
  664.  
  665.  
  666. //////////////////////////////////////////////////////////////////
  667. // fonctions globales
  668.  
  669.