Задать вопрос
@8iKS

Как «склеить» два файла?

Передо мной стоит задача, нужно склеить два файла в один не прибегая к использованию стороннего ПО по типу архиваторов, упаковщиков, инсталлеров и прочего. В руках может быть только HeX Editor и, судя по всему, святая вода.

Давайте с самого начала. В первую очередь создадим два разных файла
1)
#include <iostream>

using std::cout;
using std::endl;
using std::cin;

int main()
{
	cout << "Hello, World!" << endl;
	int i;
	cin >> i;
	return 0;
}


2)
#include <iostream>

using std::cout;
using std::endl;
using std::cin;

int main()
{
	cout << "Evil Hello World" << endl;
	int i;
	cin >> i;
	return 0;
}


После компиляции мы сразу же забываем о существовании сорс кода и работаем только со скомпилированными версиями файлов. Возвращаясь к сути вопроса, как склеить два файла в один? Из идей были следующие варианты:

1)
Просто скопировать байты второй программы и записать их в первую программу перезаписывая при этом нулевые байты которое находятся в самом конце (идея плохая ведь программа не найдет инструкций на дальнейшее выполнение и просто завершиться)
2)
Сделать тоже самое что в первом пункте НО при этом прочитать AddressOfEntryPoint второй программы и добавить инструкцию на ее выполнение

B8 00 10 40 00 00 00 00 00  ; mov rax, ImageBase + AddressOfEntryPoint (0000000140001550)
FF D0                       ; call rax


Но появляется несколько вопросов
I
Где конкретно должна располагаться такая инструкция
II
Что если две программы имею одинаковый AddressOfEntryPoint

Если кто-то сталкивался с подобной задачей или просто имеет большой опыт, то буду рад любой помощи и критике (даже камнями кидаться можете, ведь я не позиционирую себя как гуру программист, а лишь любитель)
  • Вопрос задан
  • 422 просмотра
Подписаться 1 Средний 2 комментария
Решение пользователя Wataru К ответам на вопрос (3)
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Большой и сложный бинарник вы так не встроите. Максимум, отдельные функции.

Для винды можно ваш второй файл сделать в виде dll и выпоннять код во время ее загрузки. Чуть подправить исполняемый файл или вообще просто положить dll-ку рядом с exe-шником - и библиотека загрузится.

Или можно найти пустое место в целевом файле в секции кода. Воткнуть туда вашу функцию и поменять точку входа на нее (а сама функция потом прыгает на изначальную точку входа). Если места нет, то придется увеличивать секцию кода.

В этом случае, надо изучить устройство PE файла, понимать немного ассемблера.
Ответ написан
Комментировать