jonomango / hv

Lightweight Intel VT-x Hypervisor.
MIT License
363 stars 77 forks source link

FF 25 gadget is causing a crash when used for hooking #35

Closed chiefmasterR closed 11 months ago

chiefmasterR commented 11 months ago

Hi there, I'm getting a crash when I place the FF 25 (indirect jump) gadget for EPT hooking and I double checked that I'm doing it right. While mov (register), (address); jmp (register) gadget works fine, I tried to change PTE read permission to 1 when vm-exit was triggered by instruction fetch

if (qualification.execute_access) {
  pte->read_access = 1;
  pte->write_access = 1;
  pte->execute_access = 1;
  pte->page_frame_number = hook->exec_pfn;
}

and the FF 25 gadget worked fine, but as expected, my executable page was exposed, and so was the hook. I think the crash is happening because the instruction can't read the address where we want to jmp? I'm not really sure about this and I think I'm missing something here. I place the hook on first bytes of the function. Here is the analysis of the crash dump, although there is little information.

ERROR_CODE: (NTSTATUS) 0xC0000005 (Access violation)
READ_ADDRESS:  ffffffffffffffff
EXCEPTION_PARAMETER1:  0000000000000000
EXCEPTION_PARAMETER2:  ffffffffffffffff
Attempt to read from address ffffffffffffffff
jonomango commented 11 months ago

Yeah this isn't supported at the moment. It is a little confusing, but if you think about it, this shouldn't be possible anyways:

FF 25 00 00 00 00             jmp [rip+0]
11 22 33 44 55 66 77 88       address

The memory read [rip+0] will return the contents of the original page (which is just garbage) and it'll try to jump to that. A potential fix is to enable MTF-exiting, allow read/write/execute, then remove those permissions after the instruction is done executing. Or just use something like:

push 0x11223344
mov dword ptr [rsp+4], 0x55667788
ret

(The gadget might not be exactly right, but the idea is the same)