0

Is there a way to modify a string literal in C++ from macro?

The reason for that is obfuscating code, particularly, 2 mutex wishes:

  1. I want to see literals as is in my source code, say, "password123".
  2. I want them to be mangled somehow before compilation to avoid including them in binaries.

I know that primitive modifications like XOR or shifting cannot be enough for professional analysis, but they are good enough for me.

Cœur
  • 37,241
  • 25
  • 195
  • 267
noober
  • 4,819
  • 12
  • 49
  • 85
  • Not I'm aware of doing such manipulation with the c++ preprocessor. – πάντα ῥεῖ Aug 31 '15 at 11:56
  • I could see it being possible if the string were in the format `(p,a,s,s,w,o,r,d,1,2,3)` or `(p)(a)(s)(s)(w)(o)(r)(d)(1)(2)(3)` or some other format that separates characters. You would finish by stringizing the result. – chris Aug 31 '15 at 11:57
  • Not unless you have the password decomposed into separate characters, if written as a string in the source they will constitute a preprocessing token which won't come apart during preprocessing. – skyking Aug 31 '15 at 11:57
  • You could probably achieve such a transformation with a bit of template metaprogramming, similar to that used for typesafe printf. I'll try and hunt down an appropriate link. – Toby Speight Aug 31 '15 at 12:07
  • [This](http://stackoverflow.com/questions/1356896/how-to-hide-a-string-in-binary-code?lq=1) question is similar, but this isn't a duplicate so I've reopened it. – Potatoswatter Sep 01 '15 at 02:00

2 Answers2

3

You could create a macro that doesn't really do anything, but use the macro as a "marker" for a custom build step (simple script might do it) to obfuscate the strings prior to the preprocessor getting the source code.

mark
  • 5,269
  • 2
  • 21
  • 34
3

You can use the macro to pass the string to a constexpr function which does the "encryption." Since C++14, constexpr is much easier to use.

// Similar to std::array, but with a member pointer as an accessor.
// It's complicated.
template< std::size_t length >
struct string_holder {
    char str[ length ];
    char const * ptr = str;
};

template< std::size_t length >
constexpr string_holder< length > encrypt( char const (& in)[ length ] ) {
    string_holder< length > result = {};
    for ( std::size_t i = 0; i != length - 1; ++ i ) {
        result.str[ i ] = in[ i ] ^ 1; // Do encryption here.
    }
    return result;
}

#define ENCRYPT( STR ) ( encrypt( STR ).ptr )

char const * const & s = ENCRYPT( "password123" );

http://coliru.stacked-crooked.com/a/3b6f6753d9f722cb

Note, s needs to be declared as a const& reference to take advantage of lifetime extension. You could also write auto const& s or auto &&s; it would be the same. The current version of Clang does not allow s to be declared constexpr, but I believe this to be a bug.

Ideally, you could just write a user-defined literal like "password123"_encrypted. Unfortunately, progress on implementing the underlying language features for that is slow.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421