如何在可执行代码中嵌入字符串?

时间:2011-10-02 04:36:16

标签: c visual-c++ executable portable-executable string-literals

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

让我们说:

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 个答案:

答案 0 :(得分: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开头,只需返回原始字符串(不带guids)。这样您就可以使用未经模糊处理的可执行文件,例如在调试时。

  2. 如果它以ENCRYPTED_MARK_GUID开头,则首先进行反混淆,然后返回一个新字符串。在C中你将不得不关心内存的生命周期;在C ++中,您只需返回std :: string()。

  3. 最后,创建一个混淆程序,该程序在已编译的二进制文件中查找GUID并在它们之间加密数据。它只是Python或类似语言中的几行。我还建议在之后修复EXE的CRC,尽管我的程序在没有它的情况下工作。

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

答案 1 :(得分:2)

混淆可能是你最好的选择。使用简单的混淆(例如XOR),并在运行任何需要该字符串的代码之前,将其在程序开头的另一个变量中进行解混淆。

答案 2 :(得分:0)

我经常使用非编程方式。编译您的程序,然后使用upx压缩和混淆字符串。您可以找到upxhere

答案 3 :(得分: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 is working on this furiously我认为IBM已经有了这个。不确定Visual Studio的状态。这是在修补过的gcc上编译的。