0

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:

//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:

//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:

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:

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!

Jonas
  • 6,915
  • 8
  • 35
  • 53
Giovanni
  • 33
  • 8

1 Answers1

1

As far as I can tell the problem is the bit order in the dump of the bitset, the disk dump from the first fragment of code:

11001010

means that the first bit is the most significant of the byte, so to decode this you should do in the loop something like this (tested):

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);
}

Note that you cycle size/8 since every 8 chars encode a byte and the fact that the inner loop iterates from 7 to 0 to reflect the fact that the first bit is the more significant.

gabry
  • 1,370
  • 11
  • 26
  • Thank you so much for the response! I had a feeling I had to convert from bits back to bytes manually, but have not worked with that before. When I substituted your code in for my attempted for-loop, the program works perfectly. – Giovanni Jan 20 '17 at 13:39