@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

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

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

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

В этом случае, надо изучить устройство PE файла, понимать немного ассемблера.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Vapaamies
@Vapaamies
Психанул и снес свои ответы козлам, не отмечающим…
Речь про инъекцию? Гуглить про инъекцию. Дописывание байтов в конец не поможет, обязательно нужно учитывать структуру ELF или PE, что у вас там? В PE в конце файла будут перемещаемые символы («релоки») или ресурсы. Для правильной склейки файл еще придется перебазировать.
Ответ написан
mayton2019
@mayton2019
Bigdata Engineer
Самый простой вариант - редактирование сегмента данных не трогая код. Забиваешь
нулями дополнительный резерв места в строке.

section .data
    error_message db "Hello byte, hello word", 0, 0,0,0,0,0,0,0,0,0,0,0,0


Потом в hex редакторе просто передвигаешь слово вправо не забывая что ASCIIZ строка обязательно
должна закончистя нулем.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы