0

在多核处理器之前的时代创建了很多很多程序,使用指令 rdtsc 来获取精确数据。

这在多线程程序中是一个严重的问题,因为它们可能以冲突的值结束,并且因此导致许多彻底崩溃(一些单线程程序也可能崩溃,具体取决于它们使用 rtdsc 的方式)。

至少在 Windows 上,建议只设置“处理器亲和性”是很常见的,不幸的是,这也严重削弱了一些设计(显然是不正确的)使用并行性的程序。

所以我在想,即使没有任何类型的源代码,在崩溃的程序中寻找 rdtsc 调用并用其他东西替换它有多难?(我不知道还有什么……)

4

1 回答 1

3

作为一般规则,如果有人递给您一个机器代码二进制文件,您可能会非常(图灵!)很难确定哪些字节是指令,哪些是代码。如果你不能做到这一点,你甚至找不到 RDTSC 指令来修补。(更糟糕的是:一些程序会生成代码;现在数据区域中的内容是运行时可能暂时包含 RDTSC)。在真正特殊的程序中,某些指令可能会与其他指令完全重叠,从而导致某些 JMP 真正落在被识别为长指令的中间。(x86 指令的长度可能类似于 16 个字节!)。

二进制逆向工程人员有这个问题。一般来说,我不知道他们是如何成功的。我怀疑这是因为大多数程序目标代码是由不试图隐藏任何东西的编译器生成的(当你遇到一个这样做的编译器时要小心)。

如果你能找到它们,我假设你会通过对例程的函数调用来替换它们,该例程将已知常量加载到寄存器中,以避免你建议的不一致问题。修补它们的位置可能会很尴尬;RDTSC 是(我认为)2 个字节,它们可能夹在其他两条由于某种原因无法移动的指令之间。因此,您可能被迫在每个 RDTSC 上仅使用一个断点(1 个字节)来捕获到 RDTSC 模拟器;如果有人使用 RDTSC 在计时循环中读取纳秒时钟滴答,这可能会产生性能问题。

总而言之,这似乎是一条很难走的路。你有多想运行真正的旧程序,为什么?

于 2016-01-27T07:20:53.920 回答