В этой статье я покажу и разжую как написать легкий биндер exe-файлов на C++ -2 руки (минимум по одному пальцу на каждой) -Visual studio любой версии (у меня 2017) Создаем проект Жмем вверху Файл -> Создать -> Проект Выбираем C++, консольное приложение, вводим желаемое имя файла и жмем ок Фото Отлично. Самое сложное позади. По статистике 99% людей заваливаются уже на этапе создания проекта Пишем Joiner-упаковщик Джойним файлы 2.1 Импортируем нужные нам библиотеки: Библиотеки 1 библиотека дефолтная. 2 библиотека нужна для работы с файлами. 3 библиотека нужна для вывода\считывания чего либо в консоли. 2.2 Ставим setlocale для того чтобы консоль поддерживала русский язык setlocale(LC_ALL, "ru"); Код setlocale(LC_ALL, "ru"); 2.3 Обьявляем нужные нам переменные: char ch; char star = '*'; char file1[_MAX_PATH]; char file2[_MAX_PATH]; Код char ch; char star = '*'; char file1[_MAX_PATH]; char file2[_MAX_PATH]; 2.4 Просим пользователя ввести пути до файлов: cout << "Путь к первому файлу: "; cin >> file1; cout << "Пусь ко второму файлу: "; cin >> file2; Код cout << "Путь к первому файлу: "; cin >> file1; cout << "Пусь ко второму файлу: "; cin >> file2; 2.5 Обьявляем файл где будут наши вклеенные exe и открываем для чтения файлы: ofstream Mix("Joined.exe", ios_base::binary); //Файл для записи наших exe ifstream nullBytes("src\\null.exe", ios_base::binary); ||файл который будет вытаскивать наши exe | о нем позже ifstream firstFile(file1, ios_base::binary); ||первый exe ifstream secondFile(file2, ios_base::binary);||второй exe Код ofstream Mix("Joined.exe", ios_base::binary); //Файл для записи наших exe ifstream nullBytes("src\\null.exe", ios_base::binary); ||файл который будет вытаскивать наши exe | о нем позже ifstream firstFile(file1, ios_base::binary); ||первый exe ifstream secondFile(file2, ios_base::binary);||второй exe 2.6 Начинаем клеить файлы, сначала запишем наш распаковщик: //Записываем распаковщик while (!nullBytes.eof()) { || eof - чтение до конца файла nullBytes.get(ch); ||в ch записывается прочтенный байт Mix << ch;||записываем байт } Код //Записываем распаковщик while (!nullBytes.eof()) { || eof - чтение до конца файла nullBytes.get(ch); ||в ch записывается прочтенный байт Mix << ch;||записываем байт } 2.7 Чтобы распаковщик знал где кончаются байты очередного exe пишем разделитель: for (int i = 0; i < 5; i++) { Mix << star; } nullBytes.close(); Код for (int i = 0; i < 5; i++) { Mix << star; } nullBytes.close(); 2.8 Склеиваем файлы: //Записываем первый файл Mix.clear(); Mix.seekp(0, ios_base::end); while (!firstFile.eof()) { firstFile.get(ch); Mix << ch; } for (int i = 0; i < 5; i++) { Mix << star; } firstFile.close(); //Записываем первый файл //Записываем второй файл Mix.clear(); Mix.seekp(0, ios_base::end); while (!secondFile.eof()) { secondFile.get(ch); Mix << ch; } secondFile.close(); Mix.close(); //Записываем второй файл return 0; Код //Записываем первый файл Mix.clear(); Mix.seekp(0, ios_base::end); while (!firstFile.eof()) { firstFile.get(ch); Mix << ch; } for (int i = 0; i < 5; i++) { Mix << star; } firstFile.close(); //Записываем первый файл //Записываем второй файл Mix.clear(); Mix.seekp(0, ios_base::end); while (!secondFile.eof()) { secondFile.get(ch); Mix << ch; } secondFile.close(); Mix.close(); //Записываем второй файл return 0; Наш распаковщик готов и теперь у нас есть склеенные файлы. Теперь при запуске мы должны их достать и запустить. Пишем распаковщик Код распаковщика Распаковщик мы добавляли во 2 этапе. Мы записывали его перед файлами Теперь приступим к его реализации: 3.1 Создаем новый проект аналогично упаковщику 3.2 добавляем библиотеки, также обьявляем буффер: #include "stdafx.h" #include "windows.h" #include "Processthreadsapi.h" #include <fstream>; #include <iostream> #include <list> #define BUFFER 8192; Код #include "stdafx.h" #include "windows.h" #include "Processthreadsapi.h" #include <fstream>; #include <iostream> #include <list> #define BUFFER 8192; 3.3 При запуске прячем окно консоли: ShowWindow(GetConsoleWindow(), SW_HIDE); Код ShowWindow(GetConsoleWindow(), SW_HIDE); 3.4 Обьявляем нужные нам переменные: char value[MAX_PATH]; DWORD buffSize = BUFFER; string s = ""; Код char value[MAX_PATH]; DWORD buffSize = BUFFER; string s = ""; 3.5 Т.к. распаковывать файлы прямо в ту же папку где и запускается наш сшитый файл мы не можем по понятным причинам, мы должны распаковать их туда где их не будет видно. Т.к. моя любимая папка %localappdata% то в нее мы и будем все расспаковывать. В C\C++ я не нашел работающих функций для получения пути к папке, поэтому мы будем доставать путь через реестр: RegGetValueA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Backup", "Local AppData", RRF_RT_ANY, NULL, (PVOID)&value, &buffSize) Код RegGetValueA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Backup", "Local AppData", RRF_RT_ANY, NULL, (PVOID)&value, &buffSize) 3.6 Теперь путь сохранен в массиве value[], сохраним путь в строку ибо так удобнее будет потом с ним работать: for (char i : value) { if (i == NULL) { break; } s += i; } Код for (char i : value) { if (i == NULL) { break; } s += i; } 3.7 Обьявляем переменные и открываем файлы для записи: string file1 = "\\source1.exe"; string file2 = "\\source2.exe"; ifstream null(argv[0], ios_base::binary); ofstream firstFile(s+file1, ios_base::binary); ofstream secondFile(s+file2, ios_base::binary); char ch; int i = 0; int endOfNull; int endOfFirst; Код string file1 = "\\source1.exe"; string file2 = "\\source2.exe"; ifstream null(argv[0], ios_base::binary); ofstream firstFile(s+file1, ios_base::binary); ofstream secondFile(s+file2, ios_base::binary); char ch; int i = 0; int endOfNull; int endOfFirst; 3.8 Далее мы начинаем читать байты из себя: //Игнорируем байты нашего распаковщика while (true) { null.get(ch); if (ch == '*') { i++; if (i == 5) { endOfNull = null.tellg(); break; } } if (ch != '*') { i = 0; } } //Игнорируем байты нашего распаковщика //байты первого файла while (true) { null.get(ch); if (ch == '*') { i++; if (i == 5) { endOfFirst = null.tellg(); break; } } if (ch != '*') { i = 0; } } //байты первого файла null.seekg(endOfNull, ios_base::beg); //запоминаем местоположение 1-го файла //Достаем первый файл for (int i = endOfNull; i < endOfFirst; i++) { null.get(ch); firstFile << ch; } firstFile.close(); //Достаем первый файл null.seekg(endOfFirst, ios_base::beg); //устанавливаем чтение с начала файла | не спрашивайте, просто нужно //Достаем второй файл while (!null.eof()) { null.get(ch); secondFile << ch; } secondFile.close(); //Достаем второй файл null.close(); Код //Игнорируем байты нашего распаковщика while (true) { null.get(ch); if (ch == '*') { i++; if (i == 5) { endOfNull = null.tellg(); break; } } if (ch != '*') { i = 0; } } //Игнорируем байты нашего распаковщика //байты первого файла while (true) { null.get(ch); if (ch == '*') { i++; if (i == 5) { endOfFirst = null.tellg(); break; } } if (ch != '*') { i = 0; } } //байты первого файла null.seekg(endOfNull, ios_base::beg); //запоминаем местоположение 1-го файла //Достаем первый файл for (int i = endOfNull; i < endOfFirst; i++) { null.get(ch); firstFile << ch; } firstFile.close(); //Достаем первый файл null.seekg(endOfFirst, ios_base::beg); //устанавливаем чтение с начала файла | не спрашивайте, просто нужно //Достаем второй файл while (!null.eof()) { null.get(ch); secondFile << ch; } secondFile.close(); //Достаем второй файл null.close(); 3.9 И начинаем запуск наших файлов, дальше без комментариев: //Запускаем файлы list<char> mylist; list<char> mylist2; for (int i = 0; i < sizeof(value); i++) { if (value[i] == NULL) { break; } mylist.push_back(value[i]); } mylist2 = mylist; for (char i : file1) { mylist.push_back(i); } for (char i : file2) { mylist2.push_back(i); } //char* buff = new char[MAX_PATH]; int suk1 = 0; char suk[100]; for (char i : mylist) { suk[suk1] = i; suk1++; } for (int i = suk1; i < sizeof(suk); i++) { suk[i] = 0; } STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); if (!CreateProcess(suk, NULL, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &si, &pi)){} WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); suk1 = 0; for (char i : mylist2) { suk[suk1] = i; suk1++; } for (int i = suk1; i < sizeof(suk); i++) { suk[i] = 0; } if (!CreateProcess(suk, NULL, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &si, &pi)){} WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return 0; Код //Запускаем файлы list<char> mylist; list<char> mylist2; for (int i = 0; i < sizeof(value); i++) { if (value[i] == NULL) { break; } mylist.push_back(value[i]); } mylist2 = mylist; for (char i : file1) { mylist.push_back(i); } for (char i : file2) { mylist2.push_back(i); } //char* buff = new char[MAX_PATH]; int suk1 = 0; char suk[100]; for (char i : mylist) { suk[suk1] = i; suk1++; } for (int i = suk1; i < sizeof(suk); i++) { suk[i] = 0; } STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); if (!CreateProcess(suk, NULL, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &si, &pi)){} WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); suk1 = 0; for (char i : mylist2) { suk[suk1] = i; suk1++; } for (int i = suk1; i < sizeof(suk); i++) { suk[i] = 0; } if (!CreateProcess(suk, NULL, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &si, &pi)){} WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return 0; Как оно должно работать Для работы упаковщика нужен распаковщик. И он должен находится в папке src Рядом с упаковщиком. После ввода обоих файлов консоль закрывается и в папке появляется сшитый файл Код полностью рабочий, тестился, проверялся и доведен со совершенства. Спасибо всем кто дочитал и что-то понял. А если не поняли, то все равно спасибо. Также спасибо MamkinHacker777 за оформление