user99545
user99545

Reputation: 1173

Writing hex data to an executable not working? C++

I have been trying to figure out how installers work and how they bundle everything into one executable file and how to create my own. I have tried using a hex editor called HxD which allows you to export the current hex-dump of a file into a .c source file with an array containing the hex dump that looks like the below.

enter image description here

Excited, I tried to write the file using some simple C++ code:

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

... and then tried to run it.

enter image description here

After some further research it turns out that my little program is only writing the MZ. header which PE files use in windows and excluding the rest of the code. The executable that is created has a hex-dump of 4D 5A 90 or in ASCII MZ.. Is this a fault in my coding? Why won't it write the hex data? Would I need to use some lower-level writing tool or assembly? If so, are there any C/C++ libraries that allow me to write at such a level? Thanks!

Upvotes: 1

Views: 2091

Answers (2)

Alexey Ivanov
Alexey Ivanov

Reputation: 11868

A better approach to storing binary data is to use resources. Menus, icons, bitmaps are stored in resources.

You can create a custom resource and use FindResource function, LoadResource, and then LockResource to map it into memory.

Then you can do whatever you want with the data, and of course write it to a file.

Installers usually use something like this rather than embedding lots binary data in the source code. This approach has other advantages:

  • You don't have to re-convert your data into source code and then recomplile the whole application when the data changes. Only resources have to be recompiled and re-linked.
  • The resources are not loaded into memory until use the functions above, what means until you need them. Thus the application loads faster into the memory. (Resource data are actually mapped into address space right from the file.)
    With your current approach, all the data are loaded into memory, therefore your application requires more memory.

Additionally, you should better use specialized tools for creating installers.

Upvotes: 1

oddstar
oddstar

Reputation: 554

rawData is a char* and is interpreted as a character string by the streaming operator, which is terminated by the first 0x00 byte it encounters.

For binary writing, you are best off using the

ostream& write(const char*, int);

method, leading to

newbin.write(rawData, 65536);

Assuming 65536 is the actual used size of the buffer.

Hope this helps :)

Upvotes: 4

Related Questions