I want to monitor all the activities of segment registers like CS,
DS... inside a virtual machine. For ex, I want to get notified
whenever CS or DS changes their values.
I want to use some features of Intel VT to do this. I imagine that I
can set some conditions so whenever these registers change values, it
causes VMExit.
However, I looked at the instructions that causes VMExit
conditionally, and apparently MOV can never cause VMExit. So
instruction like below:
mov DS, AX
never causes VMExit, so Intel VT cannot notify me when above
instruction happpens.
Does anybody have any idea on how to solve my problem?
Many thanks,
Jun
Why? This strikes me as an odd request.
>I want to use some features of Intel VT to do this. I imagine that I
>can set some conditions so whenever these registers change values, it
>causes VMExit.
Nope, no such thing, as far as I am aware.
>Does anybody have any idea on how to solve my problem?
Without simulating each instructions, like Bochs, I don't think there is a
way.
--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.
You can have VMEXITs upon exceptions and unmapped memory accesses,
which means to intercept the above you'd need to make sure that
whatever you load into a segment register is invalid (e.g. the segment
descriptor has P=3D0 in the GDT/LDT) and causes an exception under
normal conditions or the segment load is done from the memory instead
of a register and that memory isn't mapped. I think the first method
is viable -- you make sure that the GDT/LDT contains only unloadable
descriptors (you intercept writes to these tables and, say, ensure P=3D0
in all entries), then you catch #NPs and emulate the segment load
instructions by loading the segment descriptors in VMCS/VMCB with
valid stuff (e.g. now with P=3D1), advance rIP and do VMENTER. Looks
pretty hacky.
Alex
indeed. i have some crazy ideas, and want to explore them ...
>
> >I want to use some features of Intel VT to do this. I imagine that I
> >can set some conditions so whenever these registers change values, it
> >causes VMExit.
>
> Nope, no such thing, as far as I am aware.
>
> >Does anybody have any idea on how to solve my problem?
>
> Without simulating each instructions, like Bochs, I don't think there is =
a
> way.
that makes sense. i will see if i can do smt with Bochs ...
thanks,
J
What do you mean by "P=3D3D0"? The value of GDT entry?
> and causes an exception under
> normal conditions or the segment load is done from the memory instead
> of a register and that memory isn't mapped. I think the first method
> is viable -- you make sure that the GDT/LDT contains only unloadable
> descriptors (you intercept writes to these tables and, say, ensure P=3D3D=
0
> in all entries), then you catch #NPs and emulate the segment load
> instructions by loading the segment descriptors in VMCS/VMCB with
> valid stuff (e.g. now with P=3D3D1), advance rIP and do VMENTER. Looks
> pretty hacky.
>
Let me state again here, in case I misunderstand your idea:
- Preload GDT with invalid entries
- This causes VMExit whenever the DS changes its value. Emulate the
insn to fix the exception
However, I still dont understand how the valid insn like:
mov DS, AX
in case AX has valid value, how changing DS will cause VMExit?
Apparently DS will get the valid value now, but not invalid value we
preloaded in GDT. (??)
Thanks,
Jun
I didn't write any 3D's in the post. It's google's or news server's
invention.
I meant the present bit being 0 or 1. Just drop the "three
dimentionalities".
> > and causes an exception under
> > normal conditions or the segment load is done from the memory instead
> > of a register and that memory isn't mapped. I think the first method
> > is viable -- you make sure that the GDT/LDT contains only unloadable
> > descriptors (you intercept writes to these tables and, say, ensure P=3D=
3D3D=3D
> 0
> > in all entries), then you catch #NPs and emulate the segment load
> > instructions by loading the segment descriptors in VMCS/VMCB with
> > valid stuff (e.g. now with P=3D3D3D1), advance rIP and do VMENTER. Look=
s
> > pretty hacky.
>
> Let me state again here, in case I misunderstand your idea:
>
> - Preload GDT with invalid entries
> - This causes VMExit whenever the DS changes its value. Emulate the
> insn to fix the exception
>
> However, I still dont understand how the valid insn like:
>
> mov DS, AX
>
> in case AX has valid value, how changing DS will cause VMExit?
> Apparently DS will get the valid value now, but not invalid value we
> preloaded in GDT. (??)
You effectively keep the GDT/LDT entries invalid all the time.
That's why I wrote "you intercept writes to these tables and, say,
ensure Present bit equals one in all entries".
You don't let the software in the VM make them valid.
AX may contain a valid selector, valid in the sense of pointing to an
existing descriptor, but not valid or invalid in any additional sense.
What makes the MOV DS, AX invalid is that the descriptor (to which the
selector points) would have its Present bit set to zero. That will
cause a Segment Not Present exception.
You might also be able to shrink the GDT/LDT limit to the minimum and
get #GP instead of #NP on segment loads. Remember, however, that there
are many different causes for #GPs and you may get some unrelated to
segment loads.
Alex
Btw, you may need to handle exceptions not just from the MOV
instructions but also from all others that load segment registers
(POP, JMPF, CALLF, RETF, INT*, IRET, etc) and hardware interrupts that
force the CPU to fetch the new CS:rIP from the IDT and save/restore a
bunch of registers including other segment regs (SS in the first
place).
Alex