C++ Writing Binary Dump and Writing to Binary from Dump

I am stumped and need some assistance.
In one of my programs, I am implementing some code so that I can take a program on Windows and essentially do a hexdump (what you see in hex editors) where I convert it to binary and write that to a .txt document. I just recently got that half figured out. The other half of the code is to rebuild an object that has been dumped to binary in .txt file into the original object. This should work for all objects in general and not just rebuilding one certain object.

Partial Code for Dumping Part:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//Rip Program to Binary
    	
    			streampos size; //Declare size variable
    		    unsigned char* memblock; //Holds input
    			ifstream input; //Declare ifstream
    			ofstream output("output.txt", ios::out|ios::binary); //Specify ofstream
    			input.open("sparktools.bin", ios::in|ios::binary|ios::ate); //Open input file and move to the end of it
    
    		    size = input.tellg(); //Store current location as file length
    		    memblock = new unsigned char [size]; //Declare the input holder with array size as length of file
    		    input.seekg (0, ios::beg); //Return to beginning of file
    		    
    			input.read((char*)memblock, size); //Read each character of the input file until end of file
    			
    			for (int i=0; i<size; i++) //For each character until end of file:
    			{	
    				std::bitset<sizeof(char) * CHAR_BIT> binary(memblock[i]); //Set bitset<1> to essentially convert to a binary char array
    				output << binary; //Output from binary variable created
    		    }
    
    			input.close();
    			output.close();
    			delete[] memblock;



Partial Code for Rebuilding Part:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//Restore Ripped Binary To Program

    			int size; //Holds length of input document
    			unsigned char* memblock; //Holds input
    			ifstream input; //Declare ifstream
    			ofstream output("Binary.bin", ios::out|ios::binary); //Specify ofstream
    			input.open("Binary.txt", ios::in|ios::binary|ios::ate); //Open input file and move to the end of it
    			
    			size = input.tellg(); //Store current location as file length
    			input.seekg(0, ios::beg); //Return to beginning of file
    			memblock = new unsigned char [size]; //Declare the input holder with array size as length of file
    			input.read((char*)memblock, size); //Read each character of the input file until end of file
    
    			for (int i=0; i<size; i++) //For each character until end of file:
    			{
    				output.write((char*) &memblock[i], size); //Write each char from the input array one at a time until end of file to the output binary
    
    			}
    	
    			input.close();
    			output.close();
    			delete[] memblock;



I am testing the capabilities on an image. The original filesize is 10 KB. When dumped, the .txt file is 76 KB and the contents match what shows in a hex editor.

When I am rebuilding from the binary dump, the filesize will not go back to 10 KB. When I up the bitset number, the file size increases. However, at bitset<1> it stays at 76 KB. From my conclusion, I essentially need bitset <0.125> to reduce the filesize from 76KB back down to 10 KB and the numbers should match up and it can simply be renamed from .bin to .whatever-it-originally-was and function correctly. However I don’t think bitset goes below 1.

Code I have tried:

1
2
3
4
5
6
43555 KB: output.write((char*)&memblock[i], size);
    0 KB: output.write((char*)memblock[i], size);
    43555 KB: output.write((const char*)&memblock[i], size);
    43555 KB: output.write(reinterpret_cast<const char*>(&memblock[i]), size);
    43555 KB: output.write(reinterpret_cast<char*>(&memblock[i]), size);
    76 KB: output << memblock[i];


When I do these simple checks:

1
2
 cout << memblock[i];
    cout << size;


I am seeing that all of the input has been read in and is identical to what is in the file. The size variable is correct at 77296.

From doing some guesswork, I think I need to do something with bitset or else manually convert from bits back to bytes, convert, and then pass that value on to accomplish this. Am I on the right path or is there a better/easier way/something wrong in my code? Thanks in advance for the help!
Last edited on
The binary text dump contains 8-bit characters -- either the character '0' or '1' -- very roughly 80000 of them. That corresponds to a file that's 8 times bigger than the original 10K binary file.

You don't need a bitset that contains an eighth of a bit, you need to construct an integer from the string representation of 8 bits at a time -- to reconstruct the original byte from the 8-byte text representation.

Read the binary text dump 8 characters at a time into a string. Construct a bitset<8> from that string (there's a constructor to do this). Use the bitset to get back your original byte, and write it out.

Here's a demo; the assumption is that you already have read 8 bytes at a time. If you have trouble with that, ask.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# include <iostream>
# include <bitset>
# include <vector>

// 8-character groupings of text from your binary dump. 
// This dump corresponds to the C-string `Hello World!'.
std::vector<std::string> const binary_text_dump =
{"01001000", "01100101", "01101100", "01101100",
 "01101111", "00100000", "01010111", "01101111",
 "01110010", "01101100", "01100100", "00100001",
 "00000000"};
 
// Step 1:  Separate the contents of your dump into fixed size bits.
//   We know the file size is always a multiple of 8 bytes, so 8 character
//   blocks are the simplest solution. 
// Step 2:  Use a bitset to get from those to a single byte.
// Step 3:  Write out each byte.
# include <climits>
int main() {
    constexpr int sz = CHAR_BIT;
    for (auto const s: binary_text_dump) 
        std::cout.put(std::bitset<sz>{s}.to_ulong() &~ '\0');
}

http://coliru.stacked-crooked.com/a/d198dce8b0cde7b7

P.S.: from your numbers, the correct units are kibibytes (KiB), not kilobytes. Pedantic, usually, but it actually matters in computer science.
Last edited on
Hey, thanks for the response! The process makes sense, I'm just not too sure how to put it into code or how to use vectors.
I tried implementing some here, and my program just stopped responding. Any ideas?

1
2
3
4
5
6
7
                unsigned char bytes[size/8];
					
		for(i=0; i<size; i+=8)
		{
			input.read((char*)&bytes[i], 8);
			cout << bytes[i] << " ";
		}
A solution has been implemented and I am posting if anyone needs the help in the future with this type of binary work. Some partial code was provided by user gabry:

1
2
3
4
5
6
7
8
9
10
11
unsigned char *p = memblock;
//For each character until end of file:
for (int i=0; i<size/8; i++)  
{
    uint8_t byte = 0;
    for (int j = 7; j >= 0; j--) 
        if (*p++ == '1')
            byte |= (1 << j);

    output.write((char*) &byte, 1);
}


When that is substituted for my attempted for-loop, the program works perfectly.
Topic archived. No new replies allowed.