Задать вопрос
@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

Если кто-то сталкивался с подобной задачей или просто имеет большой опыт, то буду рад любой помощи и критике (даже камнями кидаться можете, ведь я не позиционирую себя как гуру программист, а лишь любитель)
  • Вопрос задан
  • 290 просмотров
Подписаться 1 Средний 2 комментария
Решения вопроса 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 строка обязательно
должна закончистя нулем.
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы