有一个客户声称已编译的 C 比 sudo “编译”的 Perl 字节码等更难逆向工程。任何人都有办法证明或反驳这一点?
6 回答
我对 perl 了解不多,但我会举一些例子,为什么将编译成汇编的代码反转如此难看。
逆向工程 c 代码最难看的地方是编译会删除所有类型信息。完全没有名称和类型是 IMO 最糟糕的部分。
在动态类型语言中,编译器需要保留更多关于它的信息。特别是字段/方法/...的名称,因为这些通常是不可能找到所有用途的字符串。
还有很多其他丑陋的东西。比如整个程序优化每次使用不同的寄存器来传递参数。函数被内联,所以一个简单的函数出现在许多地方,由于优化,通常形式略有不同。
堆栈上的相同寄存器和字节被函数内的不同内容重用。堆栈上的数组变得特别难看。因为你无法知道数组有多大以及它在哪里结束。
然后是一些可能会令人讨厌的微优化。例如,我曾经花费超过 15 分钟来反转一个曾经类似于return x/1600
. 因为编译器认为除法很慢,并将除法重写为几个乘法加法和按位运算。
Perl 真的很容易进行逆向工程。选择的工具是 vi、vim、emacs 或记事本。
这确实提出了他们为什么担心逆向工程的问题。将机器代码转换回类似于原始源代码的东西比通常的字节码更困难,但对于大多数不相关的邪恶活动来说。如果有人想复制您的秘密或破坏您的安全性,他们可以做的足够多,而无需将其恢复为原始源代码的完美表示。
虚拟机的逆向工程代码通常更容易。虚拟机通常被设计为该语言的简单目标。这意味着它通常相当容易和直接地代表该语言的结构。
但是,如果您正在处理的 VM 不是为该特定语言(例如,编译到 JVM 的 Perl)而设计的,这通常会使您更接近使用为真实硬件生成的代码 - 即,您必须做任何必要的事情来定位预定义的架构,而不是设计目标以适应源。
好的,多年来对此进行了充分的辩论;而且大多数结果都不是决定性的……主要是因为这无关紧要。
对于一个有动力的逆向工程师来说,两者都是一样的。
如果您使用像 perl2exe 这样的伪 exe 制造商,那么“反编译”比编译的 C 更容易,因为 perl2exe 根本不编译 perl,它只是有点“隐藏”(参见http://www.net-security .org/vuln.php?id=2464 ; 这真的很旧,但概念可能仍然相同(我没有研究过所以不确定,但我希望你明白我的意思)
我建议查看最适合这项工作的语言,以便可以明智且可持续地完成实际产品的维护和开发。
记住你_can_not_阻止一个有动机的对手,你需要让逆转比自己写更昂贵。
这四个应该使它变得困难(但又不是不可能)...
[1] 插入噪声代码(随机位置、随机代码),它会进行毫无意义的数学运算和复杂的数据结构交互(如果操作正确,如果目的是反转代码而不是功能,这将是一个非常令人头疼的问题)。
[2] 作为构建过程的一部分,在源代码上链接一些(不同的)代码混淆器。
[3] 应用软件保护加密狗,如果硬件不存在,它将阻止代码执行,这意味着在进行其余的反转之前需要对加密狗的数据进行物理访问:http://en.wikipedia。 org/wiki/Software_protection_dongle
[4] 总有一些保护器(例如 Themida http://www.oreans.com/themida.php)可以在构建后保护 .exe(不管它是如何编译的)。
...这应该让反向器足够头痛。
但请记住,所有这些也会花钱,所以你应该总是权衡你想要实现的目标,然后看看你的选择。
简而言之:这两种方法同样不安全。除非您使用的是非编译 perl-to-exe 制造商,否则本机编译的 EXE 会胜出。
我希望这有帮助。
C 比字节编译的 Perl 代码更难反编译。任何经过字节编译的 Perl 代码都可以被反编译。字节编译的代码不像已编译的 C 程序中的机器代码。其他一些人建议使用代码混淆技术。这些只是使代码更难阅读的技巧,并且不会影响反编译 Perl 源代码的难度。反编译的源代码可能更难阅读,但有许多 Perl 去混淆工具可用,甚至还有一个 Perl 模块:
http://metacpan.org/pod/B::Deobfuscate
Perl 打包程序如 Par、PerlAPP 或 Perl2exe 也不提供源代码保护。在某些时候,必须提取源代码,以便 Perl 可以执行脚本。甚至像 PerlAPP 和 Perl2exe 这样在源代码上尝试一些加密技术的打包程序也可以用调试器击败:
http://www.perlmonks.org/?displaytype=print;node_id=779752;replies=1
它会阻止某人随意浏览您的 Perl 代码,但即使是打包程序也必须先解压缩脚本才能运行。下定决心的人都可以得到源代码。
反编译 C 是完全不同的野兽。一旦它被编译,它现在是机器代码。您要么使用大多数 C 反编译器获得汇编代码,要么某些商业 C 反编译器将采用汇编代码并尝试生成等效的 C 代码,但除非它是一个非常简单的程序,否则很少能够重新创建原始代码。