jonomango / hv

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

Suggestion about ept hooking #17

Closed thewolfram closed 1 year ago

thewolfram commented 1 year ago

hey jonomango, I have a suggestion about ept hooking. I think it is better to directly hook a target function and when ept violation happens just give away original unmodified function which we already copied to our memory if read happens, and if execution happens then just give original page. I think this way it wont be possible to detect illegal memory addresses while stack walking. Please correct me if I'm wrong.

jonomango commented 1 year ago

Im not too sure what you mean… how would we hook anything if we give the original page when execution or read happens? I might be misunderstanding something…

thewolfram commented 1 year ago

Im not too sure what you mean… how would we hook anything if we give the original page when execution or read happens? I might be misunderstanding something…

So, for example we want to hook some function, we allocate memory and copy the entire page where function resides to our allocated memory. Then we directly install hook in this function and install ept hook. When the ept violation happens and someone wants to read the function we will give them our allocated memory, if someone wants to execute the function we will give them the original page of function which we hooked. This way I guess its possible to avoid having illegal memory addresses in call stack

jonomango commented 1 year ago

I see... but isn't that what the current EPT hooking implementation is already doing? This code will give the guest the original page if it is being read/written while another page is given if it is being executed.

thewolfram commented 1 year ago

I see... but isn't that what the current EPT hooking implementation is already doing? This code will give the guest the original page if it is being read/written while another page is given if it is being executed.

No, I suggest the opposite of what is currently implemented (give the guest our allocated memory if being read/written, give original page if being executed, original page has our hook)

jonomango commented 1 year ago

I mean, you can just swap the parameters when installing the EPT hook and you'll achieve that, no need to change any code. EDIT: Actually, you'll also probably have to change this line as well...

jonomango commented 1 year ago

Is there a reason why you prefer this method over what is currently implemented? IMO I don't really see the advantage of either over the other. EDIT: Actually, doing the suggested method will trigger PatchGuard if the EPT hook is installed and the hypervisor is unloaded since you would be modifying the original memory.

thewolfram commented 1 year ago

Is there a reason why you prefer this method over what is currently implemented? IMO I don't really see the advantage of either over the other. EDIT: Actually, doing the suggested method will trigger PatchGuard if the EPT hook is installed and the hypervisor is unloaded since you would be modifying the original memory.

As I said, there will be non legit memory address in call stack which will point to our 'hooked' page which we used when installed ept hook

thewolfram commented 1 year ago

For PG, we can just remove all ept hooks when unloading, no?

I think overall doing ept hook this way will be more stealthy

jonomango commented 1 year ago

I think you are misunderstanding what EPT hooking does... The addresses in the call stack are virtual addresses, while EPT hooking works with physical addresses.

thewolfram commented 1 year ago

I'll test my theory when I get home and let you know.

jonomango commented 1 year ago

To further illustrate, the addresses in the call stack will be the same no matter what in each of the following scenarios:

  1. No hypervisor is loaded (bare metal).
  2. No EPT is being used.
  3. EPT is being used, but not EPT hooking.
  4. EPT is being used, with EPT hooking.

The only thing that will produce funny values in the call stack is what YOU decide to use the hidden executable page for. The smartest way is to just use it for stealthy byte-patching. The second smartest way is to bytepatch with a 0xCC, vm-exit on the exception, and run all your hook code in root-mode. Third way is to bytepatch a CALL/JMP instruction to your hook, which will end up with funny values in the call stack no matter which EPT hook method you use.

Closing this issue since it is a non-issue.