http://www.softpedia.com/get/Programmin ... sion.shtml
A handful of resources are left out on purpose since this is an old project. I do not recommend using this but for anything more then a reference if you plan to compile it.
CodeFusion.h
- #pragma once
- /*
- * *****************************************************************************
- * CodeFusion.h - (c) atom0s 2009 [atom0s@live.com]
- * *****************************************************************************
- *
- * This file is part of FusionDump.
- *
- * FusionDump is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your opinion) any later version.
- *
- * FusionDump is distributed in the top that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABLILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with FusionDumper. If not, see <http://www.gnu.org/licenses/>.
- *
- *******************************************************************************
- */
- /*
- * *****************************************************************************
- * Informational
- * *****************************************************************************
- *
- * This file contains various structures, functions, and definitions
- * used to read a CodeFusion file overlay. This file is made for
- * educational purposes only, and not to damage CodeFusion in any
- * way. You are NOT permitted to use this file if you plan to use
- * it for any malicious reasons.
- *
- * CodeFusion is copyright to:
- * CodeFusion (c) 2003 - 2009 Kobik.domain [Krichmar Kobi, Israel]
- *
- *******************************************************************************
- */
- #ifndef __CODEFUSION_H_INCLUDED__
- #define __CODEFUSION_H_INCLUDED__
- #define STRICT
- #define WIN32_LEAN_AND_MEAN
- #define _WIN32_WINNT 0x0501
- #include <windows.h>
- /**
- * CodeFusion Overlay Signature
- *
- * @._P-DATA_.@
- *
- */
- #define CODEFUSION_FILE_SIGNATURE "@._P-DATA_.@"
- /**
- * CodeFusion Patch Types
- *
- */
- typedef enum _PATCH_TYPES {
- BytePatchOffset = 0,
- FindReplace = 1,
- FindReplaceAll = 2,
- PatternFindReplace = 3,
- UNKNOWN_TYPE_4 = 4,
- TruncateFile = 5,
- } PATCH_TYPES, *LPPATCH_TYPES;
- /**
- * CodeFusion Patch Entry
- *
- */
- typedef struct _CODEFUSION_PATCHENTRY {
- unsigned char PatchType;
- unsigned long PatchOffset;
- // Patch Type 0 Data
- std::vector< unsigned char > PatchData;
- // Patch Type 1, 3 Data
- std::vector< unsigned char > FindData;
- std::vector< unsigned char > ReplaceData;
- } CODEFUSION_PATCHENTRY, *LPCODEFUSION_PATCHENTRY;
- /**
- * CodeFusion File Entry
- *
- */
- typedef struct _CODEFUSION_FILEENTRY {
- // Basic File Info
- std::string FileName;
- unsigned long FileSize;
- std::string FileSizeText;
- std::string FileDate;
- std::string OpenDialogFilter;
- unsigned long FileCrc32;
- // File Flags
- unsigned char CheckFileSize;
- unsigned char CheckFileCrc32;
- unsigned char ShowFileDate;
- // File Patch Entries
- unsigned long FilePatchCount;
- std::vector< CODEFUSION_PATCHENTRY > PatchEntries;
- } CODEFUSION_FILEENTRY, *LPCODEFUSION_FILEENTRY;
- /**
- * CodeFusion Overlay
- *
- */
- typedef struct _CODEFUSION_OVERLAY {
- unsigned char Unknown1; // Unknown byte. Has been 4 always so far. [Assuming version of some sort.]
- unsigned char Encrypted; // Encrypted flag, 0 = no, 1 = yes.
- // Main Window Information
- std::string WindowTitle;
- std::string PatchDescription;
- std::string PatchNotes;
- // About Box Window Information
- std::string AboutBox;
- std::string ButtonOneText;
- std::string ButtonOneAction;
- std::string ButtonTwoText;
- std::string ButtonTwoAction;
- // File Entries
- unsigned char FilesToPatch;
- std::vector< CODEFUSION_FILEENTRY > FileEntries;
- // Cleanup Function
- void ClearData( void )
- {
- this->Unknown1 = 0;
- this->Encrypted = 0;
- this->FilesToPatch = 0;
- this->WindowTitle.clear();
- this->PatchDescription.clear();
- this->PatchNotes.clear();
- this->AboutBox.clear();
- this->ButtonOneText.clear();
- this->ButtonOneAction.clear();
- this->ButtonTwoText.clear();
- this->ButtonTwoAction.clear();
- this->FileEntries.clear();
- }
- } CODEFUSION_OVERLAY, *LPCODEFUSION_OVERLAY;
- /**
- * DecryptString
- * -----------------------------------------------------------------------
- * @Purpose: Decrypts xored strings inside CodeFusion overlays.
- * @Returns: int - 0 on fail, nSize on success.
- * -----------------------------------------------------------------------
- */
- __inline int DecryptString( int nSize, LPCSTR lpString, LPSTR lpBuffer )
- {
- if( ! nSize || ! lpString || ! lpBuffer )
- return 0;
- try
- {
- unsigned char* lpDataPtr = reinterpret_cast< unsigned char* >( lpBuffer );
- for( int x = 0; x < nSize; x++ )
- {
- ( *lpDataPtr ) = static_cast< unsigned char >( ( lpString[ x ] ^ ( x + 1 ) ) );
- lpDataPtr++;
- }
- return nSize;
- }
- catch( ... )
- {
- return 0;
- }
- }
- /**
- * DecryptVector
- * -----------------------------------------------------------------------
- * @Purpose: Decrypts xored patch data.
- * @Returns: int - 0 on fail, nSize on success.
- */
- __inline int DecryptVector( int nSize, std::vector< unsigned char >& vPatchData )
- {
- if( ! nSize || vPatchData.empty() )
- return 0;
- try
- {
- for( int x = 0; x < nSize; x++ )
- {
- vPatchData[x] = ( vPatchData[x] ^ ( x + 1 ) );
- }
- return nSize;
- }
- catch( ... )
- {
- return 0;
- }
- }
- /**
- * ReadPatchString
- * -----------------------------------------------------------------------
- * @Purpose: Reads a string from the given buffer.
- * @Returns: int - -1 on fail, size of string on success.
- * -----------------------------------------------------------------------
- *
- * This function reads a string from the given buffer based on the starting
- * byte as the size. You should not skip the size byte with the offset being
- * passed to this function. Strings are setup as:
- *
- * size | string[ size ]
- *
- */
- __inline int ReadPatchString( LPVOID lpOverlay, LPVOID lpBuffer )
- {
- if( ! lpOverlay || ! lpBuffer )
- return -1;
- try
- {
- unsigned char* lpDataPtr = reinterpret_cast< unsigned char* >( lpOverlay );
- int nStringSize = lpDataPtr[ 0 ];
- if( nStringSize == 0 )
- return 0;
- memcpy( lpBuffer, ( ++lpDataPtr ), nStringSize );
- return nStringSize;
- }
- catch( ... )
- {
- return -1;
- }
- }
- //
- // Text File Dump Headers
- //
- // ------------------------------------------------------------------
- #define TXT_OVERVIEW_HEADER \
- "------------------------------------------------------------------------------------------------------------\r\n" \
- "FusionDump Log File - {FILE_PATH}\r\n" \
- "------------------------------------------------------------------------------------------------------------\r\n" \
- "File Name : {FILE_PATH}\r\n" \
- "File Size : {FILE_SIZE} bytes\r\n" \
- "Overlay Size : {OVERLAY_SIZE} bytes\r\n" \
- "Overlay Encrypted : {OVERLAY_ENCRYPTED}\r\n\r\n"
- #define TXT_MAINWINDOW_HEADER \
- "------------------------------------------------------------------------------------------------------------\r\n" \
- "MAIN WINDOW INFORMATION\r\n" \
- "------------------------------------------------------------------------------------------------------------\r\n" \
- "Window Title : {WINDOW_TITLE}\r\n" \
- "Patch Description : {WINDOW_DESCRIPTION}\r\n" \
- "Patch Notes : \r\n\r\n{WINDOW_NOTES}\r\n\r\n"
- #define TXT_ABOUTWINDOW_HEADER \
- "------------------------------------------------------------------------------------------------------------\r\n" \
- "ABOUT WINDOW INFORMATION\r\n" \
- "------------------------------------------------------------------------------------------------------------\r\n" \
- "Button One Text : {ABOUT_BUTTON_ONE_TEXT}\r\n" \
- "Button One Action : {ABOUT_BUTTON_ONE_ACTION}\r\n\r\n" \
- "Button Two Text : {ABOUT_BUTTON_TWO_TEXT}\r\n" \
- "Button Two Action : {ABOUT_BUTTON_TWO_ACTION}\r\n\r\n" \
- "About Box Text : \r\n\r\n{ABOUT_BOX_TEXT}\r\n\r\n\r\n"
- #define TXT_PATCHINFO_HEADER \
- "------------------------------------------------------------------------------------------------------------\r\n" \
- "FILE PATCH INFORMATION\r\n" \
- "------------------------------------------------------------------------------------------------------------\r\n" \
- "Files To Patch : {FILE_PATCH_COUNT}\r\n\r\n"
- #define TXT_FILEENTRY_HEADER \
- " ----------------------------------------------------------------------------------------------------\r\n" \
- " | FILE ENTRY #{FILE_ENTRY_NUMBER} - {FILE_ENTRY_NAME} - ({FILE_ENTRY_PATCH_COUNT} patches.)\r\n" \
- " ----------------------------------------------------------------------------------------------------\r\n"
- #define TXT_FILEPATCHENTRY( type ) \
- TXT_FILEPATCHENTRY_##type
- #define TXT_FILEPATCHENTRY_0 \
- " ----------------------------------------\r\n" \
- " | PATCH #{PATCH_ENTRY_NUMBER} - Byte Patch at Offset\r\n" \
- " ----------------------------------------\r\n" \
- " Offset : {PATCH_OFFSET}\r\n" \
- " Patch : {PATCH_DATA}\r\n"
- #define TXT_FILEPATCHENTRY_1 \
- " ----------------------------------------\r\n" \
- " | PATCH #{PATCH_ENTRY_NUMBER} - Find and Replace\r\n" \
- " ----------------------------------------\r\n" \
- " Offset : {PATCH_OFFSET}\r\n" \
- " Find : {PATCH_FIND_DATA}\r\n" \
- " Replace : {PATCH_REPLACE_DATA}\r\n"
- #define TXT_FILEPATCHENTRY_2 \
- " ----------------------------------------\r\n" \
- " | PATCH #{PATCH_ENTRY_NUMBER} - Find and Replace (All)\r\n" \
- " ----------------------------------------\r\n" \
- " Offset : {PATCH_OFFSET}\r\n" \
- " Find : {PATCH_FIND_DATA}\r\n" \
- " Replace : {PATCH_REPLACE_DATA}\r\n"
- #define TXT_FILEPATCHENTRY_3 \
- " ----------------------------------------\r\n" \
- " | PATCH #{PATCH_ENTRY_NUMBER} - Pattern Find and Replace\r\n" \
- " ----------------------------------------\r\n" \
- " Offset : {PATCH_OFFSET}\r\n" \
- " Pattern : {PATCH_FIND_DATA}\r\n" \
- " Replace : {PATCH_REPLACE_DATA}\r\n"
- #define TXT_FILEPATCHENTRY_4 \
- " ----------------------------------------\r\n" \
- " | PATCH #{PATCH_ENTRY_NUMBER} - UNKNOWN PATCH TYPE\r\n" \
- " ----------------------------------------\r\n" \
- " Unknown patch type, please report this!\r\n"
- #define TXT_FILEPATCHENTRY_5 \
- " ----------------------------------------\r\n" \
- " | PATCH #{PATCH_ENTRY_NUMBER} - Truncate End of File\r\n" \
- " ----------------------------------------\r\n" \
- " Offset : {PATCH_OFFSET}\r\n"
- #endif // __CODEFUSION_H_INCLUDED__
- #pragma once
- /*
- * *****************************************************************************
- * CFileDump.hpp - (c) atom0s 2009 [atom0s@live.com]
- * *****************************************************************************
- *
- * This file is part of FusionDump.
- *
- * FusionDump is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your opinion) any later version.
- *
- * FusionDump is distributed in the top that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABLILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with FusionDumper. If not, see <http://www.gnu.org/licenses/>.
- *
- *******************************************************************************
- */
- #ifndef __CFILEDUMP_HPP_INCLUDED__
- #define __CFILEDUMP_HPP_INCLUDED__
- #include "defines.h"
- #include "CodeFusion.h"
- #define MAX_SECTIONS 20
- class CFileDump
- {
- std::string m_vFilePath;
- int m_vSaveMethod;
- DWORD m_vFileSize;
- LPVOID m_vFileDump;
- DWORD m_vOverlaySize;
- DWORD m_vOverlayStart;
- CODEFUSION_OVERLAY m_vOverlay;
- public:
- CFileDump( const std::string& sFile, int nSaveMethod = 0 );
- ~CFileDump( void );
- public:
- HRESULT LoadFile( LPCTSTR lpFilePath = NULL );
- private:
- HRESULT DumpOverlay( void );
- HRESULT SaveOverlay( void );
- };
- #endif // __CFILEDUMP_HPP_INCLUDED__
- /*
- * *****************************************************************************
- * CFileDump.cpp - (c) atom0s 2009 [atom0s@live.com]
- * *****************************************************************************
- *
- * This file is part of FusionDump.
- *
- * FusionDump is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your opinion) any later version.
- *
- * FusionDump is distributed in the top that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABLILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with FusionDumper. If not, see <http://www.gnu.org/licenses/>.
- *
- *******************************************************************************
- */
- #include "CFileDump.hpp"
- CFileDump::CFileDump( const std::string& sFile, int nSaveMethod ) : m_vFileDump( 0 ), m_vFileSize( 0 ), m_vOverlaySize( 0 ), m_vOverlayStart( 0 )
- {
- this->m_vFilePath = sFile;
- this->m_vSaveMethod = nSaveMethod;
- this->m_vOverlay.ClearData();
- }
- CFileDump::~CFileDump( void )
- {
- if( this->m_vFileDump )
- delete[] this->m_vFileDump;
- this->m_vFileDump = NULL;
- this->m_vOverlay.ClearData();
- }
- HRESULT CFileDump::LoadFile( LPCTSTR lpFilePath /* = NULL */ )
- {
- // User Passing New File?
- if( lpFilePath )
- this->m_vFilePath = lpFilePath;
- // Ensure A File To Dump Is Given
- if( this->m_vFilePath.length() == 0 )
- {
- LogMessage( _T( "ERROR: Call to LoadFile without a selected file.\r\n" ) );
- return E_FAIL;
- }
- // Cleanup Any Previous Information
- if( this->m_vFileDump )
- delete[] this->m_vFileDump;
- this->m_vFileDump = NULL;
- this->m_vFileSize = NULL;
- this->m_vOverlaySize = NULL;
- this->m_vOverlayStart = NULL;
- this->m_vOverlay.ClearData();
- // Valid File Existence
- if( GetFileAttributes( this->m_vFilePath.c_str() ) == 0xFFFFFFFF )
- {
- LogMessage( _T( "ERROR: File was not found.\r\n" ) );
- return E_FAIL;
- }
- //
- // Main file opening happens below. Handles are
- // opened from this point on, any failures in
- // this function MUST close any open handles!
- // ------------------------------------------------------------------
- // Attempt To Open The File
- LogMessage( _T( "Opening Selected File......" ) );
- HANDLE hFileHandle = CreateFile( this->m_vFilePath.c_str(), GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
- if( hFileHandle == INVALID_HANDLE_VALUE )
- {
- LogMessage( _T( "Failed!\r\n" ) );
- return E_FAIL;
- }
- LogMessage( _T( "Done!\r\n" ) );
- // Attempt To Read Memory Map
- LogMessage( _T( "Creating File Mapping......" ) );
- HANDLE hFileMapping = CreateFileMapping( hFileHandle, 0, PAGE_READWRITE, 0, 0, 0 );
- if( hFileMapping == NULL )
- {
- LogMessage( _T( "Failed!\r\n" ) );
- CloseHandle( hFileHandle );
- return E_FAIL;
- }
- LogMessage( _T( "Done!\r\n" ) );
- // Attempt To Map File View Into Our Address Space
- LogMessage( _T( "Mapping View Of File......." ) );
- LPVOID lpFilePtr = MapViewOfFile( hFileMapping, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, 0 );
- if( ! lpFilePtr )
- {
- LogMessage( _T( "Failed!\r\n" ) );
- CloseHandle( hFileMapping );
- CloseHandle( hFileHandle );
- return E_FAIL;
- }
- LogMessage( _T( "Done!\r\n" ) );
- //
- // Since we got this far, we will dump the loaded file into
- // our class variables rather then leave the handles open
- // and have to do various close handle calls.
- // ------------------------------------------------------------------
- LogMessage( _T( "Dumping File Into Memory..." ) );
- // Obtain True File Size
- this->m_vFileSize = GetFileSize( hFileHandle, NULL );
- // Dump File Into Our class
- this->m_vFileDump = new unsigned char[ this->m_vFileSize + 1 ];
- memcpy( this->m_vFileDump, lpFilePtr, this->m_vFileSize );
- // Cleanup Handles
- UnmapViewOfFile( lpFilePtr );
- CloseHandle( hFileMapping );
- CloseHandle( hFileHandle );
- LogMessage( _T( "Done!\r\n" ) );
- //
- // Next we need to dump the headers of the file to ensure that
- // we have loaded a valid PE file. We also use the headers to
- // read the sections inside the file to obtain the 'seen' size
- // of the file to calculate the overlay size.
- // ------------------------------------------------------------------
- PIMAGE_DOS_HEADER pDosHeader = NULL;
- PIMAGE_NT_HEADERS pNtHeaders = NULL;
- // Validate Dos Header
- LogMessage( _T( "Validating Dos Signature..." ) );
- pDosHeader = reinterpret_cast< PIMAGE_DOS_HEADER >( this->m_vFileDump );
- if( pDosHeader->e_magic != IMAGE_DOS_SIGNATURE )
- {
- LogMessage( _T( "Failed!\r\n" ) );
- return E_FAIL;
- }
- LogMessage( _T( "Done!\r\n" ) );
- // Validate Nt Headers
- LogMessage( _T( "Validating Nt Signature...." ) );
- pNtHeaders = reinterpret_cast< PIMAGE_NT_HEADERS >( reinterpret_cast< DWORD >( this->m_vFileDump ) + pDosHeader->e_lfanew );
- if( pNtHeaders->Signature != IMAGE_NT_SIGNATURE )
- {
- LogMessage( _T( "Failed!\r\n" ) );
- return E_FAIL;
- }
- LogMessage( _T( "Done!\r\n" ) );
- DWORD dwFileSize = NULL;
- DWORD dwMaxPointer = NULL;
- DWORD dwCurrPosition = ( reinterpret_cast< DWORD >( this->m_vFileDump ) + pDosHeader->e_lfanew + sizeof( IMAGE_NT_HEADERS ) );
- // Read Sections From Header [Read File Size Too]
- LogMessage( _T( "Dumping Header Sections...." ) );
- for( int x = 0; x < pNtHeaders->FileHeader.NumberOfSections; x++ )
- {
- PIMAGE_SECTION_HEADER pSectionHeader = reinterpret_cast< PIMAGE_SECTION_HEADER >( dwCurrPosition );
- if( pSectionHeader->PointerToRawData > dwMaxPointer )
- {
- dwMaxPointer = pSectionHeader->PointerToRawData;
- dwFileSize = ( pSectionHeader->PointerToRawData + pSectionHeader->SizeOfRawData );
- }
- dwCurrPosition += sizeof( IMAGE_SECTION_HEADER );
- }
- LogMessage( _T( "Done!\r\n" ) );
- // Check If Overlay Exists
- if( this->m_vFileSize <= dwFileSize )
- {
- LogMessage( _T( "ERROR: File does not appear to contain an overlay!\r\n" ) );
- return E_FAIL;
- }
- // Store Overlay Information
- this->m_vOverlaySize = ( this->m_vFileSize - dwFileSize );
- this->m_vOverlayStart = dwFileSize;
- if( ! this->DumpOverlay() )
- return E_FAIL;
- return S_OK;
- }
- HRESULT CFileDump::DumpOverlay( void )
- {
- if( ! this->m_vFileDump || this->m_vFileSize == 0 || this->m_vOverlaySize == 0 )
- return E_FAIL;
- // Local Variables
- int nSize = 0;
- // Setup Pointer To Overlay
- unsigned char* lpOverlay = reinterpret_cast< unsigned char* >( reinterpret_cast< DWORD >( this->m_vFileDump ) + this->m_vOverlayStart );
- //
- // Read and validate the file overlay signature to
- // ensure the current overlay is a CodeFusion file.
- // ------------------------------------------------------------------
- LogMessage( _T( "Validating Overlay........." ) );
- unsigned char btSignature[ 0x0D ] = { 0 };
- memcpy( & btSignature, lpOverlay, 0x0C );
- if( _stricmp( reinterpret_cast< LPCSTR >( btSignature ), CODEFUSION_FILE_SIGNATURE ) != 0 )
- {
- LogMessage( _T( "Failed!\r\n" ) );
- return E_FAIL;
- }
- LogMessage( _T( "Done!\r\n" ) );
- lpOverlay += 0x0C;
- //
- // Read the starting two bytes which contain the
- // encryption flag for the overlay.
- // ------------------------------------------------------------------
- this->m_vOverlay.Unknown1 = lpOverlay[0];
- this->m_vOverlay.Encrypted = lpOverlay[1];
- lpOverlay += 2;
- //
- // Read the window title.
- // ------------------------------------------------------------------
- char szTitleString[ 0xFF ] = { 0 };
- nSize = ReadPatchString( lpOverlay, & szTitleString );
- if( this->m_vOverlay.Encrypted )
- DecryptString( nSize, const_cast< LPCSTR >( &szTitleString[ 0 ] ), szTitleString );
- this->m_vOverlay.WindowTitle = szTitleString;
- lpOverlay += nSize;
- lpOverlay += 1;
- //
- // Read the description.
- // ------------------------------------------------------------------
- char szDescription[ 0xFF ] = { 0 };
- nSize = ReadPatchString( lpOverlay, & szDescription );
- if( this->m_vOverlay.Encrypted )
- DecryptString( nSize, const_cast< LPCSTR >( &szDescription[ 0 ] ), szDescription );
- this->m_vOverlay.PatchDescription = szDescription;
- lpOverlay += nSize;
- lpOverlay += 1;
- //
- // Read the patch notes.
- // ------------------------------------------------------------------
- char szPatchNotes[ 0xFF ] = { 0 };
- nSize = ReadPatchString( lpOverlay, & szPatchNotes );
- if( this->m_vOverlay.Encrypted )
- DecryptString( nSize, const_cast< LPCSTR >( &szPatchNotes[ 0 ] ), szPatchNotes );
- this->m_vOverlay.PatchNotes = szPatchNotes;
- lpOverlay += nSize;
- lpOverlay += 1;
- //
- // Read the about box text.
- // ------------------------------------------------------------------
- char szAboutBox[ 0xFF ] = { 0 };
- nSize = ReadPatchString( lpOverlay, & szAboutBox );
- if( this->m_vOverlay.Encrypted )
- DecryptString( nSize, const_cast< LPCSTR >( &szAboutBox[ 0 ] ), szAboutBox );
- this->m_vOverlay.AboutBox = szAboutBox;
- lpOverlay += nSize;
- lpOverlay += 1;
- //
- // Read the button one caption.
- // ------------------------------------------------------------------
- char szButtonOne[ 0xFF ] = { 0 };
- nSize = ReadPatchString( lpOverlay, & szButtonOne );
- if( this->m_vOverlay.Encrypted )
- DecryptString( nSize, const_cast< LPCSTR >( &szButtonOne[ 0 ] ), szButtonOne );
- this->m_vOverlay.ButtonOneText = szButtonOne;
- lpOverlay += nSize;
- lpOverlay += 1;
- //
- // Read the button one action.
- // ------------------------------------------------------------------
- char szButtonOneAction[ 0xFF ] = { 0 };
- nSize = ReadPatchString( lpOverlay, & szButtonOneAction );
- if( this->m_vOverlay.Encrypted )
- DecryptString( nSize, const_cast< LPCSTR >( &szButtonOneAction[ 0 ] ), szButtonOneAction );
- this->m_vOverlay.ButtonOneAction = szButtonOneAction;
- lpOverlay += nSize;
- lpOverlay += 1;
- //
- // Read the button two caption.
- // ------------------------------------------------------------------
- char szButtonTwo[ 0xFF ] = { 0 };
- nSize = ReadPatchString( lpOverlay, & szButtonTwo );
- if( this->m_vOverlay.Encrypted )
- DecryptString( nSize, const_cast< LPCSTR >( &szButtonTwo[ 0 ] ), szButtonTwo );
- this->m_vOverlay.ButtonTwoText = szButtonTwo;
- lpOverlay += nSize;
- lpOverlay += 1;
- //
- // Read the button two action.
- // ------------------------------------------------------------------
- char szButtonTwoAction[ 0xFF ] = { 0 };
- nSize = ReadPatchString( lpOverlay, & szButtonTwoAction );
- if( this->m_vOverlay.Encrypted )
- DecryptString( nSize, const_cast< LPCSTR >( &szButtonTwoAction[ 0 ] ), szButtonTwoAction );
- this->m_vOverlay.ButtonTwoAction = szButtonTwoAction;
- lpOverlay += nSize;
- lpOverlay += 1;
- //
- // Read the file patch count.
- // ------------------------------------------------------------------
- this->m_vOverlay.FilesToPatch = lpOverlay[ 0 ];
- lpOverlay += 1;
- //
- // Loop and read the file entries.
- // ------------------------------------------------------------------
- for( int x = 0; x < this->m_vOverlay.FilesToPatch; x++ )
- {
- CODEFUSION_FILEENTRY cFileEntry;
- //
- // Read the file name.
- // ------------------------------------------------------------------
- char szFileName[ 0xFF ] = { 0 };
- nSize = ReadPatchString( lpOverlay, & szFileName );
- if( this->m_vOverlay.Encrypted )
- DecryptString( nSize, const_cast< LPCSTR >( &szFileName[ 0 ] ), szFileName );
- cFileEntry.FileName = szFileName;
- lpOverlay += nSize;
- lpOverlay += 1;
- //
- // Read the file size.
- // ------------------------------------------------------------------
- cFileEntry.FileSize = *(DWORD*)( reinterpret_cast< DWORD >( lpOverlay ) );
- lpOverlay += 4;
- //
- // Read the file size text.
- // ------------------------------------------------------------------
- char szFileSize[ 0xFF ] = { 0 };
- nSize = ReadPatchString( lpOverlay, & szFileSize );
- if( this->m_vOverlay.Encrypted )
- DecryptString( nSize, const_cast< LPCSTR >( &szFileSize[ 0 ] ), szFileSize );
- cFileEntry.FileSizeText = szFileSize;
- lpOverlay += nSize;
- lpOverlay += 1;
- //
- // Read the file date.
- // ------------------------------------------------------------------
- char szFileDate[ 0xFF ] = { 0 };
- nSize = ReadPatchString( lpOverlay, & szFileDate );
- if( this->m_vOverlay.Encrypted )
- DecryptString( nSize, const_cast< LPCSTR >( &szFileDate[ 0 ] ), szFileDate );
- cFileEntry.FileDate = szFileDate;
- lpOverlay += nSize;
- lpOverlay += 1;
- //
- // Read the open file dialog filter.
- // ------------------------------------------------------------------
- char szOpenFileFilter[ 0xFF ] = { 0 };
- nSize = ReadPatchString( lpOverlay, & szOpenFileFilter );
- if( this->m_vOverlay.Encrypted )
- DecryptString( nSize, const_cast< LPCSTR >( &szOpenFileFilter[ 0 ] ), szOpenFileFilter );
- cFileEntry.OpenDialogFilter = szOpenFileFilter;
- lpOverlay += nSize;
- lpOverlay += 1;
- //
- // Read the file crc32.
- // ------------------------------------------------------------------
- cFileEntry.FileCrc32 = *(DWORD*)( reinterpret_cast< DWORD >( lpOverlay ) );
- lpOverlay += 4;
- //
- // Read the file flags.
- // ------------------------------------------------------------------
- cFileEntry.CheckFileSize = lpOverlay[ 0 ];
- cFileEntry.CheckFileCrc32 = lpOverlay[ 1 ];
- cFileEntry.ShowFileDate = lpOverlay[ 2 ];
- lpOverlay += 3;
- lpOverlay += 2; // Two unknown bytes.
- //
- // Read the file patch count.
- // ------------------------------------------------------------------
- cFileEntry.FilePatchCount = *(DWORD*)( reinterpret_cast< DWORD >( lpOverlay ) );
- lpOverlay += 4;
- //
- // Loop and read the file patches.
- // ------------------------------------------------------------------
- for( unsigned long y = 0; y < cFileEntry.FilePatchCount; y++ )
- {
- CODEFUSION_PATCHENTRY cPatchEntry;
- //
- // Read patch type.
- // ------------------------------------------------------------------
- cPatchEntry.PatchType = lpOverlay[ 0 ];
- lpOverlay += 1;
- //
- // Patch Type 0 = Byte Replace
- //
- // Patch type 0 tells the patcher to replace bytes at
- // the specific offset in the file.
- //
- // ------------------------------------------------------------------
- if( cPatchEntry.PatchType == 0 )
- {
- //
- // Read patch offset.
- // ------------------------------------------------------------------
- cPatchEntry.PatchOffset = *(DWORD*)( reinterpret_cast< DWORD >( lpOverlay ) );
- lpOverlay += 4;
- //
- // Read patch length.
- // ------------------------------------------------------------------
- unsigned char cPatchLength = lpOverlay[ 0 ];
- lpOverlay += 1;
- //
- // Read patch data.
- // ------------------------------------------------------------------
- cPatchEntry.PatchData.resize( static_cast< size_t >( cPatchLength ), 0x00 );
- memcpy( &cPatchEntry.PatchData[ 0 ], lpOverlay, static_cast< size_t >( cPatchLength ) );
- lpOverlay += cPatchLength;
- //
- // Decrypt patch data.
- //
- if( this->m_vOverlay.Encrypted )
- DecryptVector( cPatchLength, cPatchEntry.PatchData );
- }
- //
- // Patch Type 1, 2, 3 = Find and Replace
- //
- // Patch types 1 and 3 tell the patcher to replace bytes
- // based on a given pattern, and not a specific offset.
- //
- // 1 = Normal find and replace.
- // 2 = Find and replace all.
- // 3 = Pattern find and replace.
- //
- // ------------------------------------------------------------------
- else if( cPatchEntry.PatchType == 1 || cPatchEntry.PatchType == 2 || cPatchEntry.PatchType == 3 )
- {
- //
- // Read patch offset.
- // ------------------------------------------------------------------
- cPatchEntry.PatchOffset = *(DWORD*)( reinterpret_cast< DWORD >( lpOverlay ) );
- lpOverlay += 4;
- //
- // Read patch length.
- // ------------------------------------------------------------------
- unsigned char cPatchLength = lpOverlay[ 0 ];
- lpOverlay += 1;
- //
- // Read patch replacement data.
- // ------------------------------------------------------------------
- cPatchEntry.ReplaceData.resize( static_cast< size_t >( cPatchLength ), 0x00 );
- memcpy( &cPatchEntry.ReplaceData[ 0 ], lpOverlay, static_cast< size_t >( cPatchLength ) );
- lpOverlay += cPatchLength;
- //
- // Decrypt replacement data.
- //
- if( this->m_vOverlay.Encrypted )
- DecryptVector( cPatchLength, cPatchEntry.ReplaceData );
- //
- // Read pattern length.
- // ------------------------------------------------------------------
- unsigned char cPatternLength = lpOverlay[ 0 ];
- lpOverlay += 1;
- //
- // Read pattern data.
- // ------------------------------------------------------------------
- cPatchEntry.FindData.resize( static_cast< size_t >( cPatternLength ), 0x00 );
- memcpy( &cPatchEntry.FindData[ 0 ], lpOverlay, static_cast< size_t >( cPatternLength ) );
- lpOverlay += cPatternLength;
- //
- // Decrypt pattern data.
- //
- if( this->m_vOverlay.Encrypted )
- DecryptVector( cPatternLength, cPatchEntry.FindData );
- }
- //
- // Patch Type 5 = Truncate EOF
- //
- // Patch type 5 truncates a file to the given offset
- // replacing the original end of file position.
- //
- // ------------------------------------------------------------------
- else if( cPatchEntry.PatchType == 5 )
- {
- //
- // Read patch offset.
- // ------------------------------------------------------------------
- cPatchEntry.PatchOffset = *(DWORD*)( reinterpret_cast< DWORD >( lpOverlay ) );
- lpOverlay += 4;
- lpOverlay += 2; // Theres two 0x00 0x00 bytes, not sure what they are for.
- }
- //
- // Unknown Patch Type
- //
- // For any other patch types that we are unsure
- // about yet, we must fail. We cannot determine
- // the size of the unknown entry so all patches
- // behind this point would be unaligned.
- //
- // ------------------------------------------------------------------
- else
- {
- LogMessage( _T( "ERROR: Unknown patch type found:\r\nType: 0x%08X\r\nUnable to continue dumping!\r\n" ), cPatchEntry.PatchType );
- return E_FAIL;
- }
- //
- // Push back patch enter.
- // ------------------------------------------------------------------
- cFileEntry.PatchEntries.push_back( cPatchEntry );
- }
- //
- // Push back file entry.
- // ------------------------------------------------------------------
- this->m_vOverlay.FileEntries.push_back( cFileEntry );
- }
- LogMessage( _T( "Overlay Dump Successful!\r\n" ) );
- if( FAILED( this->SaveOverlay() ) )
- {
- LogMessage( _T( "ERROR: Failed to save log of dumped overlay.\r\n" ) );
- return E_FAIL;
- }
- return S_OK;
- }
- HRESULT CFileDump::SaveOverlay( void )
- {
- // Some basic checks.
- if( ! this->m_vFileDump )
- return E_FAIL;
- if( ! this->m_vFileSize )
- return E_FAIL;
- if( this->m_vOverlay.FilesToPatch == 0 )
- return E_FAIL;
- if( this->m_vSaveMethod > 1 )
- return E_FAIL;
- //
- // Create dump log file name.
- // ------------------------------------------------------------------
- std::string strFileName = PathFindFileName( this->m_vFilePath.c_str() );
- time_t tTime = { 0 };
- time( & tTime );
- TCHAR tszTime[ 1024 ] = { 0 };
- _stprintf_s( tszTime, 1024, _T( ".%d.txt" ), tTime );
- strFileName += tszTime;
- //
- // Create dump log file and begin writing.
- // ------------------------------------------------------------------
- HANDLE hFileHandle = CreateFile( strFileName.c_str(), GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 );
- if( hFileHandle == INVALID_HANDLE_VALUE )
- {
- LogMessage( _T( "ERROR: Failed to create dump log file.\r\n" ) );
- return E_FAIL;
- }
- // Buffer for internal function use.
- TCHAR tszOutput[ 1024 ] = { 0 };
- //
- // Prepare overview information.
- // ------------------------------------------------------------------
- std::string strOverview = TXT_OVERVIEW_HEADER;
- ReplaceString( strOverview, "{FILE_PATH}", this->m_vFilePath );
- _stprintf_s( tszOutput, 1024, _T( "%d" ), this->m_vFileSize );
- ReplaceString( strOverview, "{FILE_SIZE}", tszOutput );
- _stprintf_s( tszOutput, 1024, _T( "%d" ), this->m_vOverlaySize );
- ReplaceString( strOverview, "{OVERLAY_SIZE}", tszOutput );
- _stprintf_s( tszOutput, 1024, _T( "%s" ), ( this->m_vOverlay.Encrypted == 0 ) ? "False" : "True" );
- ReplaceString( strOverview, "{OVERLAY_ENCRYPTED}", tszOutput );
- //
- // Prepare main window information.
- // ------------------------------------------------------------------
- std::string strMainWindow = TXT_MAINWINDOW_HEADER;
- ReplaceString( strMainWindow, "{WINDOW_TITLE}", this->m_vOverlay.WindowTitle );
- ReplaceString( strMainWindow, "{WINDOW_DESCRIPTION}", this->m_vOverlay.PatchDescription );
- ReplaceString( strMainWindow, "{WINDOW_NOTES}", this->m_vOverlay.PatchNotes );
- //
- // Prepare about window information.
- // ------------------------------------------------------------------
- std::string strAboutWindow = TXT_ABOUTWINDOW_HEADER;
- ReplaceString( strAboutWindow, "{ABOUT_BUTTON_ONE_TEXT}", this->m_vOverlay.ButtonOneText );
- ReplaceString( strAboutWindow, "{ABOUT_BUTTON_ONE_ACTION}", this->m_vOverlay.ButtonOneAction );
- ReplaceString( strAboutWindow, "{ABOUT_BUTTON_TWO_TEXT}", this->m_vOverlay.ButtonTwoText );
- ReplaceString( strAboutWindow, "{ABOUT_BUTTON_TWO_ACTION}", this->m_vOverlay.ButtonTwoAction );
- ReplaceString( strAboutWindow, "{ABOUT_BOX_TEXT}", this->m_vOverlay.AboutBox );
- //
- // Loop overview file entries and prepare file patches.
- // ------------------------------------------------------------------
- std::string strPatchInfo = TXT_PATCHINFO_HEADER;
- _stprintf_s( tszOutput, 1024, _T( "%d" ), this->m_vOverlay.FilesToPatch );
- ReplaceString( strPatchInfo, "{FILE_PATCH_COUNT}", tszOutput );
- for( int x = 0; x < this->m_vOverlay.FilesToPatch; x++ )
- {
- std::string strFileEntryHeader = TXT_FILEENTRY_HEADER;
- _stprintf_s( tszOutput, 1024, _T( "%d" ), ( x + 1 ) );
- ReplaceString( strFileEntryHeader, "{FILE_ENTRY_NUMBER}", tszOutput );
- ReplaceString( strFileEntryHeader, "{FILE_ENTRY_NAME}", this->m_vOverlay.FileEntries[x].FileName );
- _stprintf_s( tszOutput, 1024, _T( "%d" ), this->m_vOverlay.FileEntries[x].FilePatchCount );
- ReplaceString( strFileEntryHeader, "{FILE_ENTRY_PATCH_COUNT}", tszOutput );
- for( unsigned int y = 0; y < this->m_vOverlay.FileEntries[x].FilePatchCount; y++ )
- {
- std::string strFilePatchEntry;
- switch( this->m_vOverlay.FileEntries[x].PatchEntries[y].PatchType )
- {
- case 0: strFilePatchEntry = TXT_FILEPATCHENTRY( 0 ); break;
- case 1: strFilePatchEntry = TXT_FILEPATCHENTRY( 1 ); break;
- case 2: strFilePatchEntry = TXT_FILEPATCHENTRY( 2 ); break;
- case 3: strFilePatchEntry = TXT_FILEPATCHENTRY( 3 ); break;
- case 4: strFilePatchEntry = TXT_FILEPATCHENTRY( 4 ); break;
- case 5: strFilePatchEntry = TXT_FILEPATCHENTRY( 5 ); break;
- }
- //
- // Insert Count and Offset
- // -------------------------------------
- _stprintf_s( tszOutput, 1024, _T( "%d" ), ( y + 1 ) );
- ReplaceString( strFilePatchEntry, "{PATCH_ENTRY_NUMBER}", tszOutput );
- _stprintf_s( tszOutput, 1024, _T( "0x%08X" ), this->m_vOverlay.FileEntries[x].PatchEntries[y].PatchOffset );
- ReplaceString( strFilePatchEntry, "{PATCH_OFFSET}", tszOutput );
- //
- // Insert Patch Specific Info
- // -------------------------------------
- std::string strOrigData;
- std::string strPatchData;
- switch( this->m_vOverlay.FileEntries[x].PatchEntries[y].PatchType )
- {
- case 0:
- ConvertVector( strPatchData, this->m_vOverlay.FileEntries[x].PatchEntries[y].PatchData );
- ReplaceString( strFilePatchEntry, "{PATCH_DATA}", strPatchData );
- break;
- case 1:
- case 2:
- case 3:
- ConvertVector( strOrigData, this->m_vOverlay.FileEntries[x].PatchEntries[y].FindData );
- ConvertVector( strPatchData, this->m_vOverlay.FileEntries[x].PatchEntries[y].ReplaceData );
- ReplaceString( strFilePatchEntry, "{PATCH_FIND_DATA}", strOrigData );
- ReplaceString( strFilePatchEntry, "{PATCH_REPLACE_DATA}", strPatchData );
- break;
- case 4:
- case 5:
- break;
- }
- strFileEntryHeader += strFilePatchEntry;
- }
- strPatchInfo += strFileEntryHeader;
- }
- //
- // Write Info To file
- // -------------------------------------
- DWORD dwWritten = 0;
- WriteFile( hFileHandle, strOverview.c_str(), strOverview.size(), &dwWritten, 0 );
- WriteFile( hFileHandle, strMainWindow.c_str(), strMainWindow.size(), &dwWritten, 0 );
- WriteFile( hFileHandle, strAboutWindow.c_str(), strAboutWindow.size(), &dwWritten, 0 );
- WriteFile( hFileHandle, strPatchInfo.c_str(), strPatchInfo.size(), &dwWritten, 0 );
- //
- // Cleanup and Return
- // -------------------------------------
- CloseHandle( hFileHandle );
- hFileHandle = NULL;
- return S_OK;
- }