飞思卡尔 Coldfire MCF5282 的奇怪 qemu 行为

逆向工程 奇木 摩托罗拉
2021-06-21 02:53:21


我正在尝试对工业控制器的固件(显然是裸机)进行逆向工程。该设备基于 Coldfire 控制器,更准确地说,是MCF5282为了跟踪它的行为,我想以 M68k 方式使用 Qemu,它已经支持 MCF5206 和 MCF5208。Qemu 的 Coldfire 实现在很多地方都缺乏,它似乎旨在在引导加载程序使硬件处于特定状态后运行 Linux。为了运行我的固件,我必须修补它并删除所有硬件初始化,并为我想要定位的 CPU MCF5282 编写一个新的 Qemu 文件。

到目前为止,似乎我的代码正在运行,并且 CPU 已按照我跳过的初始化代码进行初始化。当我开始模拟时,陌生感就开始了,在那里我请求您的帮助以了解正在发生的事情。当我跑

qemu-system-m68k -nographic -cpu m5282 -kernel Firmware.bin.qemuPatched \
-serial telnet:127.0.0.1:4444,server,nowait \
-serial telnet:127.0.0.1:4445,server,nowait \
-serial telnet:127.0.0.1:4446,server,nowait \
-d in_asm -D execution.log

我希望目标 CPU 的所有指令都被记录下来,这就是发生的事情,至少在它到达分支指令之前。
那个时候,没有更多的指令被记录,尽管仿真仍在继续。

我可以说仿真仍在继续,因为如果我将目标机器状态添加到记录的属性中,我会看到在记录最后一条指令后 CPU 状态正在发生变化,并且 PC 也在发生变化。
奇怪的还不止于此,如果我按照 PC 的值,我看到 CPU 正在以一种意想不到的方式在固件地址空间中执行指令,总而言之,它似乎是在采样真实流程而不写每个一小步。

有人在其中识别出预期的行为吗?

此外,至少有一次,我发现对函数(jsr)的调用,其中记录的流似乎表明该函数未执行。它只记录下一条指令,但查看 CPU 状态很明显该函数已被执行。是 Qemu 出现故障,还是只有我不明白发生了什么?

----------------
IN:
0x00004da6:  movel %fp@(8),%d6

D0 = 00000064   A0 = 00082748   F0 = 7fff ffffffffffffffff  (         nan)
D1 = 00000028   A1 = 00084778   F1 = 7fff ffffffffffffffff  (         nan)
D2 = 00000025   A2 = 00000000   F2 = 7fff ffffffffffffffff  (         nan)
D3 = 00000000   A3 = 00000000   F3 = 7fff ffffffffffffffff  (         nan)
D4 = 00000000   A4 = 00000000   F4 = 7fff ffffffffffffffff  (         nan)
D5 = 00000000   A5 = 00000000   F5 = 7fff ffffffffffffffff  (         nan)
D6 = 00000000   A6 = 0008fe44   F6 = 7fff ffffffffffffffff  (         nan)
D7 = 00000000   A7 = 0008fe34   F7 = 7fff ffffffffffffffff  (         nan)
PC = 00004da6   SR = 2004 T:0 I:0 SI --Z--
FPSR = 00000000 ----
                                FPCR =     0000 X RN
  A7(MSP) = 00000000 ->A7(USP) = 0008fe30   A7(ISP) = 00000000
VBR = 0x00000000
SFC = 0 DFC 0
SSW 00000000 TCR 00000000 URP 00000000 SRP 00000000
DTTR0/1: 00000000/00000000 ITTR0/1: 00000000/00000000
MMUSR 00000000, fault at 00000000
----------------
IN:
0x00004daa:  jsr 0x4ca0

D0 = 00000064   A0 = 00082748   F0 = 7fff ffffffffffffffff  (         nan)
D1 = 00000028   A1 = 00084778   F1 = 7fff ffffffffffffffff  (         nan)
D2 = 00000025   A2 = 00000000   F2 = 7fff ffffffffffffffff  (         nan)
D3 = 00000000   A3 = 00000000   F3 = 7fff ffffffffffffffff  (         nan)
D4 = 00000000   A4 = 00000000   F4 = 7fff ffffffffffffffff  (         nan)
D5 = 00000000   A5 = 00000000   F5 = 7fff ffffffffffffffff  (         nan)
D6 = 00000064   A6 = 0008fe44   F6 = 7fff ffffffffffffffff  (         nan)
D7 = 00000000   A7 = 0008fe34   F7 = 7fff ffffffffffffffff  (         nan)
PC = 00004daa   SR = 2000 T:0 I:0 SI -----
FPSR = 00000000 ----
                                FPCR =     0000 X RN
  A7(MSP) = 00000000 ->A7(USP) = 0008fe30   A7(ISP) = 00000000
VBR = 0x00000000
SFC = 0 DFC 0
SSW 00000000 TCR 00000000 URP 00000000 SRP 00000000
DTTR0/1: 00000000/00000000 ITTR0/1: 00000000/00000000
MMUSR 00000000, fault at 00000000
----------------
IN:
0x00004db0:  movew %d0,%d7

D0 = 00000002   A0 = 000822c8   F0 = 7fff ffffffffffffffff  (         nan)
D1 = 00000020   A1 = 00084778   F1 = 7fff ffffffffffffffff  (         nan)
D2 = 0000007f   A2 = 00000000   F2 = 7fff ffffffffffffffff  (         nan)
D3 = 00000000   A3 = 00000000   F3 = 7fff ffffffffffffffff  (         nan)
D4 = 00000000   A4 = 00000000   F4 = 7fff ffffffffffffffff  (         nan)
D5 = 00000000   A5 = 00000000   F5 = 7fff ffffffffffffffff  (         nan)
D6 = 00000064   A6 = 0008fe44   F6 = 7fff ffffffffffffffff  (         nan)
D7 = 00000000   A7 = 0008fe34   F7 = 7fff ffffffffffffffff  (         nan)
PC = 00004db0   SR = 2000 T:0 I:0 SI -----
FPSR = 00000000 ----
                                FPCR =     0000 X RN
  A7(MSP) = 00000000 ->A7(USP) = 0008fe30   A7(ISP) = 00000000
VBR = 0x00000000
SFC = 0 DFC 0
SSW 00000000 TCR 00000000 URP 00000000 SRP 00000000
DTTR0/1: 00000000/00000000 ITTR0/1: 00000000/00000000
MMUSR 00000000, fault at 00000000
1个回答

我从另一个来源得到了解释,在我看来,在这里发布我收到的答案是合适的。

这很奇怪,在我看来,我的意思是,但这是预期的行为,并且在必要的解释下也有意义。
Qemu 的本质是一个 JIT 翻译器,意味着目标 CPU 的所有代码都被翻译成主机 CPU 的代码。
当我的代码分支到已经翻译的代码部分时,它不会再次翻译它。出于这个原因,我在代码日志中没有看到指令,但我看到 CPU 状态发生了变化。