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

📄 exerep.cpp

📁 win32 exe程序反汇编
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*		fichier exeRep.cpp : fichier implementation
 *
 *	descr : classe qui represente un binaire
 *
 *	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 <algorithm>
#include <cassert>

#include "ExeRep.h"
#include "DasmBase.h"



//////////////////////////////////////////////////////////////////
// implementation class CSection 

CSection::CSection( int idSection )
	: m_idSection( idSection ) 
{
	m_pHeader = GetExe()->m_arSectHeader[ idSection ] ; 
	m_pRawData = GetExe()->rva2ptr( m_pHeader->VirtualAddress );
	m_pImageDir = 0 ;
}

// information
unsigned int CSection::size()				
{ return RoundUp( max ( m_pHeader->SizeOfRawData , m_pHeader->Misc.VirtualSize ), 4096 ) ;}
	
unsigned int CSection::init_size()		
{	return m_pHeader->Misc.VirtualSize ; } ;

BYTE* CSection::begin()		
{	return m_pRawData ; }; 

BYTE* CSection::end()			
{	return m_pRawData + size() ; };

BYTE* CSection::init_end()	
{	return m_pRawData + init_size() ; };

unsigned int CSection::va_begin()	
{	return GetExe()->rva2va( m_pHeader->VirtualAddress ) ; };

unsigned int CSection::va_end()	
{	return GetExe()->rva2va( m_pHeader->VirtualAddress ) + size() ; };

unsigned int CSection::va_init_end()
{	return GetExe()->rva2va( m_pHeader->VirtualAddress ) + init_size() ; };

DWORD CSection::GetFlags()
{
	return m_pHeader->Characteristics ;
}

bool CSection::IsCode()
{
	return (( GetFlags() & IMAGE_SCN_CNT_CODE ) != 0 ) 
		|| (( GetFlags() & IMAGE_SCN_MEM_EXECUTE ) != 0 ) ;
}

bool CSection::IsData()
{
	bool bRet = ( GetFlags() & (IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_CNT_INITIALIZED_DATA ) ) != 0 ;	
	bRet &= ( ( GetFlags() & IMAGE_SCN_LNK_NRELOC_OVFL ) == 0 ) ;
	bRet &= ( ( GetFlags() & IMAGE_SCN_MEM_DISCARDABLE ) == 0 ) ;
	bRet &=	( strcmp( (const char*)&(m_pHeader->Name[0]) ,".rsrc") != 0 );
	bRet &=	( strcmp( (const char*)&(m_pHeader->Name[0]) ,".reloc") != 0 );
	return bRet ;
}

//////////////////////////////////////////////////////////////////
// implementation class CExeRep 
/** singleton exe */
CExeRep	m_theExe ;

	//////////////////////////////////////////////////////////////
	// initialisation

CExeRep::CExeRep()
{}

CExeRep::~CExeRep()
{
	for( int idSection = 0 ; idSection < m_arRawSections.size() ; idSection ++)
	{
		delete m_arRawSections[ idSection ] ;	
	}
	CSymbolColl::iterator iter ;
	for( iter = m_arSymbols.begin() ;iter != m_arSymbols.end(); iter ++)
		delete *iter ;	
}

void CExeRep::SetFileName( const char* pszFileIn , const char* pszFileOut )
{
	int iTmpIdx ;

	if( strchr( pszFileIn , PATH_SEP ) != 0 )
	{
		const char* pTmpStr = strrchr( pszFileIn , PATH_SEP ) ;
		iTmpIdx = pTmpStr - pszFileIn ;
		m_strPath = string( pszFileIn , iTmpIdx ) ;
		++ pTmpStr ;
		iTmpIdx = strrchr( pszFileIn , '.' ) -  pTmpStr ;
		m_strBaseName = string( pTmpStr , strrchr( pszFileIn , '.' ) ) ;
	}
	else
	{
		char pszTmp[128] ;
		GetCurrentDirectory( 127 , pszTmp );
		m_strPath = pszTmp ;
		if( strchr( pszFileIn , '.' ) != 0 )
		{
			iTmpIdx = strrchr( pszFileIn , '.' ) - pszFileIn ;
			m_strBaseName = string( pszFileIn , iTmpIdx ) ;
		}
		else
			m_strBaseName = pszFileIn ;
	}
	if( pszFileOut != 0 )
		m_strOutput = pszFileOut ;
	else 
		m_strOutput = string( m_strBaseName + string(".asm") ).c_str() ;

}

