Запись шестнадцатеричных данных в исполняемый файл не работает? C ++ - PullRequest
1 голос
/ 16 февраля 2012

Я пытался выяснить, как работают установщики и как они объединяют все в один исполняемый файл и как создать свой собственный. Я попытался использовать шестнадцатеричный редактор под названием HxD, который позволяет вам экспортировать текущий шестнадцатеричный дамп файла в .c исходный файл с массивом, содержащим шестнадцатеричный дамп, который выглядит следующим образом.

enter image description here

В восторге, я попытался написать файл, используя простой код C ++:

ofstream newbin("test.exe", ios::binary);
newbin << hex << rawData;
newbin.close();

... а затем попытался запустить его.

enter image description here

После некоторых дальнейших исследований выясняется, что моя маленькая программа пишет только заголовок MZ., который PE-файлы используют в Windows, и исключает остальную часть кода. Созданный исполняемый файл имеет шестнадцатеричный дамп 4D 5A 90 или ASCII MZ.. Это ошибка в моем кодировании? Почему он не записывает шестнадцатеричные данные? Нужно ли использовать какой-нибудь инструмент или сборку более низкого уровня? Если так, есть ли библиотеки C / C ++, которые позволяют мне писать на таком уровне? Спасибо!

Ответы [ 2 ]

4 голосов
/ 16 февраля 2012

rawData является char* и интерпретируется как символьная строка оператором потоковой передачи, который заканчивается первым 0x00 байтом, который он встречает.

Для двоичной записи лучше всего использовать

ostream& write(const char*, int);

метод, ведущий к

newbin.write(rawData, 65536);

Предполагая, что 65536 является фактическим используемым размером буфера.

Надеюсь, это поможет:)

1 голос
/ 17 февраля 2012

Лучшим подходом к хранению двоичных данных является использование ресурсов. Меню, значки, растровые изображения хранятся в ресурсах.

Вы можете создать собственный ресурс и использовать функцию FindResource, LoadResource, а затем LockResource, чтобы отобразить его в памяти.

Затем вы можете делать с данными все, что хотите, и, конечно, записывать их в файл.

Установщики обычно используют что-то подобное, а не встраивают много двоичных данных в исходный код. Этот подход имеет и другие преимущества:

  • Вам не нужно повторно преобразовывать ваши данные в исходный код, а затем перекомпилировать все приложение при изменении данных. Только ресурсы должны быть перекомпилированы и повторно связаны.
  • Ресурсы не загружаются в память до тех пор, пока не будут использованы вышеперечисленные функции, то есть, пока они вам не понадобятся Таким образом, приложение загружается быстрее в память. (Данные ресурса фактически отображаются в адресное пространство прямо из файла.)
    При текущем подходе все данные загружаются в память, поэтому вашему приложению требуется больше памяти.

Кроме того, вам лучше использовать специализированные инструменты для создания установщиков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...