0

Okay, so I'm having a little bit of a problem here.

What I'm doing is converting a binary file (in this example I used a .exe file) to a Base64 string and then converting this one back to binary data to write it to the disk.

So far so good, this code works:

std::string str = base64_decode(base64str); // base64str is the base64 string made of the actual .exe file
std::ofstream strm("file.exe", std::ios::binary);
strm << str;
strm.close();

The file "file.exe" is being created as expected and I can run it.

Now my problem is that I need the decrypted file as char* instead of std::string, but whenever I call this code

str.c_str();

to either convert it to const char* or char* the contents suddenly no longer equal the binary data contained in str, but rather this:

MZP

So, for instance the following code

std::string str = base64_decode(base64str);
std::ofstream strm("file.exe", std::ios::binary);
char* cstr = new char[str.length()-1];
strcpy(cstr, str.c_str());
strm << cstr;
strm.close();

would create file.exe, but this time it would contain "MZP" instead of the actual binary data

I have no clue on how to fix this. Of course the char* is mandatory.

Can any of you help?

2
  • 7
    strcpy(cstr, str.c_str()); will stop copying after hitting the first null byte, of which there are probably hundreds in your binary file. Commented Oct 31, 2014 at 2:04
  • 2
    Don't use strm << cstr it will stop at the first null. Use strm.write(). Commented Oct 31, 2014 at 3:58

2 Answers 2

2

std::string::c_str() returns a "C string", which is a NUL-terminated array of characters. Your binary data certainly has NUL terminators in it, prior to the end of the data. This is why your data appears truncated. (Look in a hex editor, I bet byte 0x03 is zero.)

For that reason, you should instead use std::basic_string::data to get a pointer to the raw data contained by the string. When copying or writing this data, you'll want to not use strcpy (which stops at a NUL byte), but rather memcpy, or similar. The size of the data contained by the string can be gotten from std::basic_string::size.

Sign up to request clarification or add additional context in comments.

4 Comments

Okay, I now have std::basic_string<char> dec = base64_decode(base64str); char* cdec = new char[dec.size()]; memcpy(cdec, dec.data(), dec.size()); Though, it still outputs "MZP" :/
NOTE: I just tested it, dec.data() also seems to output "MZP"
NOTE2: dec.data() seems to work fine after changing stm << cdec to strm.write(dec.data(), dec.size()), but strm.write(cdec, sizeof(cdec)) still does not work ("MZP" thing)
cdec is a char*. sizeof(char*) is 4. Use dec.size() instead of sizeof(cdec).
0

If you want the data inside a std::string as a char*, you can just grab it. Either:

std::string s = ...

char* c1 = &s[0];
char* c2 = const_cast<char*>(s.c_str());
char* c3 = &s.front();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.