“查找给定二进制文件中的所有代码等同于停止问题。”真?

时间:2011-03-14 13:59:33

标签: computer-science emulation halting-problem p-np

刚刚阅读the highly voted question regarding Emulators和声明

  

已经证明找到所有的   给定二进制文件中的代码是等效的   停止问题。

真的对我不好意思了。

当然不可能是真的吗?这不仅仅是一个大的依赖图吗?

非常感谢对此声明的进一步了解。

4 个答案:

答案 0 :(得分:4)

我认为这意味着“找到所有执行过的代码”,即找到覆盖范围,可能与动态生成的代码结合使用。这确实可以归结为停滞问题。

假设你有一个完美的覆盖工具,可以找到一个可能被执行的程序中的每一段代码(所以剩下的就是死代码)。给定一个程序P,该工具还可以决定扩展程序(P ; halt)是否执行halt指令,或halt部分是否为死代码。因此,它将解决我们知道不可判断的暂停问题。

答案 1 :(得分:4)

我不同意拉斯曼。

暂停问题表明,没有任何程序P可以使用任何程序并决定该程序是否执行halt指令。让我引用维基百科:

  

Alan Turing在1936年证明,不存在解决所有可能的程序输入对的暂停问题的通用算法。我们说暂停问题对于图灵机来说是不可判定的。

另一方面,我们并没有尝试制作此类程序/算法,但我们正在尝试在此/这些特定程序中找到所有代码 。如果我们对程序进行反向工程并看到它立即调用exit()(非常乐观的示例情况),我们已经证明调用halt,而这是不可能的?!

如果我们正在尝试构建一个可以运行任何程序的模拟器,那么我们就会失败,从那以后你可以(轻松地)将其减少到Halting问题。但通常你正在建立一个类似于Game Boy的模拟器,它支持有限数量的游戏盒(程序),因此它是可能的。

答案 2 :(得分:2)

有限状态机的暂停问题是可以解决的(尽管它可能需要很长时间...... of the universe ),并且您可能正在模拟的任何机器都是有限状态机。只需运行程序,步数就受可能状态数量的限制;如果超过该数字而不停止,那么程序将永远不会停止,因为它必须处于循环中。

实际上,除非代码可以使用计算的gotos,否则查找所有代码是一个更容易的问题。您可以简单地在每个可能的分支点处对所有分支执行一次,而不是运行代码。

答案 3 :(得分:0)

我同意Larsman,我相信这个论点可以准确。首先,我必须同意"找到给定二进制文件中的所有代码"在这种情况下,意味着具有单个可计算函数,该函数确定输入二进制内的哪些字节对应于所执行的指令。

编辑:如果有人不清楚为什么会出现问题,请考虑一下混淆的机器代码。这种代码的反汇编是一个非常重要的问题。如果在多字节指令的中间开始反汇编,则会得到错误的反汇编。这不仅打破了有问题的指令,而且通常还有一些指令。等等。 (例如,google"混淆和反汇编")。

制定精确的策略草图:

首先,定义一个理论计算机/机器模型,其中程序以多位二进制指令编码,非常类似于机器代码"实际"计算机,但精确(并使其完成)。假设二进制文件对程序和所有输入进行编码。这一切都必须精确,但假设语言有一个(二进制编码的)暂停指令,并且当且仅当它执行“停止”时,程序才会停止。指令。

首先,让我们假设机器无法改变程序代码,但有一个内存可以工作。 (在有趣的情况下假设无限)。

然后,任何给定的位都将位于程序执行期间运行的指令的开头,否则不会。 (例如,它可能位于指令的中间,或数据中,或者是垃圾代码" - 即永远不会运行的代码。请注意,我没有声明这些是相互排斥的,因为例如,跳转指令可以具有位于特定指令中间的目标,从而创建另一条指令,在第一次通过时#34;看起来不像执行指令。)。

如果二进制i具有从位位置j开始的指令,则将ins(i,j)定义为返回1的函数,该指令在由i编码的程序的运行中执行。另外,将ins(i,j)定义为0。假设ins(i,j)是可计算的。

让halt_candidate(i)成为以下程序:

for j = 1 to length(i)
  if(i(j..j+len('halt')-1) == 'halt')
    if(ins(i,j) == 1)
      return 1
return 0

由于我们不允许使用上面的自我修改代码,因此他们只能暂停程序才能实现“停止”操作。在某个位置执行的指令j。通过设计,halt_candidate(i)计算暂停功能。

这提供了证明的一个方向的非常粗略的草图。即如果我们假设我们可以测试程序i是否在所有j的位置j都有一条指令,那么我们可以编写暂停函数。

对于另一个方向,必须在正式机器内编码正式机器的仿真器。然后,创建一个程序加上输入i和j,它模拟程序i,当执行位位置j的指令时,它返回1并停止。当执行任何其他指令时,它继续运行,并且如果模拟模拟了“停止”操作。函数在i中,模拟器跳转到无限循环。然后ins(i,j)相当于halt(模拟器(i,j)),因此停止问题意味着查找代码问题。

当然,人们必须假设理论计算机相当于着名的无法解决的停止问题。否则,对于一个真实的"计算机,暂停问题是可以解决但难以处理的。

对于允许自修改代码的系统,参数更复杂,但我希望没有那么不同。

编辑:我相信自我修改案例中的一个证明就是在上面的静态代码加上数据系统中实现系统加自修改代码的仿真器。然后使用自修改代码暂停,允许程序i使用数据x,与上面的静态代码加数据系统中的停顿相同,使用包含模拟器的二进制文件,i和x作为代码加数据。