How to hide strings in a exe or a dll?
I discovered that it is possible to extract the hard-coded strings from a binary.
For example the properties view of Process Explorer displays all the string with more than 3 characters.
Here is the code of a simple executable that I wrote to simply test it:
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
_TCHAR* hiddenString1 =_T("4537774B-CC80-4eda-B3E4-7A9EE77991F5");
_TCHAR* hiddenString2 =_T("hidden_password_or_whatever");
for (int i= 0; i<argc; i++) {
if (0 == _tcscmp(argv[i],hiddenString1)) {
_tprintf (_T("The guid argument is correct.\n")); }
else if (0 == _tcscmp(argv[i],hiddenString2)) {
_tprintf (_T("Do something here.\n")); }
}
_tprintf (_T("This is a visible string.\n"));
//Keep Running
Sleep(60000);
return 0;
}
The strings can clearly be extracted from the corresponding executable:
I think that it is a little too easy to find the strings.
My questions are:
- How to simply hide hiddenString1 or hiddenString2 in the executable?
- Is there a more secure way to use "cheat code" than with some obscure hidden input?
Solution 1:
Welcome to the wider world of defensive programming.
There are a couple of options, but I believe all of them depend on some form of obfuscation; which, although not perfect, is at least something.
Instead of a straight string value you can store the text in some other binary form (hex?).
You can encrypt the strings that are stored in your app, then decrypt them at run time.
You can split them across various points in your code, and reconstitute later.
Or some combination thereof.
Bear in mind, that some attacks go further than looking at the actual binary. Sometimes they will investigate the memory address space of the program while it's running. MS came up with something called a SecureString in .Net 2.0. The purpose being to keep the strings encrypted while the app is running.
A fourth idea is to not store the string in the app itself, but rather rely on a validation code to be submitted to a server you control. On the server you can verify if it's a legit "cheat code" or not.
Solution 2:
There are many ways to obscure data in an executable. Others here have posted good solutions -- some stronger than others. I won't add to that list.
Just be aware: it's all a cat-and-mouse game: it is impossible to guarantee that nobody will find out your "secret".
No matter how much encryption or other tricks you use; no matter how much effort or money you put into it. No matter how many "NASA/MIT/CIA/NSA" types are involved in hiding it.
It all comes down to simple physics:
If it were impossible for any user to pull out your secret from the executable and "unhide" it, then the computer would not be able to unhide it either, and your program wouldn't be able to use it. Any moderately skilled developer with enough incentive will find the way to unhide the secret.
The moment that you have handed your executable to a user, they have everything they need to find out the secret.
The best you can hope for is to make it so hard to uncover the secret that any benefits you can get from knowing the secret become not worth the hassle.
So, it's OK to try to obscure the data if it's merely "not-nice" for it to be public, or if the consequences of it becoming public would just be "inconvenient". But don't even think of hiding in your program "the password to your master client database", a private key, or some other critical secret. You just can't.
If you have truly critically secret information that your program will somehow need but should NEVER become public information (like a private key), then you will need to have your program talk to a remote server under your control, apply appropriate authentication and authorization controls (that is, make sure only the approved people or computers are able to make the request to the server), and have that server keep the secret and use it.
Solution 3:
The simplest way is to encrypt them with something trivial like xor or rot-13, and then decrypt them on the fly when they're used. That will eliminate casual viewing of them, but it won't stop anyone with much experience at reversing.