void CExeRep::ProcessExe( const char* pszFileIn , const char* pszFileOut )
{
	SetFileName( pszFileIn , pszFileOut );
	if( LoadBin( pszFileIn ) )
	{
		CDasm* pDasm = CreateCDasm() ;		
		if( !HasReloc() ) // test si manque relocations
			printf( "warning : missing relocation info , disassembly source may be inaccurate\n") ;
		printf( "Collecting directory entry symbols\n" ) ;
		AddDirEntrySymb() ;
		AddDllSymb() ;		
		AddRelocSymb() ;
		AddExportSymb() ;
		AddEntryPoint() ;

// boucle sections	desassemblage passe d'analyse
		vector< CSection* >::iterator iterSect  ;		
		for( int iDasmStep = 1 ; iDasmStep < m_iPassNum ; ++ iDasmStep )
		{
			printf( "Desassembling pass %i\n" , iDasmStep ) ;		

			for( iterSect = m_arRawSections.begin() + 1 ; iterSect != m_arRawSections.end() ; ++ iterSect )
			{
				if( (*iterSect)->IsCode() || (*iterSect)->IsData() )
				{
					pDasm->SetWindow( *iterSect ) ;
					pDasm->Run( ctePassScan ) ;
				}
			}
		}

		FILE* pOutFile = fopen( m_strOutput.c_str() ,"wb") ;
		pDasm->SetFile( pOutFile ) ;
		OutputMainHeader( pOutFile ) ;

// boucle sections	desassemblage pass de sortie asm
		printf( "Desassembling pass %i \n" ,m_iPassNum ) ;
		for( iterSect = m_arRawSections.begin() + 1  ; iterSect != m_arRawSections.end() ; ++ iterSect )
		{
			if( (*iterSect)->IsCode() || (*iterSect)->IsData() )
			{	
				pDasm->SetWindow( *iterSect ) ;
				OutputSectionHeader( *iterSect , pOutFile );
				pDasm->Run( ctePassEcho ) ;
			}
		}
		fprintf( pOutFile , "\nend\n" );
		delete pDasm ;
		fclose( pOutFile ) ;
	}
}

