2011-10-24 78 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