如何在该基本块中给出指令位置找到基本块?

时间:2014-08-04 16:15:17

标签: c assembly compiler-construction

假设我有一个指令位置。我想找到包含该指令的基本块。让我们将“基本块”定义为包含所需指令的基本块的入口点的指令位置。假设我禁用了任何形式的地址空间随机化,因此无论何时执行程序,所有程序段和库都会加载到虚拟地址空间中的相同位置。我该怎么做呢?

3 个答案:

答案 0 :(得分:2)

这是一个非常困难的问题。事实上,你甚至不希望知道汇编级一般情况的基本块在哪里。

问题来自于汇编是基于跳转的语言这一事实,根据定义,基本块是一系列指令,其中没有跳转。

即使你执行了99%的程序,你仍然无法知道最后一条指令是否会落在你认为是基本块的东西的中间。当然,我说的只是一次执行,但是应该考虑进行任何执行。

因此,找到二进制程序的CFG(以及它的基本块)就像停止问题一样困难(参见图灵对角线参数)。

您应该尝试提供有关您真正需要的更多详细信息,因为您所说的一般性问题根本不可能。

答案 1 :(得分:2)

您可以在限制性假设下执行此操作。

首先,代码不能在任何一般意义上进行自我修改。这会使问题变得不可判定。

其次,您需要一个完整的跳转目标列表。当然,调试信息将包含此信息。但是,如果您没有调试信息,仍然可以通过反汇编,查找所有分支和跳转指令以及获取其直接目标来推断出很多。实现switch的跳转表也很有用。一个简单的案例是函数指针。良好的逆向工程工具可以很好地完成这项任务:在对其结构知之甚少时对代码进行反汇编。另一方面,它们不可能是完美的:散布的数据和代码总是相互混淆。

第三,你需要一个程序中所有跳转/分支指令地址的列表。

有了这些清单,你就可以了。每个基本块以跳转目标开始,并运行到下一个目标之前的指令或跳转/分支指令(包括),以先到者为准。接受指令地址并在列表中搜索关联块开始和结束的算法很简单。

实际上,将列表合并为一个列表并使用二进制搜索是最简单的。搜索到的地址之前和之后的条目定义了它所在的块。

答案 2 :(得分:1)

需要做两件事:

  • 您需要保留包含映射的调试信息
  • 优化级别必须足够低,以使其明确无误。

简而言之,您需要来自工具链的支持,如果您真的想要获得比新变量生效的指令指针更多的信息,而不需要有关变量的任何信息,那么更需要支持。