有时,从二进制(可执行)文件中隐藏字符串很有用.例如,从二进制文件中隐藏加密密钥是有意义的.
当我说"隐藏"时,我的意思是在编译的二进制文件中更难找到字符串.
例如,这段代码:
const char* encryptionKey = "My strong encryption key";
// Using the key
Run Code Online (Sandbox Code Playgroud)
编译后生成一个可执行文件,其数据部分中包含以下内容:
4D 79 20 73 74 72 6F 6E-67 20 65 6E 63 72 79 70 |My strong encryp|
74 69 6F 6E 20 6B 65 79 |tion key |
Run Code Online (Sandbox Code Playgroud)
您可以看到我们的秘密字符串可以轻松找到和/或修改.
我可以隐藏字符串......
char encryptionKey[30];
int n = 0;
encryptionKey[n++] = 'M';
encryptionKey[n++] = 'y';
encryptionKey[n++] = ' ';
encryptionKey[n++] = 's';
encryptionKey[n++] = 't';
encryptionKey[n++] = 'r';
encryptionKey[n++] = 'o';
encryptionKey[n++] = 'n';
encryptionKey[n++] = …Run Code Online (Sandbox Code Playgroud) 我发现可以从二进制文件中提取硬编码字符串.
例如,Process Explorer的属性视图显示超过3个字符的所有字符串.
这是我编写的简单可执行文件的代码,只是为了测试它:
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
_TCHAR* hiddenString1 =_T("4537774B-CC80-4eda-B3E4-7A9EE77991F5");
_TCHAR* hiddenString2 =_T("hidden_password_or_whatever");
for (int i= 0; i<argc; i++) {
if (0 == _tcscmp(argv[i],hiddenString1)) {
_tprintf (_T("The guid argument is correct.\n")); }
else if (0 == _tcscmp(argv[i],hiddenString2)) {
_tprintf (_T("Do something here.\n")); }
}
_tprintf (_T("This is a visible string.\n"));
//Keep Running
Sleep(60000);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
字符串可以清楚地从相应的可执行文件中提取:

我认为找到字符串有点太容易了.
我的问题是:
c++ security obfuscation defensive-programming reverse-engineering
我想在编译时加密/编码一个字符串,以便原始字符串不会出现在已编译的可执行文件中.
我已经看过几个例子,但他们不能把字符串文字作为参数.请参阅以下示例:
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"
}
Run Code Online (Sandbox Code Playgroud)
我不想像它那样单独提供每个角色.我的目标是传递一个字符串文字,如下所示:
EncryptString<"String to encrypt">::value
Run Code Online (Sandbox Code Playgroud)
还有一些像这样的例子:
#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] + …Run Code Online (Sandbox Code Playgroud) 我想要一个编译时字符串加密,这样我就可以在我的代码中编写:
const auto encryptedInvalidLicense = ENCRYPT("Invalid license");
std::cout << encryptedInvalidLicense.decrypt() << std::endl; // outputs "Invalid license"
Run Code Online (Sandbox Code Playgroud)
并且字符串"Invalid license"不会出现在二进制文件中.预构建可能是答案,但我正在寻找一个纯c ++ constexpr解决方案来解决这个问题,它将得到VS2015的支持.
有什么建议?
我已经研究过编译时字符串加密,它没有为问题提供constexpr解决方案.
我还研究了http://www.unknowncheats.me/forum/c-and-c/113715-compile-time-string-encryption.html.虽然它是一个constexpr解决方案,但VS2015仍然将字符串纯文本添加到二进制文件中.
c++ ×4
obfuscation ×2
c++11 ×1
c++14 ×1
compile-time ×1
constexpr ×1
security ×1
string ×1
templates ×1