This example deals with multiple files. Is now also stored:
content name size: 8 content name: data.txt content size: 10 content: 1234567890
This symbol is used to signal that a new file exists
std::string symbol = "^";
1) Create program.cpp
#include <fstream> #include <iostream> #include <windows.h> #include <sstream> #include <string> #include <locale> int assetsCount = 0; std::vector<char> file_read_bin(const std::string& fileName) { std::string filePath = fileName; std::ifstream file(filePath, std::ios::binary); if (file.fail()) { std::cerr << "Erro ao abrir o arquivo " << filePath << std::endl; } // Read bytes std::vector<char> bytFile((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>()); file.close(); return bytFile; } std::string getHexValue(const std::vector<char>& bytFile, int size, int byteCount) { std::stringstream ss; ss << std::hex << std::setfill('0') << std::setw(2) << static_cast<unsigned int>(static_cast<unsigned char>(bytFile[size - byteCount])); return ss.str(); } int hexToInt(std::string hexStr) { return std::stoi(hexStr, nullptr, 16); } int getContent(std::vector<char> bytFile, int size) { if( bytFile[size - 1] != '^') { // Exist new file? std::cout << "end" << "\n"; return 0; } assetsCount+=1; std::cout << assetsCount << "-----------------" << "\n"; // Get file name size in last byte std::cout << "content name size: "; std::string sizeHex = getHexValue(bytFile, size, 2); int fileNameSize = hexToInt( sizeHex ); std::cout << fileNameSize << "\n"; // Get file name in last byte std::string fileName = "content name: "; for (int i = fileNameSize+2; i > 1; i--) { std::string byteInStringFormat; byteInStringFormat.push_back(static_cast<char>(bytFile[size - i])); // convert byte to char fileName += byteInStringFormat; } std::cout << fileName << std::endl; // Get content size in last byte std::cout << "content size: "; std::string contentSizeHex = getHexValue(bytFile, size, fileNameSize + 3); int contentSize = hexToInt( contentSizeHex ); std::cout << contentSize << "\n"; // Print content std::string content = "content: "; int contentStart = contentSize+fileNameSize+3; //9 5 for (int i = contentStart; i > fileNameSize+3; i--) { std::string byteInStringFormat; byteInStringFormat.push_back(static_cast<char>(bytFile[size - i])); // convert byte to char content += byteInStringFormat; } std::cout << content << "\n"; // End int final = size - (contentStart + 1); std::cout << "-----------------" << "\n"; getContent(bytFile, final+1); // get new file return 0; } int main(int argc, char *argv[]){ // Read file std::string filename = std::string(argv[0]) + ".exe"; std::vector<char> bytFile = file_read_bin( filename ); int size = bytFile.size(); // Logs std::cout << "file size: " << size << std::endl; std::cout << "last byte: " << getHexValue(bytFile, size, 1) << std::endl; //std::cout << "int size : " << contentSize << std::endl; // console "pt-BR" accentuation errors system("chcp 1252 > nul"); setlocale(LC_ALL, "pt_BR.UTF-8"); getContent(bytFile, size); return 0; }
2) Compile
g++ program.cpp -o program
3) Exec and get "file size"
program
file size: 168960 last byte: 00 end
Or get file size by cmd
for %I in (program.exe) do @echo %~zI 168960
4) Create patch.cpp
#include <fstream> #include <iostream> #include <string> #include <vector> #include <sstream> std::vector<char> file_read_bin(const std::string& fileName) { std::string filePath = fileName; std::ifstream file(filePath, std::ios::binary); if (file.fail()) { std::cerr << "Erro ao abrir o arquivo " << filePath << std::endl; } // Read bytes std::vector<char> bytFile((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>()); file.close(); return bytFile; } void file_write_bin(const std::string& filePath, std::vector<char> bytFile) { // Write bytes std::ofstream outFile(filePath, std::ios::binary); if (outFile.fail()) { std::cerr << "Erro ao abrir o arquivo " << filePath << " para escrita" << std::endl; } outFile.write(bytFile.data(), bytFile.size()); outFile.close(); std::cout << "Arquivo alterado com sucesso" << std::endl; } int main(int argc, char *argv[]){ if (argc != 4) { std::cout << "Require 3 args: program.exe data.txt 163857\n"; return 1; } const char* program_file = argv[1]; const char* data_file = argv[2]; std::vector<char> bytFile = file_read_bin( program_file ); std::vector<char> bytText = file_read_bin( data_file ); int correctSize = std::stoi(argv[3]); int size = bytFile.size(); int diff = size - correctSize; // Logs std::cout << "size: " << size << "\n"; std::cout << "correctSize: " << correctSize << "\n"; // Remove old code if(size > correctSize ){ bytFile.erase(bytFile.end() - diff, bytFile.end() ); } // Add content bytFile.insert(bytFile.end(), bytText.begin(), bytText.end()); // Add content size bytFile.insert( bytFile.end(), bytText.size() ); // Add file name std::string data_filename_str(data_file); data_filename_str+="\0"; bytFile.insert(bytFile.end(), data_filename_str.c_str(), data_filename_str.c_str() + data_filename_str.size() ); // Add name size bytFile.insert( bytFile.end(), data_filename_str.size() ); // Add symbol exist new file std::string symbol = "^"; bytFile.insert(bytFile.end(), symbol.c_str(), symbol.c_str() + symbol.size() ); // Rewrite file_write_bin(program_file, bytFile); return 0; }
5) Create content file: data.txt
1234567890Xkãj56
6) Apply patch
patch program.exe data.txt 168960
7) Run program.exe and get new size
program
file size: 168988 last byte: 5e 1----------------- content name size: 8 content name: data.txt content size: 17 content: 1234567890Xkãj56 ----------------- end
8) Create new content file: data2.txt
1234567890Xkãj56888
9) Apply patch with new size
patch program.exe data2.txt 168988
10) Run program.exe
program
file size: 169020 last byte: 5e 1----------------- content name size: 9 content name: data2.txt content size: 20 content: 1234567890Xkãj56888 ----------------- 2----------------- content name size: 8 content name: data.txt content size: 17 content: 1234567890Xkãj56 ----------------- end
Embedding Big Files in an Executable - Windows - Part 4
https://dev.to/gurigraphics/embedding-big-files-in-an-executable-windows-part-4-25hf
Top comments (0)