我对您可以采取的预防措施感兴趣,以便使C共享库的逆向工程更加困难
似乎不可能完全阻止,但你可以采取可能需要更长时间的步骤,因此不那么有吸引力/成本更高
代码混淆,编译器优化选项编译器调试标志等等(我会对gcc编译器特别感兴趣)
对于以$或工时等方式逆向工程~5KLOC C共享库(.so大小~200kb)的相对难度的任何想法也感兴趣。
答案 0 :(得分:7)
这些是我所知道的一些技巧:
使用strip
和--strip-unneeded
选项删除重定位所需的所有符号(因为我们讨论的是共享库):
strip --strip-unneeded libmylib.so
与标准libc 静态链接,这会产生更大的库/二进制文件,这意味着需要更多的代码和混淆,因为将函数与函数分开会更加困难。库函数:
gcc -static ...
强制编译器内联小函数,这会在代码中嵌入小函数而不是调用它们,因此几乎不可能区分代码和标准库代码。
话虽如此,我必须补充一点,我有一个使用上述措施的二进制文件,我能够在几个小时内对其进行逆向工程,我开始重建symtab
如果你很好奇,我不是逆向工程大师。
答案 1 :(得分:4)
- 无需代码混淆(如在C#或Java中)。
目标代码中不存在内部变量和函数的名称。
但是,导出的函数的名称仍将以明文形式显示在共享对象文件中。这听起来很合理。
- 最好使用gcc
优化标记-O2
或-O3
。
使用编译器优化,目标代码可能与源代码有很大不同。回到最初的C源代码实际上非常困难。
但是,始终可以在装配级别恢复工程师。通常,并非所有程序都有价值。在汇编中对有趣的部分进行逆向工程会更容易,而不是C中的整个程序。
答案 2 :(得分:4)
最常见的防反转技术的问题在于它们是众所周知的,并且有一些工具可以克服它们。当然,剥离符号和混淆是必须的,但这只是隐藏名称/符号。
如果你想让逆转器的工作更加困难,那就自己发明一些代码操作。它可能非常简单,比如使用自定义调用约定,但这会使所有反汇编程序无法识别函数的开始和结束。
这些简单的技巧将非常有效,因为没有一个已经制作的工具可以将代码恢复为原始代码。你看,对于几乎所有的商业包装商或加密器,已经有一个单击解包器。
答案 3 :(得分:3)
没那么多。一旦你剥离了调试符号和混淆了所有内部符号(不是外部符号,因为库的客户端需要一个符号链接到),你做的就不多了。由于1-1指令到操作码的映射,装配反汇编非常容易。另一方面,很难理解编译器生成的汇编代码,因为它充满了奇怪的优化和效率技巧。
就此而言,将GCC转换为最高优化可能是您可以使用的最佳混淆技巧之一。
考虑到现代计算能力,反汇编本身不会花费那么长时间,在这一点上需要人来解读它。
但好奇的是:没有逆向工程有什么重要意义?保证财务数据安全的加密和安全性大多是开源的。或者这是一个专有的软件保护措施?
答案 4 :(得分:0)
将代码与开关/案例混淆混合(使其成为非线性)。
使用C ++模板在编译时加密变量/字符串。可以在double类型中封装整数类型,以使反转更加困难。
在实际代码(jmp x,db 0E8h,x:etc。)之间插入程序集混淆宏
使用BOOST;)它确实使逆向工程变得痛苦......;)