在编译时加密/混淆字符串文字 [英] Encrypting / obfuscating a string literal at compile-time

查看:824
本文介绍了在编译时加密/混淆字符串文字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在编译时对字符串进行加密/编码,以使原始字符串不会出现在已编译的可执行文件中.

I want to encrypt/encode a string at compile time so that the original string does not appear in the compiled executable.

我已经看到了几个示例,但是它们不能将字符串文字作为参数.请参见以下示例:

I've seen several examples but they can't take a string literal as argument. See the following example:

template<char c> struct add_three {
    enum { value = c+3 };
};

template <char... Chars> struct EncryptCharsA {
    static const char value[sizeof...(Chars) + 1];
};

template<char... Chars>
char const EncryptCharsA<Chars...>::value[sizeof...(Chars) + 1] = {
    add_three<Chars>::value...
};

int main() {   
    std::cout << EncryptCharsA<'A','B','C'>::value << std::endl;
    // prints "DEF"
}

我不想像它一样单独提供每个字符.我的目标是传递一个字符串文字,如下所示:

I don't want to provide each character separately like it does. My goal is to pass a string literal like follows:

EncryptString<"String to encrypt">::value

还有一些类似的例子:

#define CRYPT8(str) { CRYPT8_(str "\0\0\0\0\0\0\0\0") }
#define CRYPT8_(str) (str)[0] + 1, (str)[1] + 2, (str)[2] + 3, (str)[3] + 4, (str)[4] + 5, (str)[5] + 6, (str)[6] + 7, (str)[7] + 8, '\0'

// calling it
const char str[] = CRYPT8("ntdll");

但是它限制了字符串的大小.

But it limits the size of the string.

有什么方法可以实现我想要的吗?

Is there any way to achieve what I want?

推荐答案

我认为这个问题值得更新.

I think this question deserves an updated answer.

几年前我问这个问题时,我没有考虑区别在混淆和加密之间.如果我知道这种区别,那么我会在标题前加上 Obfuscation .

When I asked this question several years ago, I didn't consider the difference between obfuscation and encryption. Had I known this difference then, I'd have included the term Obfuscation in the title before.

C ++ 11和C ++ 14具有可以有效且有效地实现编译时字符串混淆(以及可能的加密,尽管我还没有尝试过)的功能.相当简单的方法,而且已经完成了.

C++11 and C++14 have features that make it possible to implement compile-time string obfuscation (and possibly encryption, although I haven't tried that yet) in an effective and reasonably simple way, and it's already been done.

ADVobfuscator 是由Sebastien Andrivet创建的混淆库,它使用C ++ 11/14生成编译时的混淆代码,而无需使用任何外部工具,而仅使用C ++代码.无需创建额外的构建步骤,只需添加并使用它即可.我不知道不使用外部工具或构建步骤的更好的编译时字符串加密/混淆实现.如果您这样做,请分享.

ADVobfuscator is an obfuscation library created by Sebastien Andrivet that uses C++11/14 to generate compile-time obfuscated code without using any external tool, just C++ code. There's no need to create extra build steps, just include it and use it. I don't know a better compile-time string encryption/obfuscation implementation that doesn't use external tools or build steps. If you do, please share.

它不仅消除字符串,还具有其他有用的功能,例如编译时FSM( Finite状态机),可以随机混淆函数调用和编译时伪随机数生成器,但这不在此答案的范围之内.

It not only obuscates strings, but it has other useful things like a compile-time FSM (Finite State Machine) that can randomly obfuscate function calls, and a compile-time pseudo-random number generator, but these are out of the scope of this answer.

这是一个使用ADVobfuscator的简单字符串混淆示例:

Here's a simple string obfuscation example using 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_OBFUSCATEDOBFUSCATED宏.例如:

You can replace the macros DEF_OBFUSCATED and OBFUSCATED with your own macros. Eg.:

#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)以及选择的算法用于xor字符串字符的随机char,在编译时随机选择这三个变体之一. /p>

Basically, there are three different variants of the MetaString class (the core of the string obfuscation). Each has its own obfuscation algorithm. One of these three variants is chosen randomly at compile-time, using the library's pseudo-random number generator (MetaRandom), along with a random char that is used by the chosen algorithm to xor the string characters.

嘿,但是,如果我们做数学运算,则3种算法* 255个可能的char键(不使用0)=迷惑字符串的765个变体"

"Hey, but if we do the math, 3 algorithms * 255 possible char keys (0 is not used) = 765 variants of the obfuscated string"

您是对的.同一字符串只能以765种不同的方式进行混淆.如果您有理由需要更安全的东西(您偏执狂/您的应用程序要求更高的安全性),则可以使用更强的混淆甚至加密功能来扩展库并实现自己的算法(white-box cryptography 在lib的路线图中).

You're right. The same string can only be obfuscated in 765 different ways. If you have a reason to need something safer (you're paranoid / your application demands increased security) you can extend the library and implement your own algorithms, using stronger obfuscation or even encryption (White-Box cryptography is in the lib's roadmap).

混淆的字符串存储在哪里/如何存储?

关于此实现,我发现有趣的一件事是它不会将混淆的字符串存储在可执行文件的数据部分中. 相反,它是静态存储在MetaString对象本身中(在堆栈上),并且算法会在运行时对其进行解码.这种方法使静态或在运行时查找混淆后的字符串变得更加困难.

One thing I find interesting about this implementation is that it doesn't store the obfuscated string in the data section of the executable. Instead, it is statically stored into the MetaString object itself (on the stack) and the algorithm decodes it in place at runtime. This approach makes it much harder to find the obfuscated strings, statically or at runtime.

您可以自己深入实施.这是一个非常好的基本混淆解决方案,并且可以成为更复杂的解决方案的起点.

You can dive deeper into the implementation by yourself. That's a very good basic obfuscation solution and can be a starting point to a more complex one.

这篇关于在编译时加密/混淆字符串文字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