【发布时间】:2020-07-17 19:13:47
【问题描述】:
我最近发现了这个:https://github.com/xoreaxeaxeax/movfuscator
这似乎取决于mov 是图灵完备的事实。这是真的吗,为什么?
【问题讨论】:
标签: assembly x86 computer-science mov turing-complete
我最近发现了这个:https://github.com/xoreaxeaxeax/movfuscator
这似乎取决于mov 是图灵完备的事实。这是真的吗,为什么?
【问题讨论】:
标签: assembly x86 computer-science mov turing-complete
是的,x86 的 mov 是图灵完备的。我在您的问题中添加了该标签,因为它可能不适用于具有名为 mov 的指令的其他 ISA,并且 movfuscator 编译器仅针对 x86。
计算不是“mov”本身,而是可以进行加法(和位移)的 x86 寻址模式。我没有详细了解它的工作原理,但它在很大程度上依赖于查找表,以及诸如 mov eax, [base + eax*4] 之类的东西,它根据 EAX 为 0 或 1 加载两个可能值之一。 p>
还要记住x86 mov has several forms:在内存和寄存器之间(加载、存储或reg
我不认为它依赖于自我修改代码,但如果我错了,请纠正我。 (如果确实如此,我认为/希望 movfuscator 至少不会创建除mov 以外的指令。那将是作弊。)
而且,这只是一个事实;您需要一些方法来循环主程序,假设原始源不是没有循环的直线 - Movfuscator github 自述文件谈到了这一点:
虽然 Dolan 的论文需要 jmp 指令,但 M/o/Vfuscator 不需要 - 它使用错误的 mov 指令来实现无限执行循环。如果您担心这仍然是“跳跃”,则可以通过别名为相同地址的页面、围绕内存上限执行执行、环 0 异常处理或只是无限期地重复 mov 循环来实现相同的效果。目前使用 jmp 来调度外部函数 - 如果这是一个问题,请避免使用外部函数,或者也使用 M/o/Vfuscator 编译库。
在为仅运行 mov 的代码创建用户空间环境时,我假设它创建了一个 SIGSEGV 处理程序(在 POSIX 操作系统上),该处理程序从顶部重新开始执行。所以任何有故障的负载都可以重新启动主循环。
还提到了让执行环绕的可能性:
IP 环绕在 16 位模式下可以很好地工作,其中 IP 是 16 位,但 CS:IP 形成 20 位线性地址(实模式)或在 16 位保护模式下,线性地址空间中某处的 64k 窗口.即,您只能在地址空间的 部分 中拥有 64k 的指令块,而其他空间则留给数据。 DS 段可以使用不同的基数。 (16 位模式下的 32 位寻址模式是可能的,因此您仍然拥有任何寄存器和缩放索引寻址模式的全部功能。)请注意,用于读取和写入段寄存器的助记符也是 mov。
但在 32 位模式下更难,其中 EIP 是 32 位,在 seg+off 计算后线性地址也是如此。除非有其他技巧,否则回绕只能发生在整个地址空间中,而不管您对分段做什么。这不会为数据留下非代码空间。设置较低的段限制可能会导致代码提取错误,但这不会导致回绕(除非您设置信号处理程序,或者在裸机上设置中断处理程序地址)。
无论哪种方式,即使 x86-64 也只有 64 位指针(理论上;实际上是 48 或 57 位),因此空间是有限的,不像真正的图灵机具有无限磁带。
【讨论】:
系统很少通过直接证明其所有图灵可计算功能的能力而被称为图灵完备。 相反,它们通常被“类比”为已知为图灵完备的现有系统。
paper by Stephen Dolan 表明mov 是 TC,它通过根据mov 构建一个 TM 系统的模拟来做到这一点。因此,任何可能对 TC 系统提出的问题,最坏的情况都可以在 mov 构造的模拟中虚拟化。
【讨论】: