Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch between shadow and real page for sleep skipping #1545

Open
RadamireZ opened this issue Nov 11, 2022 · 2 comments
Open

Switch between shadow and real page for sleep skipping #1545

RadamireZ opened this issue Nov 11, 2022 · 2 comments

Comments

@RadamireZ
Copy link

Hi guys, i'm trying to implement a kind of sleep skipping mechanism for some of the process under analysis.
I want to fake the ticks stored on KUSER_SHARED_DATA that can be read by any userspace process at a known virtual address.
My approach is to create a shadow page where i can alter the tick field and then switch between the shadow page and the original one based on which process requests that page.
I already created the shadow page and call vmi_slat_change_gfn like drakvuf does for inject_trap_pa, then i registered also a memory trap so i can filter the process that request the page in my callback invoked by pre_mem_cb.
I want now to switch between those two pages in pre_mem_cb, but if i set the slat_id to altp2m_idx, my executable that i use for test never start and cause the vm crash at the end.
I don't understand how drakvuf perform the switch to hiding the breakpoints, Is it enuogh to set slat_id to 0 for real page and set to altp2m_idx for shadow one?
Should i use a different approach?

@tklengyel
Copy link
Owner

So the problem you have is that you want to present two different versions of a page when it's being read from depending on the process that's doing the reading. I don't think your approach is going to work for that. Generally speaking the idx view has the shadow copies mapped as executable but not readable, so it knows it needs to switch to view 0 when its being read/written, for a single instruction, and then switch back to idx afterwards. In your case though you need to have the shadow page restricted (non-readable) so you can check what is the process accessing it. But then where do you switch where the permission is lifted? If you have the permission as readable only in view 0 with the original page then the shadow version will always be unreadable.

What would be the easier solution is to just have the page non-readable in idx and then return a VMI_EVENT_RESPONSE_SET_EMUL_READ_DATA as your response with the faked data used during emulation when you see that field being accessed. Currently the MEMACCESS trap type in DRAKVUF will always switch to view id 0 with singlestep enabled, so you would need a different trap type introduced where the emulation is used instead when needed.

@RadamireZ
Copy link
Author

RadamireZ commented Nov 14, 2022

Thanks a lot,
The permissions are readable only in view 0 since userspace processes can only read from KUSER.
Having another shadow page with read permission just for performing the switch was a possible way ? But it is require another domain or I didn't get it?
I will implement your solution, Thanks
I'm still understanding how to use emulation read, i guess i can not just modify the ticks on the shadow page but i should set something on the emul_read data array, while still is setting slat_id to idx.
For now, just for making attempts, i'm using MEMACCESS trap used for RW access with an if condition in pre_mem_cb where return the VMI_EVENT_RESPONSE_SET_EMUL_READ_DATA only for the gfn of KUSER.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants