DEV Community

Cover image for Embedding Multiples Files in an Executable - Windows - Part 3
Gurigraphics
Gurigraphics

Posted on

Embedding Multiples Files in an Executable - Windows - Part 3

This example deals with multiple files. Is now also stored:

content name size: 8 content name: data.txt content size: 10 content: 1234567890 
Enter fullscreen mode Exit fullscreen mode

This symbol is used to signal that a new file exists

std::string symbol = "^"; 
Enter fullscreen mode Exit fullscreen mode

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; } 
Enter fullscreen mode Exit fullscreen mode

2) Compile

g++ program.cpp -o program 
Enter fullscreen mode Exit fullscreen mode

3) Exec and get "file size"

program 
Enter fullscreen mode Exit fullscreen mode
file size: 168960 last byte: 00 end 
Enter fullscreen mode Exit fullscreen mode

Or get file size by cmd

for %I in (program.exe) do @echo %~zI 168960 
Enter fullscreen mode Exit fullscreen mode

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; } 
Enter fullscreen mode Exit fullscreen mode

5) Create content file: data.txt

1234567890Xkãj56 
Enter fullscreen mode Exit fullscreen mode

6) Apply patch

patch program.exe data.txt 168960 
Enter fullscreen mode Exit fullscreen mode

7) Run program.exe and get new size

program 
Enter fullscreen mode Exit fullscreen mode
file size: 168988 last byte: 5e 1----------------- content name size: 8 content name: data.txt content size: 17 content: 1234567890Xkãj56 ----------------- end 
Enter fullscreen mode Exit fullscreen mode

8) Create new content file: data2.txt

1234567890Xkãj56888 
Enter fullscreen mode Exit fullscreen mode

9) Apply patch with new size

patch program.exe data2.txt 168988 
Enter fullscreen mode Exit fullscreen mode

10) Run program.exe

program 
Enter fullscreen mode Exit fullscreen mode
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 
Enter fullscreen mode Exit fullscreen mode

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)