Embedding Multiples Files in an Executable - Windows - Part 3
Gurigraphics
Posted on March 19, 2023
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
💖 💪 🙅 🚩
Gurigraphics
Posted on March 19, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.