PUSHFQ lifting not clearing VM and RF
From the x64 manual:
> When copying RFLAGS to the stack, the VM and RF flags (bits 16 and 17) are not copied; instead, values for these flags are cleared in the RFLAGS image stored on the stack.
(from: https://www.felixcloutier.com/x86/pushf:pushfd:pushfq)
But when lifting this instruction in x64 mode, i.e. lifting `PUSHFQ`, this is the lifted code, which does not clear the VM and RF flags.
```
loc_0:
RSP = RSP + -0x8
@64[RSP + -0x8] = zeroExt_64({cf 0 1, 0x1 1 2, pf 2 3, 0x0 3 4, af 4 5, 0x0 5 6, zf 6 7, nf 7 8, tf 8 9, i_f 9 10, df 10 11, of 11 12, iopl_f 12 14, nt 14 15, 0x0 15 16, rf 16 17, vm 17 18, ac 18 19, vif 19 20, vip 20 21, i_d 21 22, 0x0 22 32})
IRDst = loc_1
```
I realise that this is really an edge-case, and I don't really care if it is fixed or not. But it is now here if somebody does encounter this issue in the future.
For the 32bit version `PUSHFD`:
> When copying the entire EFLAGS register to the stack, the VM and RF flags (bits 16 and 17) are not copied; instead, the values for these flags are cleared in the EFLAGS image stored on the stack. See Chapter 3 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more information about the EFLAGS register.
So I would assume that this bug also exists for x86 lifting, although I did not test that.
A reproducer script:
```Python
from miasm.analysis.binary import Container
from miasm.analysis.machine import Machine
from miasm.core.locationdb import LocationDB
loc_db = LocationDB()
cont = Container.from_string(b"\x9c", loc_db)
machine = Machine("x86_64")
mdis = machine.dis_engine(cont.bin_stream, loc_db=loc_db, dont_dis=[1])
asmcfg = mdis.dis_multiblock(0)
lifter = machine.lifter(mdis.loc_db)
ircfg = lifter.new_ircfg_from_asmcfg(asmcfg)
for irblock in ircfg.blocks.values():
print(irblock)
```
0 条评论