assembly 避免在二进制文件或反汇编代码中出现可读文本

6ss1mwsb  于 2023-03-23  发布在  其他
关注(0)|答案(2)|浏览(123)

有没有什么广泛使用的程序来隐藏可读的字符串?在调试我的代码后,我发现了很多纯文本。我可以使用一些简单的加密(凯撒密码等...),但这种解决方案会完全减慢我的代码。有什么想法吗?

bmvo0sr5

bmvo0sr51#

不,没有广泛使用的隐藏引用字符串的方法。
在某些时候,一个被访问的字符串必须被解密,这将揭示密钥/方法,你的解密变成了混淆。如果有人想读取你所有引用的字符串,他可以很容易地编写一些脚本来将它们全部转换为可读的。
我想不出有什么理由要对字符串进行这样的模糊处理。它们只对分析你的可执行文件的人可见。这些人同时也能够对你的去模糊处理进行逆向工程,并将其应用于所有字符串。
如果字符串的保密性对应用程序的安全性至关重要,则必须重新考虑这一点。
旁注:在C中破译字符串不会降低应用程序的速度...除非你的应用程序充满了字符串,并且你在破译过程中做了一些非常低效的事情。你测试过这个吗?

qni6mghb

qni6mghb2#

这不会阻止严重的逆向工程(例如,在程序解密字符串后,使用调试器查看内存中的字符串),但可以对偶然的strings -a a.out隐藏一些字符串。
如果你要做这样的事情,CPU效率最高的方法通常是用某个常量对每个字节进行异或,或者用某个32位常量对每个4字节块进行异或。(无论哪种方式,“解密”都可以在寄存器宽度的块中完成,如64位或使用SIMD 128位,就地或复制和异或与memcpy一样快。)解密/加密是相同的功能,因为x^x == 0和XOR是结合/交换。
这就是GNU C memfrob所做的,它是为您的用例而设计的,通过将每个字节与常量42进行异或来轻微地隐藏内存中的数据。一个高位设置的常量将ASCII转换为非ASCII字符,如0xaa
另请参阅 * How to hide a string in binary code? *,这是一个C++的Boost CPP宏,它在编译时加密字符串。它使用循环计数器来改变每个字节的XOR常量。
Caesar密码通常只定义在字母表字符上,在字母表边界26处 Package 。对于一般的二进制情况,unsigned char加法与 Package 模1<<CHAR_BIT(通常为256)也可以正常工作,尽管在uint64_t中并行执行8个字节将需要SIMD或SWAR以避免从一个字节进位影响其相邻字节。
在可移植的ISO C中,使用memcpy(&tmp, ptr, sizeof(tmp))char[]数据中执行uint64_t tmp的别名安全未对齐加载。(另请参阅 * Why does unaligned access to mmap'ed memory sometimes segfault on AMD64? *)。现代编译器将其编译为单个加载指令,至少在针对不需要对齐加载的ISA时。当针对MIPS或RISC-V时可能会更糟。
特别是当你使用了一些有效的东西,比如一个简单的XOR常量,伊拉巴克斯特的评论是非常正确的,这对性能的影响可以忽略不计,因为大多数程序不会花很多时间阅读字符串文字数据。如果你这样做了,解密一次并将字符串保存在内存中。

相关问题