Hi all
I`m trying to track code execution with page granularity by setting the access rights in the EPT to not executable on Xen 4.4.1.
The idea is as follows:
According to the intel manual „A reference using a guest-physical address whose translation encounters an EPT paging-structure
that is not present causes an EPT violation.“
So whenever a nonexisting memory page gets requested an EPT violation is caused (and handled by
ept_handle_violation). Extending the EXIT_REASON_EPT_VIOLATION I should be able to set the access rights
for every new page to access_rw(By using the
p2m->get_entry and
p2m-> set_entry functions right after the violation was handled), leading to a new EPT violation every time an instruction is fetched from this page.
There are several problems with my approach so far:
·
I get to few unique GFN (derived from the gpa by PAGE_SHIFT in the EPT violations when booting a WinXP guest. I get about 250 EPT_VIOLATIONS with unique GFNs when booting the guest OS and none when starting
new programs in the guest. So something seems to be wrong there. Also I read the access rights of the pages back after setting them. Most of the time the initial access rights are access_n before and the same after I tried setting them to access_rw (this happens
when the type is p2m_mmio_dm, when the type is p2m_ram_rw the setting works temporarily).
·
I never get an EPT violation with the
EPT_EXEC_VIOLATION flag set in the exit qualifications even for the pages where the setting of the access rights did succeed.
·
Later when checking the access rights (I simply save the GFNs in an array and use p2m->get_entry in an own call to domctl.c from xl) of the GFNs they all have access right access_n and type
p2m_mmio_dm , even for the pages where the setting of the access rights did succeed or the type was different before.
This all tells me that there is something fundamentally wrong with my approach so far, leading me to the following questions:
1.
Every time a new page in memory is allocated by the guest I get an EPT_VIOLATION, right?
a..
If this is the case then why don’t I get new violations after windows has finished booting?
2.
What is the difference between types
p2m_mmio_dm and p2m_ram_rw? (got a feeling that part of the problem lies here)
3.
Are the p2m->get_entry/p2m->set_entry functions the right tools for this purpose?
a..
If they are, then why do they sometimes fail?
4.
To get the domain I use
struct vcpu *curr = current; and struct p2m_domain *p2m = p2m_get_hostp2m(curr->domain); before using the get/set_entry-functions. Do I get confused with wrong domains or something like that?
5.
Because I just set the access rights to rw every time
EXIT_REASON_EPT_VIOLATION is called the whole domain should freeze/crash as soon as the first page tries to execute an instruction, right? It doesn’t because I get no execution attempts on the pages I set the access_rw, but why don’t
I get an execution attempt?
I hope it got clear what I try to achieve.
Thanks
Kevin