
Does boost have any compile-time classes for string encryption? Is it even possible? When a hacker dumps an executable, they can see all of the strings the program might use, and some of those strings may contain sensitive information. Does boost have any classes that can encode the strings at compile-time? Ideally, the third string in the code below would never compile the "secret" string into the final binary. Regards, -Sid void foo( void ) { char const * s1 = "abc"; string s2 = "xyz"; encrypted_string s3( "secret" ); }

On Mon, 27 Apr 2009 11:21:11 -0400, "Sid Sacek" <ssacek@securewatch24.com> wrote:
When a hacker dumps an executable, they can see all of the strings the program might use, and some of those strings may contain sensitive information. Does boost have any classes that can encode the strings at compile-time? Ideally, the third string in the code below would never compile the "secret" string into the final binary.
Excuse my asking, but what kind of security do you hope to achieve with this? -- EA

Excuse my asking, but what kind of security do you hope to achieve with this?
I don't mind. I would simply like to make a binary more opaque to snoopers. A binary may contain server names, registry keys, configuration settings, etc... Anything that's string-based could pique someone's curiosity. I realize it wouldn't truly secure a program to have strings be obfuscated, but if a first-glance at the binary contains no visible text, then the snooper may not even bother going on to the next level of snooping. -Sid

On Mon, 27 Apr 2009 13:00:44 -0400, "Sid Sacek" <ssacek@securewatch24.com> wrote:
I don't mind. I would simply like to make a binary more opaque to snoopers. A binary may contain server names, registry keys, configuration settings, etc... Anything that's string-based could pique someone's curiosity.
I realize it wouldn't truly secure a program to have strings be obfuscated, but if a first-glance at the binary contains no visible text, then the snooper may not even bother going on to the next level of snooping.
It only depends on the value of what you are protecting and against who you want to protection. You need to assess this before doing anything. If you cipher the strings of your binary image but decipher them at the process' start-up, process explorer (in Windows) will be able to show them. Ciphering and deciphering strings as they are acceded by encapsulating std::string (or whatever you're using) is probably a bit better but will impact performances. For the cipher, something simple and fast like RC4 is sufficient. RC4 can be written in few lines of C++ (http://en.wikipedia.org/wiki/RC4#Implementation) without any dependencies and is better than a trivial byte to byte obfuscation that will not hide the patterns the attacker may be looking for (ie. path with '/' or '\'). For extra security you can even compress the strings with a simple LZW compression. But in the end it's probably better to go for a full fledged protection, knowing that the protection is far from being bulletproof (but it can be ok if you're not protecting something very valuable). Binary protections may however provoke incompatibilities problems. Don't forget that most operating systems provide protected areas where you can store more sensitive information. For example, if your program is a service running as a privileged users, you can store the "important stuff" in a configuration file that a regular user cannot access. You can even protect this configuration file with a run time parameter for extra security or the user's encryption certificate if the OS provides you with one. Hope this helps. -- EA

If you cipher the strings of your binary image but decipher them at the process' start-up, process explorer (in Windows) will be able to show them.
You make some good points. I think the strings need to stay obfuscated until they're used and then discarded immediately afterwards.
For the cipher, something simple and fast like RC4 is sufficient. RC4 can be written in few lines of C++ (http://en.wikipedia.org/wiki/RC4#Implementation) without any dependencies and is better than a trivial byte to byte obfuscation that will not hide the patterns the attacker may be looking for (ie. path with '/' or '\').
I will look into that. Thanks for the suggestions. -Sid

Sid Sacek wrote:
You make some good points. I think the strings need to stay obfuscated until they're used and then discarded immediately afterwards.
The timespan during which the strings are decrypted doesn't matter much unless the cracker is randomly scanning memory... what matters more is what is done with those strings. Something to keep in mind is that a cracker can look at the "other end": as coded as the string is originally / wherever it comes from, once it is decoded it will probably be used... for something, right? If this is done in an unprivileged process (a user process), all that trouble was useless. For instance if this string is a SQL connection login/password, you don't even have to look for anything concerning the encrypted string. It's much simpler to just attach to the running process with a debugger, set a breakpoint on the DB API's method where the app gives the password to that API (almost guaranteed to be in cleartext, or at the very least replayable), look at the args when the breakpoint is hit, and voilà ! you have the password. By experience (in this very case, get a decrypted SQL password by setting a breakpoint in OLE DB) this takes less than 10 minutes. Regards, François

There is an implementation of a mpl::string by Eric Neibler somewhere. The only way you can prevent it from appearing is by including the deciphered text in the type. Once you have "secret" anywhere, it will normally be in the executable unless you are extremely lucky. What kind of encryption would you use? Sid Sacek wrote:
Does boost have any compile-time classes for string encryption? Is it even possible?
When a hacker dumps an executable, they can see all of the strings the program might use, and some of those strings may contain sensitive information. Does boost have any classes that can encode the strings at compile-time? Ideally, the third string in the code below would never compile the "secret" string into the final binary.
Regards,
-Sid
void foo( void )
{
char const * s1 = "abc";
string s2 = "xyz";
encrypted_string s3( "secret" );
}
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- Sohail Somani http://uint32t.blogspot.com

on Mon Apr 27 2009, Sohail Somani <sohail-AT-taggedtype.net> wrote:
There is an implementation of a mpl::string by Eric Neibler somewhere.
well, that's an interesting point. The string itself wouldn't even appear in the data segment. Cool. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams wrote:
on Mon Apr 27 2009, Sohail Somani <sohail-AT-taggedtype.net> wrote:
There is an implementation of a mpl::string by Eric Neibler somewhere.
well, that's an interesting point. The string itself wouldn't even appear in the data segment. Cool.
Below is the definition of a std_str() function that takes an mpl::string and turns it into a std::string. (boost/mpl/string.hpp is available on trunk, but hasn't been released yet.) It's not *very* obfuscated, but should be enough to fool a naive string-dump. #include <string> #include <iostream> #include <boost/mpl/string.hpp> #include <boost/mpl/for_each.hpp> using namespace boost; struct push_back_str { push_back_str(std::string & s) : str(s) {} void operator()(char c) const { this->str.push_back(c); } private: std::string & str; }; template<typename String> std::string std_str() { std::string result; result.reserve(mpl::size<String>()); mpl::for_each<String>(push_back_str(result)); return result; } int main() { std::cout << std_str< mpl::string<'hell','o wo','rld!'> >() << std::endl; return 0; } HTH, -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler wrote:
David Abrahams wrote:
on Mon Apr 27 2009, Sohail Somani <sohail-AT-taggedtype.net> wrote:
There is an implementation of a mpl::string by Eric Neibler somewhere.
well, that's an interesting point. The string itself wouldn't even appear in the data segment. Cool.
Below is the definition of a std_str() function that takes an mpl::string and turns it into a std::string. (boost/mpl/string.hpp is available on trunk, but hasn't been released yet.) It's not *very* obfuscated, but should be enough to fool a naive string-dump.
I think it should be straightforward for the OP to write a rot13 transformation and apply that (at compile-time) to the mpl::string (or even vector_c<char,...>.) Then he can use the inverse + your function to compute the deciphered string at runtime every time he needs it. Though I guess he could also have the computation of the inverse set up at compile time, just not execute it. Interesting mental exercise anyway! -- Sohail Somani http://uint32t.blogspot.com

Trunk appears to be unstable; I can't get a successful build happening. Here's the error I keep getting: boost/utility/value_init.hpp(70) : error C2061: syntax error : identifier 'wrapper_address' Anyway, I see the technique you're using below. I'm going to play around with your idea, and possibly add some more obfuscation and see what I come up with. Thanks so much for the time you spent writing that sample. -Sid -----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Eric Niebler Sent: Monday, April 27, 2009 1:45 PM To: boost@lists.boost.org Subject: Re: [boost] [encrypted strings]
Below is the definition of a std_str() function that takes an mpl::string and turns it into a std::string. (boost/mpl/string.hpp is available on trunk, but hasn't been released yet.) It's not *very* obfuscated, but should be enough to fool a naive string-dump.
#include <string> #include <iostream> #include <boost/mpl/string.hpp> #include <boost/mpl/for_each.hpp> using namespace boost;
struct push_back_str { push_back_str(std::string & s) : str(s) {}
void operator()(char c) const { this->str.push_back(c); } private: std::string & str; };
template<typename String> std::string std_str() { std::string result; result.reserve(mpl::size<String>()); mpl::for_each<String>(push_back_str(result)); return result; }
int main() { std::cout << std_str< mpl::string<'hell','o wo','rld!'> >() << std::endl; return 0; } -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Mon, 27 Apr 2009 21:15:48 -0400, "Sid Sacek" <ssacek@securewatch24.com> wrote:
Trunk appears to be unstable; I can't get a successful build happening. Here's the error I keep getting:
boost/utility/value_init.hpp(70) : error C2061: syntax error : identifier 'wrapper_address'
Anyway, I see the technique you're using below. I'm going to play around with your idea, and possibly add some more obfuscation and see what I come up with.
Thanks so much for the time you spent writing that sample.
Perhaps if you explain the context of your security problem we can provide you with a good solution. If your executable contains strings that the user should not see my question would be : why? Is this a login/password pair to a database? In which case, this means that the user is using a program to access a database he shouldn't access without it? Strange. One use case I would see for this kind of encryption is a machine that doesn't have internet access and disallow USB / floppies. The user is then limited to what is installed on the machine. You want to protect against someone who would drag your binary into notepad to get some info. -- EA

Eric Niebler wrote:
David Abrahams wrote:
on Mon Apr 27 2009, Sohail Somani <sohail-AT-taggedtype.net> wrote:
There is an implementation of a mpl::string by Eric Neibler somewhere.
well, that's an interesting point. The string itself wouldn't even appear in the data segment. Cool.
Below is the definition of a std_str() function that takes an mpl::string and turns it into a std::string. (boost/mpl/string.hpp is available on trunk, but hasn't been released yet.) It's not *very* obfuscated, but should be enough to fool a naive string-dump.
I just realized that mpl::string has a c_str member. That means the OP has to use mpl::vector_c right? -- Sohail Somani http://uint32t.blogspot.com

Sohail Somani wrote:
Eric Niebler wrote:
David Abrahams wrote:
on Mon Apr 27 2009, Sohail Somani <sohail-AT-taggedtype.net> wrote:
There is an implementation of a mpl::string by Eric Neibler somewhere. well, that's an interesting point. The string itself wouldn't even appear in the data segment. Cool. Below is the definition of a std_str() function that takes an mpl::string and turns it into a std::string. (boost/mpl/string.hpp is available on trunk, but hasn't been released yet.) It's not *very* obfuscated, but should be enough to fool a naive string-dump.
I just realized that mpl::string has a c_str member. That means the OP has to use mpl::vector_c right?
It doesn't anymore. See the latest mpl/string.hpp on trunk. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler wrote:
Sohail Somani wrote:
Eric Niebler wrote:
David Abrahams wrote:
on Mon Apr 27 2009, Sohail Somani <sohail-AT-taggedtype.net> wrote:
There is an implementation of a mpl::string by Eric Neibler somewhere. well, that's an interesting point. The string itself wouldn't even appear in the data segment. Cool. Below is the definition of a std_str() function that takes an mpl::string and turns it into a std::string. (boost/mpl/string.hpp is available on trunk, but hasn't been released yet.) It's not *very* obfuscated, but should be enough to fool a naive string-dump.
I just realized that mpl::string has a c_str member. That means the OP has to use mpl::vector_c right?
It doesn't anymore. See the latest mpl/string.hpp on trunk.
I see it, cool :-) -- Sohail Somani http://uint32t.blogspot.com

Sid Sacek wrote:
Does boost have any compile-time classes for string encryption? Is it even possible?
When a hacker dumps an executable, they can see all of the strings the program might use, and some of those strings may contain sensitive information. Does boost have any classes that can encode the strings at compile-time? Ideally, the third string in the code below would never compile the "secret" string into the final binary.
Hi Sid, I suggest that, like CAPTCHAs, this is something where it's better if everyone invents their own. If we all used the same string-obfuscation method, the crackers would only need to crack it once. The one time I did this I think it was something like this: #define C(x) x^0x42 const char secret[] = {C('s'), C('e'), C('c'), C('r'), C('e'), C('t')}; Maybe variadic templates would let you write that as obfus_string<'s','e','c','r','e','t'> - but watch out for that putting a less-obfuscated version in the symbol table. If you have more strings I would use some sort of external script to do the munging for you. (Not writing iPhone apps are you? Many apps now check if they are legitimate copies with something like: if (some_api_fn()=="signed_by_apple") - the cracker only needs to corrupt that string in the app to defeat the check.) Phil.

Maybe variadic templates would let you write that as obfus_string<'s','e','c','r','e','t'> - but watch out for that putting a less-obfuscated version in the symbol table.
That's an interesting suggestion. I will play with that idea a bit.
Not writing iPhone apps are you?
Nope. I just been wishing to have something like this for some time now. -Sid

Phil Endecott wrote:
Sid Sacek wrote:
Does boost have any compile-time classes for string encryption? Is it even possible?
When a hacker dumps an executable, they can see all of the strings the program might use, and some of those strings may contain sensitive information. Does boost have any classes that can encode the strings at compile-time? Ideally, the third string in the code below would never compile the "secret" string into the final binary.
Hi Sid,
I suggest that, like CAPTCHAs, this is something where it's better if everyone invents their own. If we all used the same string-obfuscation method, the crackers would only need to crack it once.
The one time I did this I think it was something like this:
#define C(x) x^0x42 const char secret[] = {C('s'), C('e'), C('c'), C('r'), C('e'), C('t')};
Maybe variadic templates would let you write that as obfus_string<'s','e','c','r','e','t'> - but watch out for that putting a less-obfuscated version in the symbol table.
If you have more strings I would use some sort of external script to do the munging for you.
(Not writing iPhone apps are you? Many apps now check if they are legitimate copies with something like: if (some_api_fn()=="signed_by_apple") - the cracker only needs to corrupt that string in the app to defeat the check.)
Phil.
No offense Phil, but the method of string encrpytion you chose will last no more than the 15 minutes it takes a hacker to write a script to automatically decrypt every string encrypted with the algorithm you chose and any other method based on DecryptString(encrypted_string_here).

Raindog wrote:
No offense Phil, but the method of string encrpytion you chose will last no more than the 15 minutes it takes a hacker to write a script to automatically decrypt every string encrypted with the algorithm you chose and any other method based on DecryptString(encrypted_string_here).
I don't think so because the string is encoded in the type. It is not a runtime value. So if he has encrypted_string<'whatever'> abc; The string "whatever" is probably not actually part of the executable at all. If anything, he has a structure that looks something like: vector<'jungrire'> abc; Again, the "encrypted" string is part of the type and probably does not appear in the executable at all. The cracker would have to figure out at runtime where abc.decrypt/decipher() is being called and s/he would have to find it for each type above which I'm sure could be scripted. I don't know if there is someone who could be given an executable with this type of protection unknown to him/her and crack it in 15 minutes. -- Sohail Somani http://uint32t.blogspot.com

Sohail Somani wrote:
Raindog wrote:
No offense Phil, but the method of string encrpytion you chose will last no more than the 15 minutes it takes a hacker to write a script to automatically decrypt every string encrypted with the algorithm you chose and any other method based on DecryptString(encrypted_string_here).
I don't think so because the string is encoded in the type. It is not a runtime value.
So if he has encrypted_string<'whatever'> abc; The string "whatever" is probably not actually part of the executable at all.
If anything, he has a structure that looks something like:
vector<'jungrire'> abc;
Again, the "encrypted" string is part of the type and probably does not appear in the executable at all.
The cracker would have to figure out at runtime where abc.decrypt/decipher() is being called and s/he would have to find it for each type above which I'm sure could be scripted.
I don't know if there is someone who could be given an executable with this type of protection unknown to him/her and crack it in 15 minutes.
Take it from someone whose job it is to do exactly what you think cannot be done that it is possible.

Raindog wrote:
The cracker would have to figure out at runtime where abc.decrypt/decipher() is being called and s/he would have to find it for each type above which I'm sure could be scripted.
I don't know if there is someone who could be given an executable with this type of protection unknown to him/her and crack it in 15 minutes.
Take it from someone whose job it is to do exactly what you think cannot be done that it is possible.
Oh, I'm sure! -- Sohail Somani http://uint32t.blogspot.com

"Raindog" wrote
Phil Endecott wrote:
Sid Sacek wrote:
Does boost have any compile-time classes for string encryption? Is it even possible?
#define C(x) x^0x42 const char secret[] = {C('s'), C('e'), C('c'), C('r'), C('e'), C('t')};
Maybe variadic templates would let you write that as obfus_string<'s','e','c','r','e','t'> - but watch out for that putting a less-obfuscated version in the symbol table.
(Not writing iPhone apps are you? Many apps now check if they are legitimate copies with something like: if (some_api_fn()=="signed_by_apple") - the cracker only needs to corrupt that string in the app to defeat the check.)
No offense Phil, but the method of string encrpytion you chose will last no more than the 15 minutes it takes a hacker to write a script to automatically decrypt every string encrypted with the algorithm you chose and any other method based on DecryptString(encrypted_string_here).
There is an app for cracked iPhones that lets the attacker crack other apps in "one click". A user of this app needs less skill to crack apps than it takes to make a phone call. You wrote in another message that "anyone unable to bypass the methods suggested would be unable to bypass a plain text target". I do not agree. An app that implements any trivial form of defense against this one cracking app will be safe from 99% of the crackers. Obfuscating the string test in the trivial defense will make it safe from the 99% of the rest and from the "next version" of the cracking app. The decision as to whether to expend the effort (or spend the money) to try to defend against the determined 0.001% who are left is up to the developer. Phil.

On Tue, 28 Apr 2009 09:54:29 +0100, "Phil Endecott" <spam_from_boost_dev@chezphil.org> wrote:
You wrote in another message that "anyone unable to bypass the methods suggested would be unable to bypass a plain text target". I do not agree. An app that implements any trivial form of defense against this one cracking app will be safe from 99% of the crackers. Obfuscating the string test in the trivial defense will make it safe from the 99% of the rest and from the "next version" of the cracking app. The decision as to whether to expend the effort (or spend the money) to try to defend against the determined 0.001% who are left is up to the developer.
In the security business we say "you're secure if breaking the protection is more expensive than the protected". I don't know about the iPhone application but I would agree that a simple security defence that protects against automated hacks is worth implementing if its distributed cost (ie cost of the security measure per application) is negligible. However you need to realize that if your application is popular it will be warezed, whatever you do. Spending too much money on protection is a waste. You'll have more fun and make more money in spending that time on features. -- EA

Edouard A. wrote:
However you need to realize that if your application is popular it will be warezed, whatever you do.
Only one person needs to know how to write a crack. Then he'll put it up on the Internet and even the kiddies can bypass your protection. Ultimately, string obfuscation doesn't buy you anything, and it costs you time (and thus money) to implement. I'd ignore it. --Jeffrey Bosboom

Sid Sacek wrote:
Does boost have any compile-time classes for string encryption? Is it even possible?
When a hacker dumps an executable, they can see all of the strings the program might use, and some of those strings may contain sensitive information.
Obfuscation doesn't lead to security. I suggest you change your design so that if the user of a program shouldn't know about some information, then the program cannot know of it either.

Sid Sacek wrote:
Does boost have any compile-time classes for string encryption? Is it even possible?
When a hacker dumps an executable, they can see all of the strings the program might use, and some of those strings may contain sensitive information. Does boost have any classes that can encode the strings at compile-time? Ideally, the third string in the code below would never compile the "secret" string into the final binary.
Regards,
-Sid
Sid, I made my original suggestion based on being both a virus analyst by profession and game hacker by hobby. No offense to the suggestions that have been made by others on this mail list[1], but they all appear to suffer the same problem in that laymen are suggesting solutions that not even professionals have completely solved. I understand that you are looking for simple techniques to "thwart noobs from haxxing your shizzle", but in reality, anyone unable to bypass the methods suggested would be unable to bypass a plain text target. Rolling your own solution has so many problems that I cannot even begin to tackle them here. You'll be much better off using an off the shelf protection mechanism. If you're really itching to try your hand, look at pecompact which allows you to provide your own decryption/encryption algorithm on top of their packer. [1]. Edouard's suggestion appears to imply that he has at least a cursory introduction to the problems faced by anti-piracy/anti-reverse engineering experts.

[DISCLAIMER: this post of mine, and the recent part of the thread, is completely OT unless it is brought into a discussion about actual compile-time conversions of strings] On Apr 28, 2009, at 1:30 AM, Raindog wrote:
Sid Sacek wrote:
Does boost have any compile-time classes for string encryption? Is it even possible?
When a hacker dumps an executable, they can see all of the strings the program might use, and some of those strings may contain sensitive information. Does boost have any classes that can encode the strings at compile-time? Ideally, the third string in the code below would never compile the "secret" string into the final binary.
Regards,
-Sid
Sid,
I made my original suggestion based on being both a virus analyst by profession and game hacker by hobby. No offense to the suggestions that have been made by others on this mail list[1], but they all appear to suffer the same problem in that laymen are suggesting solutions that not even professionals have completely solved.
One should (i) separate obfuscating from securing, as has been mentioned before in this thread and indicated by you, and (ii) not underestimate the power of the former, when it comes to avoid less experienced "hackers" (kids using readily available tools, and having not more than double-clicking as their skill set), curious IT-savvy guys and the accidental potential eavesdropper - often on a public WiFi where an 'exe' is sent in in an e-mail (with a simplistic mail server setup), but (iii) not overestimate the power of the former. So, obfuscation is a good tool for such "spurious" attacks/ eavesdropping. For really securing stuff? Of course not.
I understand that you are looking for simple techniques to "thwart noobs from haxxing your shizzle", but in reality, anyone unable to bypass the methods suggested would be unable to bypass a plain text target.
I do not agree, partly from intuition but more importantly from experience: simple obfuscation has made a huge difference for two of my products, whereof one deployed to many millions of users. I.e., a lot of people who could bypass a plain text target but much fewer who could deal with a simple obfuscation.
Rolling your own solution has so many problems that I cannot even begin to tackle them here.
I think it is easy to tackle it, and it is just one problem: it will be simple obfuscation, which is breakable by a good hacker, but *might* protect you from simple eavesdropping (Wiresharked or not - after all, it does not take a brain surgeon to install and run Wireshark :-) )
You'll be much better off using an off the shelf protection mechanism.
Depends on the needs and integrity needs.
If you're really itching to try your hand, look at pecompact which allows you to provide your own decryption/encryption algorithm on top of their packer.
I have not used it; will check it out. I have dealt extensively with PE compression (and obfuscation) in the form of .NET PE's the last year, so it could be refreshing to review PE's from a "native" angle again :-)
[1]. Edouard's suggestion appears to imply that he has at least a cursory introduction to the problems faced by anti-piracy/anti- reverse engineering experts.
I think (hope?) most people involved in this thread, and similar threads, have more than a cursory knowledge of this domain, and I think (still hope?) that most of them have hacked a game at some point in their youth ;-) /David

I understand that you are looking for simple techniques to "thwart noobs from haxxing your shizzle", but in reality, anyone unable to bypass the methods suggested would be unable to bypass a plain text target. Rolling your own solution has so many problems that I cannot even begin to tackle them here. You'll be much better off using an off the shelf protection mechanism.
If you're really itching to try your hand, look at pecompact which allows you to provide your own decryption/encryption algorithm on top of their packer.
I hear ya man. I'm not at that point where I want to make my code hack-proof, but I will keep your thoughts and suggestions in my mail save box for when I do need to go in that directions. -Sid
participants (11)
-
David Abrahams
-
David Bergman
-
Edouard A.
-
Eric Niebler
-
Francois Barel
-
Jeffrey Bosboom
-
Mathias Gaunard
-
Phil Endecott
-
Raindog
-
Sid Sacek
-
Sohail Somani