bool CExeRep::LoadBin( const char* pszName ) 
{
	BYTE* pFilePtr ;
	DWORD iFileSize = GetImageSize( pszName ) ;
	if( iFileSize == 0 )
		return false ;
// ouverture fichier et allocation
	FILE* 	pFile = fopen( pszName , "rb" ) ;
	if( pFile == 0 )
	{
		printf( "error: unable to open file : %s \n" , pszName ) ;
		return false ;
	}
	m_pRawData = (BYTE*)VirtualAlloc( 0 , iFileSize , MEM_COMMIT , PAGE_READWRITE ) ;
	pFilePtr = m_pRawData ;
	if( m_pRawData == 0 )
	{
		printf( "error: unable to allocate memory\n") ;		
		return false ;
	}

// lecture headers
	m_pDosHeader = (_IMAGE_DOS_HEADER*) pFilePtr ;
	fread( m_pDosHeader , sizeof( _IMAGE_DOS_HEADER ) , 1 , pFile );
	fseek( pFile , m_pDosHeader->e_lfanew , SEEK_SET ) ;	
	pFilePtr += m_pDosHeader->e_lfanew ;
	fread( pFilePtr , 4 , 1 , pFile ) ;
	m_dwNTSign =  *((DWORD*)pFilePtr) ;
	pFilePtr += 4 ;
	m_pNTHeader = (_IMAGE_FILE_HEADER*)( pFilePtr ) ;
	fread( m_pNTHeader , sizeof(_IMAGE_FILE_HEADER) , 1 , pFile ) ;	
	pFilePtr += sizeof( _IMAGE_FILE_HEADER ) ;
	m_pNTOptHeader = (IMAGE_OPTIONAL_HEADER*)( pFilePtr ) ;
	fread( m_pNTOptHeader , sizeof( IMAGE_OPTIONAL_HEADER ) , 1 , pFile ) ;
	pFilePtr += sizeof( IMAGE_OPTIONAL_HEADER ) ;
	if( m_pNTHeader->SizeOfOptionalHeader > sizeof( IMAGE_OPTIONAL_HEADER ) )// avance vers la table des sections
	{
		fseek( pFile , m_pNTHeader->SizeOfOptionalHeader - sizeof( IMAGE_OPTIONAL_HEADER ) , SEEK_CUR ) ;	
		pFilePtr += m_pNTHeader->SizeOfOptionalHeader - sizeof( IMAGE_OPTIONAL_HEADER ) ;	
	}

	m_vaOffset = reinterpret_cast<unsigned int>( m_pRawData ) - m_pNTOptHeader->ImageBase ;

// verifications
	if( m_dwNTSign != IMAGE_NT_SIGNATURE )
		printf( "warning : bad NT image signature\n" ) ;
	if( m_pNTHeader->Machine != IMAGE_FILE_MACHINE_I386 )
	{
		printf( "error: unsupported processor\n");
		return false ;
	}
	if( ( ( m_pNTHeader->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE ) == 0 ) 
		|| ( m_pNTHeader->SizeOfOptionalHeader == 0 ) )
	{
		printf( "error: obj or lib files unsupported\n" );
		return false ;	
	}
	
	m_arSectHeader.resize( m_pNTHeader->NumberOfSections + 1 ) ;
	
	// on considere le header comme une section ( des RVA utiles pointent dessus )	
	IMAGE_SECTION_HEADER* pHeaderSect = new IMAGE_SECTION_HEADER ;
	memset( pHeaderSect , 0 , sizeof(IMAGE_SECTION_HEADER) ) ;
	strcpy( (char*)pHeaderSect->Name , "header" ) ;
	pHeaderSect->SizeOfRawData = m_pNTOptHeader->SizeOfHeaders ;
	pHeaderSect->Misc.VirtualSize = m_pNTOptHeader->SizeOfHeaders ;
	pHeaderSect->VirtualAddress = m_pNTOptHeader->ImageBase ;
	m_arSectHeader[0] = pHeaderSect ;
	for( int idSect = 1 ; idSect < m_arSectHeader.size() ; idSect ++ )
	{
		m_arSectHeader[ idSect ] = (IMAGE_SECTION_HEADER*)pFilePtr ;		
		fread( m_arSectHeader[ idSect ] , sizeof( IMAGE_SECTION_HEADER ) , 1 , pFile ) ;
		pFilePtr += sizeof( IMAGE_SECTION_HEADER ) ;
	}
// lecture sections
	m_arRawSections.resize( m_arSectHeader.size() );
	for( idSect = 0 ; idSect < m_arSectHeader.size() ; idSect ++ )
	{
		m_arRawSections[idSect] = new CSection( idSect ) ;
		fseek( pFile , m_arSectHeader[ idSect ]->PointerToRawData , SEEK_SET ) ;
		fread( m_arRawSections[idSect]->begin() , m_arSectHeader[ idSect ]->SizeOfRawData , 1 , pFile ) ;		
	}
	DWORD dwTmp ; VirtualProtect( m_pRawData ,m_pNTOptHeader->SizeOfImage , PAGE_READONLY , &dwTmp ) ;
	fclose( pFile );
	return true;
}

bool CExeRep::ScanConfFile( FILE* pFile )
{
	char_buff pszTmpBuff ;
	char* pszCur ;
	unsigned int iAdr = 0 ;
	unsigned int  iType ;
	for( int iLine = 0 ; fgets( pszTmpBuff , sizeof(pszTmpBuff) - 1 , pFile ) != 0 ; ++ iLine )
	{
		if( pszTmpBuff[0] == '#' || pszTmpBuff[0] == '\n' )
			continue ;
		
		pszCur = strtok( pszTmpBuff , " \t,") ;
		if( ( pszCur == 0 ) 
			|| ( sscanf( pszCur , "%x" , &iAdr ) == EOF )
			|| ( iAdr  == 0 )
			|| ( ( pszCur = strtok( 0 , " \t\r\n,") ) == 0 ) )
		{
			printf("config file error line %i \n" , iLine  ) ;
			return false ;
		}
		if( stricmp( pszCur , "data") == 0 )
			iType = cSymData | fSymUser ;
		else if( stricmp( pszCur , "funct") == 0 )
			iType = cSymFunc | fSymUser  ;
		else if( stricmp( pszCur , "ptr") == 0 )
			iType = cSymDataPtr | fSymUser ;
		else
		{
			printf("config file error line %i : %s bad symbol type \n" , iLine , pszCur ) ;
			return false ;
		}
		pszCur = strtok( 0 , " \r\n\t,") ;
		CSymbol* pSymbol = new CSymbol( iAdr , iType , pszCur ) ;
		m_arSymbols.insert( pSymbol ) ;
	}
	return true ;
}


void CExeRep::AddDirEntrySymb() 
{
	for( int idDirTable = 0 ; idDirTable < IMAGE_NUMBEROF_DIRECTORY_ENTRIES ; idDirTable ++ )
	{
		if( m_pNTOptHeader->DataDirectory[ idDirTable ].Size > 0 )
		{
			CSection* pOwner = GetSectFromVA( rva2va( m_pNTOptHeader->DataDirectory[ idDirTable ].VirtualAddress)  ) ;
			if( pOwner != 0 )
				pOwner->m_pImageDir = &(m_pNTOptHeader->DataDirectory[ idDirTable ]) ;
		}
	}
}

