I have a string literal that's used in a number of different places around my executable.
Let's say something like:
const char *formatString = "Something I don't want to make obvious: %d";
int format1(char *buf) { sprintf(buf, formatString, 1); }
int format2(char *buf) { sprintf(buf, formatString, 2); }
//...
Now, this string literal becomes very obvious inside the executable code, because it's embedded literally.
Is there any way to avoid this by forcing the compiler to, for example, generate assembly instructions (e.g. mov [ptr + 4], 0x65
) instructions to create the strings, instead of embedding the strings literally?
I don't want to do an obfuscation of any sort -- I simply want to avoid making the string obvious inside the executable. (I also don't want to have to modify my code in every single place the string is used.)
Is this possible?
To avoid pasting encrypted strings into code by hand, you can create a macro which would mark strings that need obfuscation and a function which decrypts them:
#define OB(s) dec("START_MARK_GUID" s "\0" "END_MARK_GUID")
const char* dec(const char* s) { ... }
...
const char* s = OB("not easily readable"); // on all strings needed
const char* s = OB("either");
The function must do two things:
If the parameter starts with START_MARK_GUID, simply return the original string (without the guids). This will allow you to use unobfuscated executable too, e.g. when debugging.
If it starts with ENCRYPTED_MARK_GUID, deobfuscate first then return a new string. In C you will have to care about memory lifetime here; in C++ you could simply return std::string().
Finally, create an obfuscator program which looks for GUIDs in a compiled binary and encrypts data between them. It is only a few lines in Python or similar language. I also recommend to fix EXE's CRC back after, though my program worked even without that.
You can change guids with less unique identifiers to save some space. Also you can improve this to make decryption happen only one time (e.g. write string ID among with ENCRYPTED_MARK_GUID and keep decrypted strings in a dictionary by that ID).