-1

I would like to obtain this hex notation for a binary I enter in parameter:

The output I obtain and what I want:

enter image description here

This is the code I written, I don't have the good hex number (for the part after 5A) , what I am doing wrong ? How to convert properly the byte I read to hex ? Thanks.

int main(int argc, char *argv[])
{

    std::string parameter = "The\\Path\\To\My\exe.exe";
    ifstream::pos_type size;
    char * memblock;

    ifstream file(parametre, ios::in | ios::binary | ios::ate);
    if (file.is_open())
    {
        size = file.tellg();
        memblock = new char[size];
        file.seekg(0, ios::beg);
        file.read(memblock, size);
        file.close();

        cout << "the complete file content is in memory" << endl;
        string str = string(memblock, size);
        string hexContent = "";
        int maxColumn = 0;

        std::stringstream ss;
        int column = 0;
        for (int i = 0; i < size; ++i) 
        {       
            ss << std::hex << (int)str[i];
            if (column == 8)
            {
                ss << '\n';
                column = 0;
            }
            column++;

        }

        std::string mystr = ss.str();
        cout << mystr;
    }
    return 0;
}
user4581301
  • 33,082
  • 7
  • 33
  • 54

1 Answers1

1

Looks like char is signed on your system and you are the victim of sign extension. For example 0x90 is a negative, so when it's converted into an int, that negativity has to be carried through, resulting in 0xffffff90.

Solution

Read the file into unsigned char, or uint8_t from <cstdint> if it is available, instead of an array of char.

char * memblock;

becomes

uint8_t * memblock;

then

memblock = new char[size];  

becomes

memblock = new uint8_t[size];  

and don't convert it into a string later.

string str = string(memblock, size);

is pointless, you could just as easily have read from memblock, and undoes the unsigned-ness we've established earlier. Just read out of memblock

Do not forget to

delete[] memblock;

when you are done. That leads to

Better solution

Use a std::vector. It cleans up after itself.

std::vector<uint8_t> memblock(size);
file.seekg(0, ios::beg);
file.read(reinterpret_cast<char*>(memblock.data()), size); 
//or file.read(reinterpret_cast<char*>(&memblock[0]), size); if no or data method 
Community
  • 1
  • 1
user4581301
  • 33,082
  • 7
  • 33
  • 54
  • Thanks for your help, I obtain `0x4d,0x5a,0x90,0x0,0x3,0x0,0x0,0x0,0x4...` instead of `0x4D,0x5A,0x90,0x00, 0x03,0x00,0x00,0x00, 0x04...` Do you know why the first 0 of my numberis truncated ? Thanks. – Timtim45687 Sep 27 '18 at 20:45
  • You need to use a few additional IO manipulators in addition to `std::hex`. See [How can I pad an int with leading zeros when using cout << operator?](https://stackoverflow.com/questions/1714515/how-can-i-pad-an-int-with-leading-zeros-when-using-cout-operator) for more details. – user4581301 Sep 27 '18 at 20:52