【问题标题】:How can I reverse-engineer a Perl program that has been compiled with perlcc?如何对使用 perlcc 编译的 Perl 程序进行反向工程?
【发布时间】:2012-02-14 20:26:06
【问题描述】:

我继承了一个在 Unix 上具有“已编译”perl 脚本的环境。是否可以对其进行反编译、逆向工程(不管是什么术语),并从编译后的目标代码中获取源代码?

可能不可能,但我想我会问而不是假设。

谢谢, -凯文。

【问题讨论】:

  • 仅供参考,是的,术语是“逆向工程”;您正在从低抽象表示(编译/机器代码)到更高抽象表示(结构化源代码)。
  • @RichardJPLeGuen 已经 8 年了。你从哪里得到这个?
  • 我没有得到任何结果,因为我没有尝试这样做。

标签: perl compilation


【解决方案1】:

撇开已经介绍过的字节码后端 tchrist,只讨论 C 后端,perlcc 所做的就是将编译的 perl 程序的 optree 转换为 C 程序,然后编译。该 C 程序将在运行时将该 optree 重建到内存中,并基本上像 perl 通常那样执行它。这样做的目的实际上只是为了加快常规 perl 代码的编译时间。

你的程序的那个 optree 然后在PL_main_root 全局变量中可用。我们已经有一个名为B::Deparse 的模块,它能够使用optree 并将它们转换为大致相当于编译optree 的原始代码的源代码。它恰好有一个 compile 方法,该方法返回一个 coderef,该代码在执行时将打印 PL_main_root 的解析结果。

还有 C 函数 Perl_eval_pv,您可以使用它从 C 空间评估 Perl sn-ps。

$ echo 'print 42, "\\n"' > foo.pl
$ perl foo.pl
42
$ perlcc foo.pl
$ ./a.out
42
$ gdb a.out
...
(gdb) b perl_run
Breakpoint 1 at 0x4570e5: file perl.c, line 2213.
(gdb) r
...
Breakpoint 1, perl_run (my_perl=0xa11010) at perl.c:2213
(gdb) p Perl_eval_pv (my_perl, "use B::Deparse; B::Deparse->compile->()", 1)
print 42, "\n";
$1 = (SV *) 0xe47b10

当然,通常的 B::Deparse 警告适用,但这对于逆向工程肯定会很方便。在大多数情况下,实际上重构原始源代码是不可能的,即使它适用于上述示例。

要让 B::Deparse 给你一些合理的东西,你必须做的确切的 gdb 魔法也很大程度上取决于你的 perl。我正在使用带有 ithreads 的 perl,因此是多重性的。这就是我传递my_perl 变量的原因。其他 perls 可能不需要。此外,如果有人剥离了 perlcc 编译的二进制文件,事情会变得有点困难,但同样的技术仍然有效。

你也可以用它来编译任何你可以在程序执行期间随时以某种方式获得的optree。看看 B::Deparse 的 compile sub 并做一些类似的事情,除了为你想要转储的任何 optree 提供一个 B 对象而不是 B::main_root

同样的事情也适用于提到的 perlcc 的字节码后端。我不完全确定名为 CC 的优化 C 后端。

【讨论】:

  • 我只考虑 B 和 CC 后端;我忘记了 C 后端。
  • 其实简单看了一下CC后端,好像和C后端大同小异。无论如何,上述方法都足够相似。
【解决方案2】:

天哪!

如果且仅当它通过perlcc -B 编译成可执行字节码,您可以然后以与 B::Deparse 相同的方式反编译它。您将取回所有未以这种方式优化的源。它可能看起来有点滑稽,但它会是一个等效的程序。

但是,如果它被完全编译成 C 代码,然后编译成汇编程序和机器语言,并通过 ld 运行正确的 a.out 文件,那么您将无法执行类似的操作。这就像试图拆解/bin/cat

好吧,你可以拆开它,但在那里没有乐趣。即使您可以得到原始的、生成的 C 代码——这是你做不到的——它实际上也无法使用。

我想您可能会对其运行 strings(1) 以查看是否有任何有用的东西被永久留在某个地方,但我不会指望它。

对不起。

【讨论】:

  • 没有语言,只有方言。即使在计算机编程语言中。在这种情况下,只有这么多的语法、错误、语法,并不能真正告诉你源代码是否有意义。要理解源代码,您必须能够更进一步,绘制出用于编写代码的算法,甚至是构建它的系统架构。通常,在您真正理解源代码之前,您会对其有所了解。在理解任何事情之前都有一个子层次。 ... 呃,感谢您的阅读,这是我今天要说的很长的路要走。
【解决方案3】:

使用 7-zip。右键单击 exe 文件,然后执行 7zip>Open Archive,然后抓取 perl 文件。

【讨论】:

  • 这仅适用于打包程序,不适用于编译程序。
猜你喜欢
  • 2016-04-20
  • 2010-11-09
  • 2013-01-25
  • 2012-01-16
  • 1970-01-01
  • 1970-01-01
  • 2011-07-13
  • 1970-01-01
  • 2023-03-24
相关资源
最近更新 更多