2011-10-24 75 views
2

比方说,我有一个字符串,我想在我的代码中混淆。 (这个例子只是为了学习。)如何制作C宏预生成预处理器?

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

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

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

我该如何去做这个与Visual C++预处理?

+0

退房Boost.Wave文件。 –

+1

Plesae见http://stackoverflow.com/questions/1356896/how-to-hide-a-string-in-binary-code和http://stackoverflow.com/questions/4102320/c-how-to-encrypt -strings-at-compile-time –

+0

@MitchWheat:这些链接并不真正提供任何答案。 – Mehrdad

回答

0

如果您使用的最近GCC(即GCC 4.6)在Linux上,你也可以有一个插件,它提供了一个内置功能设置为“加密”编译时间字符串,或者你甚至可以使一个GCC MELT扩展(MELT是高级别领域特定语言来扩展GCC)。

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

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

,并有像

const char crypstring_123[]="thecryptedstringatline123"; 

等你产生"mycrypt.h"包含事物的"mycrypt.h"发生器可以是awkpythonocaml(等)的脚本。

1

我张贴了这个答案一对夫妇的问题,因为很多人都有这样的问题,比如我自己,我也认为这是不可能的,即使它很简单,人写道,你需要一个自定义的工具来扫描解决方案然后建立文件并扫描字符串并像这样加密字符串,这并不坏,但我想要一个从Visual Studio编译的程序包,现在就可以了!

你需要的是C++ 11(Visual Studio的2015年更新1开箱)

魔术与这个新的命令constexpr

通过魔术发生在这个#define

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

发生这不会在编译时解密XorString,只在运行时解密,但它只会在编译时加密字符串,所以字符串不会出现在可执行文件中

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

它会打印出"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()) 
//////////////////////////////////////////////////////////////////// 
+0

这是无法与vs15更新3. 我用下面的代码: printf(XorString(“test”)); 但字符串应用程序(sysinternals)显示“测试”字符串。 – AK87

+0

尝试优化模式。 (-O) – SSpoke