如何制作 C 宏预构建预处理器?

发布于 2024-12-11 09:17:14 字数 293 浏览 0 评论 0原文

假设我有一个想要在代码中进行混淆的字符串。 (此示例仅供学习。)

我的计划是用宏包装字符串文字,例如

#define MY_STRING "lol"
const char *get_string() { return _MY_ENCRYPTION_MACRO(MY_STRING); }

,作为预构建步骤,通过我自己的预处理器运行我的源文件以查找 _MY_ENCRYPTION_MACRO 的所有用法 并相应地混淆字符串。

我将如何使用 Visual C++ 进行预处理?

Let's say I have a string that I would like to obfuscate in my code. (This example is just for learning.)

My plan is to wrap the string literal with a macro, e.g.

#define MY_STRING "lol"
const char *get_string() { return _MY_ENCRYPTION_MACRO(MY_STRING); }

and, as a pre-build step, to run my source file through my own preprocessor to look for all usages of _MY_ENCRYPTION_MACRO and obfuscate the strings accordingly.

How would I go about doing this preprocessing with Visual C++?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

笨死的猪 2024-12-18 09:17:14

我在几个问题上发布了这个答案,因为很多人都遇到这个问题,比如我自己,我也认为这是不可能的,即使它非常简单,人们编写了解决方案,您需要一个自定义工具来扫描构建的文件,然后像这样扫描字符串并加密字符串,这还不错,但我想要一个从 Visual Studio 编译的包,现在就可以了!

您需要的是 C++ 11(开箱即用的 Visual Studio 2015 Update 1),

神奇的事情发生在这个新命令 constexpr

神奇的事情发生在这个 #define< /code>

#define XorString( String ) ( CXorString<ConstructIndexList<sizeof( String ) - 1>::Result>( String ).decrypt() )

它不会在编译时解密 XorString,只会在运行时解密,但它只会在编译时加密字符串,因此字符串不会出现在可执行文件中

printf(XorString( "this string is hidden!" ));

它会打印出 “这个字符串已隐藏!” 但您不会在可执行文件中以字符串形式找到它!请使用 Microsoft Sysinternals Strings 程序下载链接自行检查:https://technet.microsoft.com/en-us/sysinternals/strings.aspx

完整的源代码相当大但可以轻松包含在一个头文件中。但也相当随机,因此加密的字符串输出总是会在每次新编译时发生变化,种子会根据编译时间而变化,非常可靠、完美的解决方案。

创建一个名为 XorString.h 的文件

#pragma once

//-------------------------------------------------------------//
// "Malware related compile-time hacks with C++11" by LeFF   //
// You can use this code however you like, I just don't really //
// give a shit, but if you feel some respect for me, please //
// don't cut off this comment when copy-pasting... ;-)       //
//-------------------------------------------------------------//

////////////////////////////////////////////////////////////////////
template <int X> struct EnsureCompileTime {
    enum : int {
        Value = X
    };
};
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
//Use Compile-Time as seed
#define Seed ((__TIME__[7] - '0') * 1  + (__TIME__[6] - '0') * 10  + \
              (__TIME__[4] - '0') * 60   + (__TIME__[3] - '0') * 600 + \
              (__TIME__[1] - '0') * 3600 + (__TIME__[0] - '0') * 36000)
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
constexpr int LinearCongruentGenerator(int Rounds) {
    return 1013904223 + 1664525 * ((Rounds> 0) ? LinearCongruentGenerator(Rounds - 1) : Seed & 0xFFFFFFFF);
}
#define Random() EnsureCompileTime<LinearCongruentGenerator(10)>::Value //10 Rounds
#define RandomNumber(Min, Max) (Min + (Random() % (Max - Min + 1)))
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
template <int... Pack> struct IndexList {};
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
template <typename IndexList, int Right> struct Append;
template <int... Left, int Right> struct Append<IndexList<Left...>, Right> {
    typedef IndexList<Left..., Right> Result;
};
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
template <int N> struct ConstructIndexList {
    typedef typename Append<typename ConstructIndexList<N - 1>::Result, N - 1>::Result Result;
};
template <> struct ConstructIndexList<0> {
    typedef IndexList<> Result;
};
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
const char XORKEY = static_cast<char>(RandomNumber(0, 0xFF));
constexpr char EncryptCharacter(const char Character, int Index) {
    return Character ^ (XORKEY + Index);
}

template <typename IndexList> class CXorString;
template <int... Index> class CXorString<IndexList<Index...> > {
private:
    char Value[sizeof...(Index) + 1];
public:
    constexpr CXorString(const char* const String)
    : Value{ EncryptCharacter(String[Index], Index)... } {}

    char* decrypt() {
        for(int t = 0; t < sizeof...(Index); t++) {
            Value[t] = Value[t] ^ (XORKEY + t);
        }
        Value[sizeof...(Index)] = '\0';
        return Value;
    }

    char* get() {
        return Value;
    }
};
#define XorS(X, String) CXorString<ConstructIndexList<sizeof(String)-1>::Result> X(String)
#define XorString( String ) ( CXorString<ConstructIndexList<sizeof( String ) - 1>::Result>( String ).decrypt() )
////////////////////////////////////////////////////////////////////

I posted this answer on a couple of questions as many people have this problem such as myself, I also thought this wasn't possible, even though it's very simple, people wrote solutions where you need a custom tool to scan the built file afterwards and scan for strings and encrypt the strings like that, which wasn't bad but I wanted a package that's compiled from Visual Studio, and it's possible now!

What you need is C++ 11 (Visual Studio 2015 Update 1 out of the box)

