New*_*bie 10 c++ windows visual-studio-2008
我想在我的.exe中隐藏一些字符串,这样人们就不能简单地打开.exe并查看那里的所有字符串.我不关心加密方法的强度,所以我可能会使用XOR等.
我怎么能在编译时这样做?这样我的字符串将不会存储在.exe中,但加密版本会存储.然后,我每次只使用我的解密功能在屏幕上显示这些字符串.
Yev*_*hen 10
您可以使用宏对其进行加密或编写自己的预处理器
#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");Run Code Online (Sandbox Code Playgroud)
以 SSPoke 的答案为基础,这里是一个稍微简单且更强大的解决方案。使用 MSVC 2017 和 gcc 7.3 https://godbolt.org/z/7fc3Zi 进行测试
变化:
#include <iostream>
// =============================================================================
namespace crypt {
// =============================================================================
// convert __TIME__ == "hh:mm:ss" to a sum of seconds this gives us a compile-time seed
// Note: in some weird cases I've seen the seed being different from encryption
// to decryption so it's safer to not use time and set the seed manually
#if 0
#define TBX_XSTR_SEED ((__TIME__[7] - '0') * 1ull + (__TIME__[6] - '0') * 10ull + \
(__TIME__[4] - '0') * 60ull + (__TIME__[3] - '0') * 600ull + \
(__TIME__[1] - '0') * 3600ull + (__TIME__[0] - '0') * 36000ull)
#else
#define TBX_XSTR_SEED (3600ull)
#endif
// -----------------------------------------------------------------------------
// @return a pseudo random number clamped at 0xFFFFFFFF
constexpr unsigned long long linear_congruent_generator(unsigned rounds) {
return 1013904223ull + (1664525ull * ((rounds> 0) ? linear_congruent_generator(rounds - 1) : (TBX_XSTR_SEED) )) % 0xFFFFFFFF;
}
// -----------------------------------------------------------------------------
#define Random() linear_congruent_generator(10)
#define XSTR_RANDOM_NUMBER(Min, Max) (Min + (Random() % (Max - Min + 1)))
// -----------------------------------------------------------------------------
constexpr const unsigned long long XORKEY = XSTR_RANDOM_NUMBER(0, 0xFF);
// -----------------------------------------------------------------------------
template<typename Char >
constexpr Char encrypt_character(const Char character, int index) {
return character ^ (static_cast<Char>(XORKEY) + index);
}
// -----------------------------------------------------------------------------
template <unsigned size, typename Char>
class Xor_string {
public:
const unsigned _nb_chars = (size - 1);
Char _string[size];
// if every goes alright this constructor should be executed at compile time
inline constexpr Xor_string(const Char* string)
: _string{}
{
for(unsigned i = 0u; i < size; ++i)
_string[i] = encrypt_character<Char>(string[i], i);
}
// This is executed at runtime.
// HACK: although decrypt() is const we modify '_string' in place
const Char* decrypt() const
{
Char* string = const_cast<Char*>(_string);
for(unsigned t = 0; t < _nb_chars; t++) {
string[t] = string[t] ^ (static_cast<Char>(XORKEY) + t);
}
string[_nb_chars] = '\0';
return string;
}
};
}// END crypt NAMESPACE ========================================================
#define XorS(name, my_string) constexpr crypt::Xor_string<(sizeof(my_string)/sizeof(char)), char> name(my_string)
// Because of a limitation/bug in msvc 2017 we need to declare crypt::Xor_string() as a constexpr
// otherwise the constructor is not evaluated at compile time. The lambda function is here to allow this declaration inside the macro
// because there is no such thing as casting to 'constexpr' (and casting to const does not solve this bug).
#define XorString(my_string) []{ constexpr crypt::Xor_string<(sizeof(my_string)/sizeof(char)), char> expr(my_string); return expr; }().decrypt()
// Crypt normal string char*
#define _c( string ) XorString( string )
#define XorWS(name, my_string) constexpr crypt::Xor_string<(sizeof(my_string)/sizeof(wchar_t)), wchar_t> name(my_string)
#define XorWideString(my_string) []{ constexpr crypt::Xor_string<(sizeof(my_string)/sizeof(wchar_t)), wchar_t> expr(my_string); return expr; }().decrypt()
// crypt wide characters
#define _cw( string ) XorWideString( string )
int main(void ) {
std::cout << _c("0obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzzeobfuscate me pleazzzzzze obfuscate me pleazzzzzze0\n"
"1obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzzeobfuscate me pleazzzzzze obfuscate me pleazzzzzze1\n"
"2obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzzeobfuscate me pleazzzzzze obfuscate me pleazzzzzze2\n"
"3obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzzeobfuscate me pleazzzzzze obfuscate me pleazzzzzze3\n"
"4obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzzeobfuscate me pleazzzzzze obfuscate me pleazzzzzze4\n"
"5obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzzeobfuscate me pleazzzzzze obfuscate me pleazzzzzze5\n"
"6obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzzeobfuscate me pleazzzzzze obfuscate me pleazzzzzze6\n"
"7obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzzeobfuscate me pleazzzzzze obfuscate me pleazzzzzze7\n"
"8obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzzeobfuscate me pleazzzzzze obfuscate me pleazzzzzze8\n"
"9obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzzeobfuscate me pleazzzzzze obfuscate me pleazzzzzze9\n" ) << std::endl;
std::cout << "Wide strings" << std::endl;
std::wcout << _cw(L"0obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzzeobfuscate me pleazzzzzze obfuscate me pleazzzzzze0\n"
"1obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzzeobfuscate me pleazzzzzze obfuscate me pleazzzzzze1\n"
"2obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzzeobfuscate me pleazzzzzze obfuscate me pleazzzzzze2\n"
"3obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzzeobfuscate me pleazzzzzze obfuscate me pleazzzzzze3\n"
"4obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzzeobfuscate me pleazzzzzze obfuscate me pleazzzzzze4\n"
"5obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzzeobfuscate me pleazzzzzze obfuscate me pleazzzzzze5\n"
"6obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzzeobfuscate me pleazzzzzze obfuscate me pleazzzzzze6\n"
"7obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzzeobfuscate me pleazzzzzze obfuscate me pleazzzzzze7\n"
"8obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzzeobfuscate me pleazzzzzze obfuscate me pleazzzzzze8\n"
"9obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzze obfuscate me pleazzzzzzeobfuscate me pleazzzzzze obfuscate me pleazzzzzze9\n") << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我也认为这是不可能的,尽管它非常简单,人们编写解决方案,你需要一个自定义工具来扫描构建的文件然后扫描字符串并加密字符串,这是不错但我想要一个从Visual Studio编译的包,现在可能!
您需要的是C++ 11(Visual Studio 2015 Update 1开箱即用)
这个新命令会发生魔力 constexpr
通过魔法发生在这 #define
#define XorString( String ) ( CXorString<ConstructIndexList<sizeof( String ) - 1>::Result>( String ).decrypt() )
Run Code Online (Sandbox Code Playgroud)
它不会在编译时解密XorString,仅在运行时解密,但它只会在编译时加密字符串,因此字符串不会出现在可执行文件中
printf(XorString( "this string is hidden!" ));
Run Code Online (Sandbox Code Playgroud)
它将打印出来,"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() )
////////////////////////////////////////////////////////////////////
Run Code Online (Sandbox Code Playgroud)