2

I'm trying to learn how to crack file formats, so I started with a simple example I've taken from there: How to read / write a struct in Binary Files?

#include <fstream>
#include <iostream>
#include <vector>
#include <string.h>

using namespace std;


typedef struct student
{
    char name[10];
    double age;
    vector<int> grades;
}student_t;

void readBinaryFile(string filename)
{
    ifstream input_file(filename, ios::binary);
    student_t master[3];
    input_file.read((char*)&master, sizeof(master));

    for (size_t idx = 0; idx < 3; idx++)
    {
        // If you wanted to search for specific records, 
        // you should do it here! if (idx == 2) ...

        cout << "Record #" << idx << endl;
        //cout << "Capacity: " << master[idx].grades.capacity() << endl;
        cout << "Name: " << master[idx].name << endl;
        cout << "Age: " << master[idx].age << endl;
        cout << "Grades: " << endl;

        for (size_t i = 0; i < master[idx].grades.size(); i++)
           cout << master[idx].grades[i] << " ";
        cout << endl << endl;
    }
    input_file.close();
}

int main()
{
    student_t apprentice[3];  
    strcpy(apprentice[0].name, "john");
    apprentice[0].age = 21;
    apprentice[1].grades.push_back(1);
    apprentice[1].grades.push_back(2);
    apprentice[1].grades.push_back(3);

    strcpy(apprentice[1].name, "jerry");
    apprentice[1].age = 22;
    apprentice[0].grades.push_back(4);
    apprentice[0].grades.push_back(5);
    apprentice[0].grades.push_back(6);

    strcpy(apprentice[2].name, "jimmy");
    apprentice[2].age = 24;
    apprentice[2].grades.push_back(7);
    apprentice[2].grades.push_back(8);
    apprentice[2].grades.push_back(9);

    string filename = "students2.data";
    // Serializing struct to student.data
    ofstream output_file(filename, ios::binary);
    output_file.write((char*)&apprentice, sizeof(apprentice));
    output_file.close();

    // Reading from it
    readBinaryFile(filename);

    system("pause");
    return 0;
}

I can write the file and read it correctly, and when I open it in an hex editor, I get this:

6a 6f 68 6e 00 cc cc cc cc cc cc cc cc cc cc cc
00 00 00 00 00 00 35 40 40 59 84 00 80 cf 84 00
8c cf 84 00 8c cf 84 00 6a 65 72 72 79 00 cc cc
cc cc cc cc cc cc cc cc 00 00 00 00 00 00 36 40
50 85 84 00 60 d0 84 00 6c d0 84 00 6c d0 84 00
6a 69 6d 6d 79 00 cc cc cc cc cc cc cc cc cc cc
00 00 00 00 00 00 38 40 50 79 84 00 b8 cf 84 00
c4 cf 84 00 c4 cf 84 00

I can clearly find the names (6a 6f 68 6e 00 cc cc cc cc cc), and ages (00 00 00 00 00 00 35 40), but I have a lot more trouble finding the grades values. I thought by making a second files with different values I could find the differences, but I found something I don't understand instead. By changing the first student to:

strcpy(apprentice[0].name, "john");
apprentice[0].age = 21;
apprentice[1].grades.push_back(1);
apprentice[1].grades.push_back(2);
apprentice[1].grades.push_back(3);
apprentice[1].grades.push_back(4);
apprentice[1].grades.push_back(5);
apprentice[1].grades.push_back(6);

I expected to get a bigger file, but its size doesn't change:

6a 6f 68 6e 00 cc cc cc cc cc cc cc cc cc cc cc
00 00 00 00 00 00 35 40 40 59 8e 00 48 cf 8e 00
54 cf 8e 00 54 cf 8e 00 6a 65 72 72 79 00 cc cc
cc cc cc cc cc cc cc cc 00 00 00 00 00 00 36 40
50 85 8e 00 88 79 8e 00 ac 79 8e 00 ac 79 8e 00
6a 69 6d 6d 79 00 cc cc cc cc cc cc cc cc cc cc
00 00 00 00 00 00 38 40 50 79 8e 00 98 d0 8e 00
a4 d0 8e 00 a4 d0 8e 00

How is that possible? I even tried with a vector with 60+ elements and the file would still remain the same size... Any help would be appreciated!

EDIT: As tux3 pointed out, I'm not actually saving my vectors to binary. I should have paid more attention to the code I copied, my bad.

Community
  • 1
  • 1
MyUsername112358
  • 1,320
  • 14
  • 39
  • I'm not having trouble serializing or unserializing a vector though, I'm trying to understand what is happening when I do. – MyUsername112358 Jun 13 '15 at 20:18
  • 2
    @MyUsername112358 `I'm not having trouble` Yes you have, but you don´t understand it. See the first answer. – deviantfan Jun 13 '15 at 20:20
  • Well, I understand that the code I copied from an accepted answer is wrong, but that still doesn't mean I'm trying to serialize a vector. The answers found in the reply is not the answer I was looking for. – MyUsername112358 Jun 13 '15 at 20:22
  • 2
    actually saving the structure into a file is serializing it. – Hauke S Jun 13 '15 at 20:30
  • 1
    And *proper* serialization doesn´t save whole `std::vectors`, because the content is as implementation-defined as possible. First steo: Treating each element in the vector separately (but this is far from enough). Read a book about serialization. – deviantfan Jun 13 '15 at 20:37
  • I know, that was not my point... All I'm saying is that while making the question I was not looking on how to serialize a vector because I didn't pay attention to the code I copied and simply thought they had it right. The answer to my question is "You got your vector serialization wrong", not "[How to serialize a vector]". – MyUsername112358 Jun 13 '15 at 20:39
  • Please read up on ser. nonetheless. – deviantfan Jun 13 '15 at 20:40

1 Answers1

5

output_file.write((char*)&apprentice, sizeof(apprentice));

This is not going to do what you think. std::vector puts its data on the free store, not in the object itself like an array.

So here you're only writing the vector's metadata (its size, capacity, a pointer to the data, ...), but not the data itself.

tux3
  • 7,171
  • 6
  • 39
  • 51
  • Ugh, you are right... I should have paid more attention to the link I copied my code from -_-. I will accept your answer as soon as it's possible to do so. – MyUsername112358 Jun 13 '15 at 20:20