the magic happens with this new command constexpr

By magic happens in this #define

#define XorString( String ) ( CXorString<ConstructIndexList<sizeof( String ) - 1>::Result>( String ).decrypt() )

It won't decrypt the XorString at compile-time, only at run-time, but it will encrypt the string only in compile-time, so the strings will not appear in the Executable file

printf(XorString( "this string is hidden!" ));

It will print out "this string is hidden!" but you won't find it inside Executable file as strings!, check it yourself with Microsoft Sysinternals Strings program download link: https://technet.microsoft.com/en-us/sysinternals/strings.aspx

The full source code is quite large but could easily be included into one header file. But also quite random so the encrypted string outputs will always change every new compile, the seed is changed based on the time it took it compile, pretty much solid,perfect solution.

Create a file called XorString.h

#pragma once

//-------------------------------------------------------------//
// "Malware related compile-time hacks with C++11" by LeFF   //
// You can use this code however you like, I just don't really //
// give a shit, but if you feel some respect for me, please //
// don't cut off this comment when copy-pasting... ;-)       //
//-------------------------------------------------------------//

////////////////////////////////////////////////////////////////////
template <int X> struct EnsureCompileTime {
    enum : int {
        Value = X
    };
};
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
//Use Compile-Time as seed
#define Seed ((__TIME__[7] - '0') * 1  + (__TIME__[6] - '0') * 10  + \
              (__TIME__[4] - '0') * 60   + (__TIME__[3] - '0') * 600 + \
              (__TIME__[1] - '0') * 3600 + (__TIME__[0] - '0') * 36000)
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
constexpr int LinearCongruentGenerator(int Rounds) {
    return 1013904223 + 1664525 * ((Rounds> 0) ? LinearCongruentGenerator(Rounds - 1) : Seed & 0xFFFFFFFF);
}
#define Random() EnsureCompileTime<LinearCongruentGenerator(10)>::Value //10 Rounds
#define RandomNumber(Min, Max) (Min + (Random() % (Max - Min + 1)))
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
template <int... Pack> struct IndexList {};
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
template <typename IndexList, int Right> struct Append;
template <int... Left, int Right> struct Append<IndexList<Left...>, Right> {
    typedef IndexList<Left..., Right> Result;
};
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
template <int N> struct ConstructIndexList {
    typedef typename Append<typename ConstructIndexList<N - 1>::Result, N - 1>::Result Result;
};
template <> struct ConstructIndexList<0> {
    typedef IndexList<> Result;
};
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
const char XORKEY = static_cast<char>(RandomNumber(0, 0xFF));
constexpr char EncryptCharacter(const char Character, int Index) {
    return Character ^ (XORKEY + Index);
}

template <typename IndexList> class CXorString;
template <int... Index> class CXorString<IndexList<Index...> > {
private:
    char Value[sizeof...(Index) + 1];
public:
    constexpr CXorString(const char* const String)
    : Value{ EncryptCharacter(String[Index], Index)... } {}

    char* decrypt() {
        for(int t = 0; t < sizeof...(Index); t++) {
            Value[t] = Value[t] ^ (XORKEY + t);
        }
        Value[sizeof...(Index)] = '\0';
        return Value;
    }

    char* get() {
        return Value;
    }
};
#define XorS(X, String) CXorString<ConstructIndexList<sizeof(String)-1>::Result> X(String)
#define XorString( String ) ( CXorString<ConstructIndexList<sizeof( String ) - 1>::Result>( String ).decrypt() )
////////////////////////////////////////////////////////////////////
不再让梦枯萎 2024-12-18 09:17:14

如果您在 Linux 上使用了最新的 GCC(即 GCC 4.6),您还可以拥有一个提供内置功能的插件函数来“加密”编译时字符串,或者您甚至可以将其设为 GCC MELT 扩展(MELT 是一个高级要扩展的级别特定领域语言海湾合作委员会)。

如果您使用其他 C++,您可能有自己的预处理脚本来查找宏。
例如,您可能有一些程序可以扫描所有 C++ 源代码中出现的每一个 ENCRYPTSTRING("anyconstantstring"),并生成一个 mycrypt.h 文件,您可以#include "mycrypt.h" 在您的 C++ 代码中。然后你可能会做一些技巧

#define ENCRYPTSTRING(S) ENCRPYTSTRING_AT(S,__LINE__)
#define ENCRYPTSTRING_AT(S,L) cryptstring_#L

,让你生成的 "mycrypt.h" 包含诸如此类的东西

const char crypstring_123[]="thecryptedstringatline123";

"mycrypt.h" 生成器可以是一个 awk 或 pythonocaml (等等...)脚本。

If you used a recent GCC (i.e. GCC 4.6) on Linux, you could also have a plugin which provides a builtin function to "encrypt" compile time strings, or you could even make it a GCC MELT extension (MELT is a high-level domain specific language to extend GCC).

If you use some other C++, you might have your own pre-processing scripts finding your macros.
You might for instance have some program which scan every occurrence of ENCRYPTSTRING("anyconstantstring") in all your C++ sources, and generate a mycrypt.h file which you #include "mycrypt.h" in your C++ code. Then you might do tricks like

#define ENCRYPTSTRING(S) ENCRPYTSTRING_AT(S,__LINE__)
#define ENCRYPTSTRING_AT(S,L) cryptstring_#L

and have your generated "mycrypt.h" contain things like

const char crypstring_123[]="thecryptedstringatline123";

etc. The "mycrypt.h" generator could be an awk or python or ocaml (etc...) script.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文