Exemple #1
0
bool z3ResEx::z3Decrypt
(
	TMemoryStream &src,
	TMemoryStream &dst,
	unsigned char *key,
	unsigned int keylen
)
{
	StringSource keyStr( key, keylen, true );
	
	AutoSeededRandomPool rng;
	ECIES<ECP>::Decryptor ellipticalEnc( keyStr );
	
	unsigned char *tmpBuffer( new unsigned char[ src.Size() ] );

	DecodingResult dr = ellipticalEnc.Decrypt( rng, src.Data(), src.Size(), tmpBuffer );
	
	if( !( dr.isValidCoding ) || ( dr.messageLength == 0 ) )
	{
		delete tmpBuffer;
		return false;
	}

	dst.Write( tmpBuffer, dr.messageLength );

	delete tmpBuffer;

	return true;
}
Exemple #2
0
bool z3ResEx::fsRle( TMemoryStream &src, TMemoryStream &dst, bool isMSF )
{
	unsigned int msfSizeFlag;
	unsigned int expectedSize, len;
	unsigned char *pData( src.Data() ), *pDataEnd( pData + src.Size() );

	if( isMSF )
	{
		// Read the expected size from data
		msfSizeFlag = src.ReadUInt();
		pData += 4;
	}

	if( !( z3Rle::decodeSize( pData, expectedSize, len ) ) )
	{
		dst.Close();
		//printf("ERROR: Problems decoding RLE buffer size\n");
		return false;
	}

	if( isMSF && !( msfSizeFlag == expectedSize ) )
	{
		dst.Close();
		//printf("ERROR: Unexpected MSF buffer size\n");
		return false;
	}

	// Skip the length of the expected size
	pData += len;

	unsigned char *tmpBuffer( new unsigned char[ expectedSize ] );
	unsigned int tmpOffset( 0 );

	while( tmpOffset < expectedSize )
	{
		if( !( z3Rle::decodeInstruction( pData, len, pDataEnd, tmpBuffer, tmpOffset ) ) )
		{
			delete tmpBuffer;
			//printf("ERROR: Problems decoding RLE buffer\n");

			return false;
		}

		pData += len;
	}

	dst.Write( tmpBuffer, expectedSize );

	delete tmpBuffer;

	return true;
}
Exemple #3
0
void z3ResEx::parseMsf( TMemoryStream &msf )
{
	switch( m_fileindexVer )
	{
		case 0 :
		{
			unsigned char method( 0 );
			FILEINDEX_ENTRY info;
			unsigned char *strMRFN( nullptr );
			unsigned char *strName( nullptr );

			unsigned int items( 0 ), errors( 0 );

			while( ( msf.Position() < msf.Size() ) && ( errors < MAX_ERRORS ) )
			{
				method = msf.ReadByte();
				msf.Read( &info, sizeof( FILEINDEX_ENTRY ) );

				unpackStringEx( msf, strMRFN, info.lenMRFN );
				unpackStringEx( msf, strName, info.lenName );

				if( m_listContents )
				{
					printf( "%s (%u bytes)\n", strName, info.size );
				}
				else
				{
					if( !( extractItem( info, method, (char *)strMRFN, (char *)strName ) ) )
						++errors;
				}

				++items;

				delete strMRFN;
				delete strName;
			}

			printf( "Processed %u items (%u issues)\n\n", items, errors );

			break;
		}
		case 1 :
		{
			parseMsfMethod2( msf );

			break;
		}		
	}
}
Exemple #4
0
bool z3ResEx::z3Decrypt
(
	TMemoryStream &src,
	TMemoryStream &dst,
	unsigned char *key,
	unsigned int keylen
)
{
	StringSource keyStr( key, keylen, true );
	
	AutoSeededRandomPool rng;
	ECIES<ECP>::Decryptor ellipticalEnc( keyStr );
	
  vector<unsigned char> tmpBuffer(src.Size());
	DecodingResult dr = ellipticalEnc.Decrypt( rng, src.Data(), src.Size(), &tmpBuffer[0] );
	
	if( dr.isValidCoding && dr.messageLength > 0 )
	{
    dst.Write(&tmpBuffer[0], dr.messageLength);
    return true;
	}

	return false;
}
Exemple #5
0
void z3ResEx::parseMsf( TMemoryStream &msf )
{
	switch( m_fileindexVer )
	{
		case 0 :
		{
			unsigned char method( 0 );
			FILEINDEX_ENTRY info;

      vector<unsigned char> strMRFN(MAX_STRING_SIZE);
      vector<unsigned char> strName(MAX_STRING_SIZE);

			unsigned int items( 0 ), errors( 0 );

			while( ( msf.Position() < msf.Size() ) && ( errors < MAX_ERRORS ) )
			{
				method = msf.ReadByte();
				msf.Read( &info, sizeof( FILEINDEX_ENTRY ) );

        unpackStringEx(msf, strMRFN, info.lenMRFN);
        unpackStringEx(msf, strName, info.lenName);

				if( m_listContents )
				{
					printf( "%s (%u bytes)\n", &strName[0], info.size );
				}
				else
				{
					if( !( extractItem( info, method, reinterpret_cast<const char*>(&strMRFN[0]), reinterpret_cast<const char*>(&strName[0]) ) ) )
						++errors;
				}

				++items;
			}

			printf( "Processed %u items (%u issues)\n\n", items, errors );

			break;
		}
		case 1 :
		{
			parseMsfMethod2( msf );

			break;
		}		
	}
}
Exemple #6
0
void z3ResEx::parseMsfMethod2( TMemoryStream &msf )
{
	unsigned short strLen( 0 );
	unsigned short mrfIndexLen( 0 );

	// Folders are now in a table at the top of the file
	msf.Read( &mrfIndexLen, sizeof( unsigned short ) );

  if (mrfIndexLen == 0)
  {
    // There are no folders in the filesystem
    return;
  }

	// List of filenames
  vector<string> vecMsf(mrfIndexLen);

  vector<unsigned char> strBuffer(MAX_STRING_SIZE);

	// MRF filenames are now packed in a list
	for( unsigned short i( 0 ); i != mrfIndexLen; ++i )
	{
		strLen = msf.ReadUShort();
		unpackStringEx( msf, strBuffer, strLen );

		// Required to rename files
		//vecMsf[i].first.assign( (char *)strBuffer );
		// Cached file opening (and a pointer so we can call the constructor)
		//vecMsf[i].second = new TFileStream( strBuffer );

    vecMsf[i] = string(strBuffer.begin(), strBuffer.end());
	}

	// Files are now listed (similar to before)
	FILEINDEX_ENTRY2 fiItem;

	unsigned int items( 0 ), errors( 0 );

	//msf.SaveToFile("debugFilesys.dat");

	bool bMatchesCriteria = true;
	string tmpFilename;

	while( ( msf.Position() < msf.Size() ) && ( errors < MAX_ERRORS ) )
	{
		msf.Read( &fiItem, sizeof( FILEINDEX_ENTRY2 ) );

		strLen = msf.ReadUShort();
		unpackStringEx( msf, strBuffer, strLen );
		
		if( !m_folderCriteria.empty() )
		{
      tmpFilename = string(strBuffer.begin(), strBuffer.end());
			std::transform(tmpFilename.begin(), tmpFilename.end(), tmpFilename.begin(), ::toupper);
			bMatchesCriteria = !( tmpFilename.find( m_folderCriteria ) == string::npos );
		}

		if( bMatchesCriteria )
		{
			if( m_listContents )
			{
				printf( "%s (%u bytes)\n", &strBuffer[0], fiItem.size );
			}
			else
			{
				if( !( extractItem2( fiItem, vecMsf[ fiItem.mrfIndex ], reinterpret_cast<const char*>(&strBuffer[0]) ) ) )
					++errors;
			}
		}

		++items;
	}

	vecMsf.clear();

	printf( "Processed %u items (%u issues)\n\n", items, errors );
}
Exemple #7
0
void z3ResEx::fsXor( TMemoryStream &src, unsigned int key ) const
{
	z3Xor::rs3Unscramble( src.Data(), src.Size(), key );
}
Exemple #8
0
void z3ResEx::Run( )
{
	// Check the fileindex exists
	if( TFileSize( msfName ) == 0 )
	{
		setMessage( "ERROR: Unable to open file (%s)", msfName );
	}
	else
	{
		TMemoryStream msf;

		m_fileindexKey			= nullptr;
		m_fileindexKeyLength	= 0;

		//
		// Brute-force the key (version 1)
		//

		unsigned int keyIndex( 0 );

		// For all known keys
		while( ( keyIndex < keyList1Count ) && ( msf.Size() == 0 ) )
		{
			// Try to read the fileindex
			if( fsReadMSF( msf, keyList1[ keyIndex ].Data, KeyLength1, 0 ) )
			{
				m_fileindexKey			= keyList1[ keyIndex ].Data;
				m_fileindexKeyLength	= KeyLength1;
				m_fileindexVer			= 0;

				if( m_verboseMessages )
					printf("Found key for %s!\n", keyList1[ keyIndex ].Desc );
			}

			++keyIndex;
		}

		// If key has not been found
		if( m_fileindexKey == nullptr )
		{
			//
			//  Continue to brute-force the key (version 2)
			//

			keyIndex = 0;
			// For all known keys
			while( ( keyIndex < keyList2Count ) && ( msf.Size() == 0 ) )
			{
				// Try to read the fileindex
				if( fsReadMSF( msf, keyList2[ keyIndex ].Data, KeyLength2, 1 ) )
				{
					m_fileindexKey			= keyList2[ keyIndex ].Data;
					m_fileindexKeyLength	= KeyLength2;
					m_fileindexVer			= 1;

					if( m_verboseMessages )
						printf("Found key for %s!\n", keyList2[ keyIndex ].Desc );
				}

				++keyIndex;
			}
		}

		// If a valid key has been found and fileindex loaded
		if( !( ( m_fileindexKey == nullptr ) && ( msf.Size() == 0 ) ) )
		{
			// Attempt to parse it (to extract or list files)
			msf.Seek( 0, bufo_start );
			parseMsf( msf );
		}
		else
		{
			// No key found or incompatiable file (not checked)
			setMessage( "ERROR: This file is using an updated key or unsupported method" );
		}

		msf.Close();
	}
}
Exemple #9
0
int main( int argc, char **argv )
{
	printf
	(
		"z3ResEx" \
		"\nResearched and coded by x1nixmzeng\n\n"
	);
		
	// Check arguments
	if( argc > 1 )
	{
		if( SetCurrentDirectory( argv[1] ) == 0 )
		{
			printf("ERROR: Failed to set the client path (%s)\n", argv[1] );
			return 0;
		}

		if( argc > 2 )
		{
			// For all other arguments, check against known flags

			if( argv[2][0] == '-' )
			{
				// -v		Verbose
				// todo

				// -l		List all files
				if( argv[2][1] == 'l' )
				{
					user_opt_list_files = true;
				}
				else
				
				// -x		No extraction
				if( argv[2][1] == 'x' )
				{
					user_opt_allow_extraction = false;
				}

				// -f		Extract only (filter)
				// todo
			}

		}
	}

	// Check the fileindex exists
	if( TFileSize( msfName ) == 0 )
	{
		printf("ERROR: Unable to open file (%s)\n", msfName);
	}
	else
	{
		unsigned int keyIndex( 0 );
		TMemoryStream msf;

		// Brute-force the key
		while( ( keyIndex < Z3_KEY_LIST_LENGTH ) && ( msf.Size() == 0 ) )
		{
			if( fsReadMSF( msf, Z3_KEY_LIST[ keyIndex ] ) )
			{
				z3CurrentKey = Z3_KEY_LIST[ keyIndex ];
				
				// todo: verbose? - show key
			}

			++keyIndex;
		}

		if( !( z3CurrentKey == nullptr ) )
		{
			// Run main extraction loop
			if( !( user_opt_allow_extraction ) )
				printf("NOTE:  Opted NOT to save data\n");

			extractionMain( msf );
		}
		else
		{
			// No key found or incompatiable file (not checked)
			printf("ERROR: This file is using an updated key or unsupported method\n");
		}

		msf.Close();
	}

	return 0;
}
Exemple #10
0
void extractionMain( TMemoryStream &msf )
{
	const unsigned int MAX_ERRORS( 50 );
	unsigned int items( 0 );

	FILEINDEX_ENTRY info;
	unsigned char method;

	char *strMRFN( nullptr ), *strName( nullptr );

	#define unpackString(buf,len) \
	{ \
		buf = new char[ len +1 ]; \
		msf.Read( buf, len ); \
		buf[ len ] = 0; \
	}

#ifdef SAVE_MSF_FILEINDEX
	msf.SaveToFile("z3debug_fileindex.msf");
#endif

	// Are we just listing files?
	if( user_opt_list_files )
	{
		std::string fname;

		printf("Listing filesystem contents\n\n");

		while( msf.Position() < msf.Size() )
		{
			method = msf.ReadByte();
			msf.Read( &info, sizeof( FILEINDEX_ENTRY ) );

			unpackString( strMRFN, info.lenMRFN );
			unpackString( strName, info.lenName );

			fname = fsRename( strMRFN, strName );
			printf("%s\n", fname.c_str());
			
			++items;

			delete strMRFN;
			delete strName;
		}

		fname.clear();
		printf("\nLocated %u files\n", items);
	}
	else
	// Run the main extraction loop
	{
		unsigned int errors( 0 );

		printf("Extracting filesystem contents\n\n");

		while( ( msf.Position() < msf.Size() ) && ( errors < MAX_ERRORS ) )
		{
			method = msf.ReadByte();
			msf.Read( &info, sizeof( FILEINDEX_ENTRY ) );

			unpackString( strMRFN, info.lenMRFN );
			unpackString( strName, info.lenName );

			if( !( extractItem( info, method, strMRFN, strName ) ) )
				++errors;

			++items;

			delete strMRFN;
			delete strName;
		}

		if( errors >= MAX_ERRORS )
			printf("ERROR: Extraction stopped as there were too many errors\n");
		else
			printf("\nExtracted %u files (%u problems)\n", items, errors);
	}
}
Exemple #11
0
void z3ResEx::parseMsfMethod2( TMemoryStream &msf )
{
	unsigned short strLen( 0 );
	unsigned char *strBuffer( nullptr );

	unsigned short mrfIndexLen( 0 );

	// Folders are now in a table at the top of the file
	msf.Read( &mrfIndexLen, sizeof( unsigned short ) );

	// List of filenames
	//typedef std::pair<string, TFileStream* > mrfItem;
	typedef vector<string > mrfItemList;

	mrfItemList vecMsf;
	vecMsf.resize( mrfIndexLen );
			
	// MRF filenames are now packed in a list
	for( unsigned short i( 0 ); i != mrfIndexLen; ++i )
	{
		strLen = msf.ReadUShort();
		unpackStringEx( msf, strBuffer, strLen );

		// Required to rename files
		//vecMsf[i].first.assign( (char *)strBuffer );
		// Cached file opening (and a pointer so we can call the constructor)
		//vecMsf[i].second = new TFileStream( strBuffer );

		vecMsf[i].assign( (char *)strBuffer );

		delete strBuffer;
	}

	// Files are now listed (similar to before)
	FILEINDEX_ENTRY2 fiItem;

	unsigned int items( 0 ), errors( 0 );

	//msf.SaveToFile("debugFilesys.dat");

	while( ( msf.Position() < msf.Size() ) && ( errors < MAX_ERRORS ) )
	{
		msf.Read( &fiItem, sizeof( FILEINDEX_ENTRY2 ) );

		strLen = msf.ReadUShort();
		unpackStringEx( msf, strBuffer, strLen );
		
		if( m_listContents )
		{
			printf( "%s (%u bytes)\n", strBuffer, fiItem.size );
		}
		else
		{
			if( !( extractItem2( fiItem, vecMsf[ fiItem.mrfIndex ], (char *)strBuffer ) ) )
				++errors;
		}

		delete strBuffer;

		++items;
	}

	vecMsf.clear();

	printf( "Processed %u items (%u issues)\n\n", items, errors );
}