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; }
bool z3ResEx::extractItem( FILEINDEX_ENTRY &info, unsigned char method, const char *strMrf, const char *strName ) { TFileStream mrf( strMrf ); if( !( mrf.isOpen() ) ) { setMessage( "ERROR: Unable to open file (%s)", strMrf ); return false; } // Format the output filename std::string fname( fsRename( strMrf, strName ) ); // UNFORCED EXTRACTION // If file already exists, ignore it if( TFileSize( fname.c_str() ) == info.size ) { mrf.Close(); return true; } vector<unsigned char> buf( info.zsize ); // Load MRF data into buffer mrf.Seek( info.offset, bufo_start ); mrf.Read( &buf[0], info.zsize ); mrf.Close(); // Copy into TStream TMemoryStream fdata; fdata.LoadFromBuffer( &buf[0], info.zsize ); buf.clear(); printf ( ( m_doExtraction ? "Saving %s.. " : "Checking %s.. " ), fname.substr( fname.rfind('/') +1 ).c_str() ); // Create path only when extraction is flagged if( m_doExtraction ) fsCreatePath( fname ); switch( method ) { // Compressed, most files case FILEINDEX_ENTRY_COMPRESSED : { fsXor( fdata, info.xorkey ); TMemoryStream fdata_raw; if( fsRle( fdata, fdata_raw ) ) { if( m_doExtraction ) fdata_raw.SaveToFile( fname.c_str() ); puts(" ..done!"); } // fsRle will display any errors fdata_raw.Close(); break; } // Encrypted and compressed, some system data (GunZ 2) case FILEINDEX_ENTRY_COMPRESSED2 : { TMemoryStream fdata_dec; z3Decrypt( fdata, fdata_dec, m_fileindexKey, m_fileindexKeyLength ); fdata.Close(); // Now same as FILEINDEX_ENTRY_COMPRESSED fsXor( fdata_dec, info.xorkey ); TMemoryStream fdata_raw; if( fsRle( fdata_dec, fdata_raw ) ) { if( m_doExtraction ) fdata_raw.SaveToFile( fname.c_str() ); printf(" ..done!\n"); } // fsRle will display any errors fdata_dec.Close(); fdata_raw.Close(); break; } // Large files, some FSB (GunZ 2) case FILEINDEX_ENTRY_UNCOMPRESSED : { if( m_doExtraction ) fdata.SaveToFile( fname.c_str() ); puts(" ..done!"); break; } default: { fdata.Close(); printf("ERROR: Unknown compression type (%02X)\n", method); return false; } } fdata.Close(); return true; }
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(); } }
bool extractItem( FILEINDEX_ENTRY &info, unsigned char method, char *strMrf, char *strName ) { TFileStream mrf( strMrf ); if( !( mrf.isOpen() ) ) { printf("ERROR: Could not open file (%s)\n", strMrf ); return false; } // Format the output filename std::string fname( fsRename( strMrf, strName ) ); #ifdef VERBOSE printf("Using filename: %s\n", fname.c_str()); #endif // UNFORCED EXTRACTION // If file already exists, ignore it if( TFileSize( fname.c_str() ) == info.size ) { mrf.Close(); return true; } unsigned char *buf( new unsigned char[ info.zsize ] ); #ifdef VERBOSE printf("Allocated %u bytes\n", info.zsize); #endif // Load MRF data into buffer mrf.Seek( info.offset, bufo_start ); mrf.Read( buf, info.zsize ); mrf.Close(); #ifdef VERBOSE printf("Read %u bytes at %u\n", info.zsize, info.offset ); #endif // Copy into TStream TMemoryStream fdata; fdata.LoadFromBuffer( buf, info.zsize ); delete buf; printf ( ( user_opt_allow_extraction ? "Saving %s.. " : "Checking %s.. " ), fname.substr( fname.rfind('/') +1 ).c_str() ); // Create path only when extraction is flagged if( user_opt_allow_extraction ) fsCreatePath( fname ); switch( method ) { // Compressed, most files case FILEINDEX_ENTRY_COMPRESSED : { fsXor( info, fdata ); #ifdef VERBOSE printf("Complete XOR routine\n"); #endif TMemoryStream fdata_raw; if( fsRle( fdata, fdata_raw ) ) { #ifdef VERBOSE printf("Completed RLE routine\n"); #endif if( user_opt_allow_extraction ) fdata_raw.SaveToFile( fname.c_str() ); printf("done!\n"); } // fsRle will display any errors fdata_raw.Close(); break; } // Encrypted and compressed, some system data (GunZ 2) case FILEINDEX_ENTRY_COMPRESSED2 : { TMemoryStream fdata_dec; z3Decrypt( z3CurrentKey, fdata, fdata_dec ); fdata.Close(); // Now same as FILEINDEX_ENTRY_COMPRESSED fsXor( info, fdata_dec ); TMemoryStream fdata_raw; if( fsRle( fdata_dec, fdata_raw ) ) { if( user_opt_allow_extraction ) fdata_raw.SaveToFile( fname.c_str() ); printf("done!\n"); } // fsRle will display any errors fdata_dec.Close(); fdata_raw.Close(); break; } // Large files, some FSB (GunZ 2) case FILEINDEX_ENTRY_UNCOMPRESSED : { if( user_opt_allow_extraction ) fdata.SaveToFile( fname.c_str() ); printf("done!\n"); break; } default: { fdata.Close(); printf("ERROR: Unknown compression type (%02X)\n", method); return false; } } fdata.Close(); return true; }
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; }
bool z3ResEx::extractItem2( FILEINDEX_ENTRY2 &info, const string &strMrf, char *strName ) { TFileStream mrf( strMrf.c_str() ); if( !( mrf.isOpen() ) ) { setMessage( "ERROR: Unable to open file (%s)", strMrf.c_str() ); return false; } // Format the output filename std::string fname( fsRename( strMrf.c_str(), strName ) ); // UNFORCED EXTRACTION // If file already exists, ignore it if( TFileSize( fname.c_str() ) == info.size ) { mrf.Close(); return true; } unsigned char *buf( new unsigned char[ info.zsize ] ); // Load MRF data into buffer mrf.Seek( info.offset, bufo_start ); mrf.Read( buf, info.zsize ); mrf.Close(); // Copy into TStream TMemoryStream fdata; fdata.LoadFromBuffer( buf, info.zsize ); delete buf; printf( "Saving %s.. ", fname.substr( fname.rfind('/') +1 ).c_str() ); fsCreatePath( fname ); switch( info.type ) { case FILEINDEXITEM_COMPRESSED : { fsXor( fdata, info.xorkey ); TMemoryStream fdata_raw; if( fsRle( fdata, fdata_raw ) ) { if( m_doExtraction ) fdata_raw.SaveToFile( fname.c_str() ); puts(" ..done!"); } // fsRle will display any errors fdata_raw.Close(); break; } /* // Encrypted and compressed, some system data (GunZ 2) case FILEINDEX_ENTRY_COMPRESSED2 : { TMemoryStream fdata_dec; z3Decrypt( fdata, fdata_dec, m_fileindexKey, m_fileindexKeyLength ); fdata.Close(); // Now same as FILEINDEX_ENTRY_COMPRESSED fsXor( info, fdata_dec ); TMemoryStream fdata_raw; if( fsRle( fdata_dec, fdata_raw ) ) { if( m_doExtraction ) fdata_raw.SaveToFile( fname.c_str() ); printf(" ..done!\n"); } // fsRle will display any errors fdata_dec.Close(); fdata_raw.Close(); break; } */ case FILEINDEXITEM_UNCOMPRESSED : { fdata.SaveToFile( fname.c_str() ); puts(" ..done!"); break; } default: { fdata.Close(); printf("ERROR: Unknown compression type (%02X)\n", info.type); return false; } } fdata.Close(); return true; }