この質問は更新された答えに値すると思います。
数年前にこの質問をしたとき、私は難読化と暗号化の違いを考慮していませんでした。そのときこの違いを知っていたら、以前はタイトルに難読化という用語を含めていたでしょう。
C++11とC++14には、コンパイル時の文字列の難読化(および、まだ試していませんが、暗号化)を効果的かつ合理的に単純な方法で実装できる機能があり、すでに実行されています。
ADVobfuscatorは、Sebastien Andrivetによって作成された難読化ライブラリであり、C ++ 11/14を使用して、C ++コードだけでなく、外部ツールを使用せずにコンパイル時の難読化コードを生成します。追加のビルドステップを作成する必要はありません。それを含めて使用するだけです。外部ツールやビルドステップを使用しない、より優れたコンパイル時の文字列暗号化/難読化の実装はわかりません。もしそうなら、共有してください。
文字列を難読化するだけでなく、関数呼び出しをランダムに難読化できるコンパイル時FSM(有限状態マシン)やコンパイル時の疑似乱数ジェネレータなど、他の便利な機能もありますが、これらはこの範囲外です。答え。
ADVobfuscatorを使用した簡単な文字列難読化の例を次に示します。
#include "MetaString.h"
using namespace std;
using namespace andrivet::ADVobfuscator;
void Example()
{
/* Example 1 */
// here, the string is compiled in an obfuscated form, and
// it's only deobfuscated at runtime, at the very moment of its use
cout << OBFUSCATED("Now you see me") << endl;
/* Example 2 */
// here, we store the obfuscated string into an object to
// deobfuscate whenever we need to
auto narrator = DEF_OBFUSCATED("Tyler Durden");
// note: although the function is named `decrypt()`, it's still deobfuscation
cout << narrator.decrypt() << endl;
}
DEF_OBFUSCATED
マクロとOBFUSCATED
独自のマクロを置き換えることができます。例えば。:
#define _OBF(s) OBFUSCATED(s)
...
cout << _OBF("klapaucius");
それはどのように機能しますか?
MetaString.hでこれら2つのマクロの定義を見ると、次のことがわかります。
#define DEF_OBFUSCATED(str) MetaString<andrivet::ADVobfuscator::MetaRandom<__COUNTER__, 3>::value, andrivet::ADVobfuscator::MetaRandomChar<__COUNTER__>::value, Make_Indexes<sizeof(str) - 1>::type>(str)
#define OBFUSCATED(str) (DEF_OBFUSCATED(str).decrypt())
基本的に、クラスには3つの異なるバリアントがありますMetaString
(文字列の難読化のコア)。それぞれに独自の難読化アルゴリズムがあります。これらの3つのバリアントの1つは、ライブラリの疑似乱数ジェネレーター(MetaRandom
)を使用して、コンパイル時にランダムに選択されます。またchar
、選択されたアルゴリズムによってxor
文字列文字に使用されるランダムも使用されます。
「ねえ、でも計算すると、3つのアルゴリズム* 255の可能なcharキー(0は使用されない)=難読化された文字列の765のバリアント」
あなたが正しい。同じ文字列は、765の異なる方法でのみ難読化できます。より安全なものが必要な理由がある場合(パラノイアである/アプリケーションがセキュリティの強化を要求している場合)、より強力な難読化または暗号化を使用して、ライブラリを拡張し、独自のアルゴリズムを実装できます(ホワイトボックス暗号化はライブラリのロードマップにあります)。
難読化された文字列はどこに/どのように保存されますか?
この実装について私が興味深いと思うことの1つは、実行可能ファイルのデータセクションに難読化された文字列を格納しないことです。代わりに、MetaString
オブジェクト自体(スタック上)に静的に格納され、アルゴリズムが実行時にその場でデコードします。このアプローチでは、静的または実行時に、難読化された文字列を見つけるのがはるかに困難になります。
自分で実装を深く掘り下げることができます。これは非常に優れた基本的な難読化ソリューションであり、より複雑なソリューションへの出発点になる可能性があります。