返回介绍

1.5 反编译器的上下文环境

发布于 2025-03-09 23:09:32 字数 1884 浏览 0 评论 0 收藏 0

在实践中,有一些程序可以配合反编译器一起创建目标高级语言程序。一般来说,源二进制程序有一个重定位地址表,当程序被装入内存的时候,将在那些地址上进行重定位。这个任务由装载程序完成。然后,已重定位的或绝对的机器码被反汇编产生该程序的汇编表示法。反汇编器可以借助编译器和库的签名去掉编译器启动代码(start-up) 和库例程的反汇编。然后,汇编语言程序作为反编译器的输入,产生一个高级语言目标程序。需要对目标程序做进一步的处理,比如对 while() 循环做一转换以便后期处理器处理。图 1-14 展示了“反编译过程”的几个典型步骤。使用者也可能作为一个信息提供者,尤其是在确定库例程以及区分数据和指令的时候。如果可能的话,这比使用自动工具更可靠。反编译器辅助工具在第 8 章讨论。这一节简单说明它们的任务。

图 1-14: 反编译系统

装载器

装载器是一个程序,它把二进制程序装入内存、而且如果程序是可重定位的那么就重定位机器码。在重定位期间,指令被改变然后放回内存。

签名生成器

签名生成器是一个自动确定编译器和库的签名的程序:唯一地标识每个编译器和库子程序的二进制标本。这些签名的使用试图反向进行链接器的工作——链接器把库和编译器启动代码链接到程序。这样,被分析的程序只包括用户子程序:从用户最初的高级语言程序编译那些。

例如,显示“hello world”的 C 程序编译以后,在二进制程序中有超过 25 个不同子程序,其中 16 个子程序是被编译器增加来设置它的环境,9 个例程是被链接器加入来实现 printf(),1 个子程序来自最初的 C 程序。

签名生成器的使用不仅减少了需要分析的子程序个数,也由于使用库函数名称代替任意的子程序名称从而增加了目标程序的可读性。

原型生成器

原型生成器是一个自动确定库子程序参数类型以及函数返回值类型的程序。这些原型来自于函数库的头文件,被反编译器用来确定库子程序的参数以及参数个数。

反汇编器

反汇编器是一个把机器语言转换成汇编语言的程序。有些反编译器把汇编语言程序转换成一个更高级的表示法(见第 2 章)。在这些事例中,反汇编器输出的汇编程序原来是在汇编器中编写的或者是在编译器中编写并编译成汇编程序。

库绑定

假如产生的目标代码中使用库函数名称 (亦即,能检测到库签名),如果反编译器的目标语言不是最初编译二进制源程序的同一种语言,那么由于两种语言使用不同的库例程,所以即使这个程序是正确的也不能再用目标语言编译它了。解决这个问题的办法是使用库绑定——在两种语言的库例程之间建立关联。

后期处理器

后期处理器是一个程序,它把一个高级语言程序转换成同种语言的一个语义等价的高级程序。例如,假如目标语言是 C 语言,以下代码

loc1 = 1;

while (loc1 < 50) {

/* some code in C */

loc1 = loc1 + 1;

}

可能被后期处理器转换成

for (loc1 = 1; loc1 < 50; loc1++) {

/* some code in C */

}

这是一个语义等价的程序,使用 C 语言适用的控制结构,而不是反编译器反编译结果的一般化结构。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文