我认为这个问题值得更新的答案。
几年前我问这个问题时,我没有考虑混淆和加密之间的区别。如果我当时知道这种差异,我之前会在标题中包含术语混淆。
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中这两个宏的定义,你会看到:
#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())
基本上,该类有三种不同的变体MetaString
(字符串混淆的核心)。每个都有自己的混淆算法。这三个变体之一是在编译时随机选择的,使用库的伪随机数生成器 ( MetaRandom
),以及char
所选算法对xor
字符串字符使用的随机数。
“嘿,但是如果我们算一下,3 个算法 * 255 个可能的字符键(0 未使用)= 765 个混淆字符串的变体”
你是对的。相同的字符串只能以 765 种不同的方式进行混淆。如果您有理由需要更安全的东西(您是偏执狂/您的应用程序需要更高的安全性),您可以扩展库并实施您自己的算法,使用更强的混淆甚至加密(白盒加密在 lib 的路线图中)。
它在哪里/如何存储混淆的字符串?
我觉得这个实现有趣的一件事是它不会将混淆后的字符串存储在可执行文件的数据部分中。相反,它被静态存储到MetaString
对象本身(在堆栈上),并且算法在运行时将其解码到位。这种方法使得在静态或运行时查找混淆字符串变得更加困难。
您可以自己深入研究实现。这是一个非常好的基本混淆解决方案,可以作为更复杂的解决方案的起点。