1

我有一个字符串文字,它在我的可执行文件周围的许多不同地方使用。

让我们这样说:

const char *formatString = "Something I don't want to make obvious: %d";

int format1(char *buf) { sprintf(buf, formatString, 1); }
int format2(char *buf) { sprintf(buf, formatString, 2); }

//...

现在,这个字符串文字在可执行代码中变得非常明显,因为它是按字面嵌入的。

有没有办法通过强制编译器来避免这种情况,例如,生成汇编指令(例如mov [ptr + 4], 0x65)指令来创建字符串,而不是按字面嵌入字符串?

我不想做任何形式的混淆——我只是想避免使字符串在可执行文件中变得明显。(我也不想在使用字符串的每个地方都修改我的代码。)

这可能吗?

4

3 回答 3

4

为了避免手动将加密的字符串粘贴到代码中,您可以创建一个宏来标记需要混淆的字符串和一个解密它们的函数:

#define OB(s) dec("START_MARK_GUID" s "\0" "END_MARK_GUID")
const char* dec(const char* s) { ... }
...
const char* s = OB("not easily readable"); // on all strings needed
const char* s = OB("either");

该函数必须做两件事:

  1. 如果参数以 START_MARK_GUID 开头,则只需返回原始字符串(不带 guid)。这也将允许您使用未混淆的可执行文件,例如在调试时。

  2. 如果它以 ENCRYPTED_MARK_GUID 开头,首先去混淆然后返回一个新字符串。在 C 中,您必须在这里关心内存寿命;在 C++ 中,您可以简单地返回 std::string()。

最后,创建一个混淆器程序,在编译的二进制文件中查找 GUID 并加密它们之间的数据。它只是 Python 或类似语言的几行代码。我还建议在之后修复 EXE 的 CRC,尽管我的程序即使没有它也能正常工作。

您可以更改具有较少唯一标识符的 guid 以节省一些空间。您也可以改进这一点,使解密只发生一次(例如,使用 ENCRYPTED_MARK_GUID 在其中写入字符串 ID,并通过该 ID 将解密的字符串保存在字典中)。

于 2011-10-02T07:43:34.567 回答
2

Obfuscation is probably your best bet. Use a simple obfuscation (such as XOR), and unobfuscate it into another variable at the beginning of your program before running any code that needs the string.

于 2011-10-02T04:42:06.510 回答
0

很快使用 C++11,您将能够使用用户定义的文字。

constexpr const char*
operator"" _decrypto(const char*, size_t len)
{
  //  decrypt input string.
}

const char* formatString = "encrypted gibberish"_decrypto;

int format1(char* buf) { sprintf(buf, formatString, 1); }
int format2(char* buf) { sprintf(buf, formatString, 2); }

int
main()
{
}

gcc 正在努力解决这个问题,我认为 IBM 已经这样做了。不确定 Visual Studio 的状态。这是在修补的 gcc 上编译的。

于 2011-10-02T16:15:56.663 回答