void CExeRep::AddDllSymb()
{
	static char_buff pszTmp ; 
// creation fichier include pour les import de dll
	FILE* pOutFile = fopen( "dllImport.inc" ,"wb") ;	
	fprintf(pOutFile,"%s%s\n" , cteHeaderSep , cteHeaderStLine ) ;
	fprintf(pOutFile,
		"%s	 PEDasm generated dll import file for file: %s.asm \n" 
		,cteHeaderStLine, m_strBaseName.c_str() );	
	fprintf( pOutFile, "%s\n%s\n%s\n\n" , cteHeaderStLine,cteHeaderStLine,cteHeaderStLine);

	IMAGE_IMPORT_DESCRIPTOR* pImpDllTable = (IMAGE_IMPORT_DESCRIPTOR*)rva2ptr(
		m_pNTOptHeader->DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ].VirtualAddress ) ;
	for( ; ( pImpDllTable != 0 ) && ( pImpDllTable->Name != 0 ) ; pImpDllTable ++ )
	{	// iteration sur les dll
		DWORD	curFunVA = (DWORD)pImpDllTable->FirstThunk + m_pNTOptHeader->ImageBase ;
		DWORD*	pRVANameArray ;
		const char* pszDllName = (const char*)rva2ptr( pImpDllTable->Name ) ;
		const char* pFunName ;
	// chargement de la dll
		if( !LoadImpDll( pszDllName ) )
		{
			printf( "Unable to Load dll : %s , use listing option \n" , pszDllName ) ;
			exit(1) ;
		}
	// creation de fichier .def pour creer des import lib	
		sprintf( pszTmp ,"%s.def" , GetBaseName(pszDllName) ) ;
		FILE* pDefFile = fopen( pszTmp , "wb" ) ;
		fprintf(pDefFile,
	"LIBRARY %s\n\nDESCRIPTION 'import lib def file for use with LIB.EXE'\n\nEXPORTS\n", GetBaseName(pszDllName) ) ;

	// ajout d'une section ds le fichier include
		fprintf(pOutFile,"\n\n%s%s\n",ctePartSep , ctePartStLine ) ;
		fprintf(pOutFile,
			"%s	from dll : %s \n%s\n\n" , ctePartStLine , pszDllName , ctePartStLine );	
		
		if( pImpDllTable->Characteristics != 0 )
			pRVANameArray = (DWORD*)rva2ptr( pImpDllTable->Characteristics ) ;
		else
			pRVANameArray = (DWORD*)rva2ptr( (DWORD)pImpDllTable->FirstThunk ) ;
		do
		{	
			bool bHasName ;
			CSymbol* pDllImpSym ;
			// iteration sur les fonctions de la dll
			if( ( (*pRVANameArray ) & IMAGE_ORDINAL_FLAG ) != 0 )			
			{
				pFunName = GetNameFromOrd( pszDllName , (*pRVANameArray) & 0x0000ffff , &bHasName ) ;
				if( bHasName )
					fprintf( pDefFile , "\t%s\t@%i\n", pFunName , (*pRVANameArray) & 0x0000ffff);							
				else
					fprintf( pDefFile , "\t%s\t@%i\tNONAME\n",pFunName,(*pRVANameArray) & 0x0000ffff);			
			}
			else
			{
				pFunName = (const char*)&(((IMAGE_IMPORT_BY_NAME*)rva2ptr( *pRVANameArray ))->Name)[0] ;			
				fprintf( pDefFile , "\t%s\t@%i\n", pFunName , GetOrdFromName( pszDllName , pFunName ) );			
			}
			pDllImpSym = new CSymbol( curFunVA , cSymDllImp , pFunName ) ;
			m_arSymbols.insert( pDllImpSym );
			curFunVA += 4 ;
			pRVANameArray ++ ;
			fprintf(pOutFile , "%s" , pDllImpSym->GetDeclaration() ) ;		
		}
		while( *pRVANameArray != 0 ) ;
		fclose( pDefFile ) ;
	}
	fclose( pOutFile ) ;
}

void CExeRep::AddRelocSymb()
{
	BYTE* pRelocTable , *pRelocCur , *pRelocEnd ;
	pRelocTable = (BYTE*)rva2ptr( 

⌨️ 快捷键说明

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