PolyHook_2_0
PolyHook_2_0 copied to clipboard
Discuss Features Going Forward
Please propose new milestones and features for the project here. I want to create a queue of actionable tickets for myself and contributors to work on. What do you all want next, and in what order? Some potential ideas:
- Linux Port
- Language Bindings (Which?)
- ZyDis support
- Out of process support
- Inline hooks without typdef research
Language Bindings -> rust and support windows kernel mode
https://github.com/ZhuHuiBeiShaDiao/PFHook https://github.com/wbenny/hvpp https://github.com/LordNoteworthy/cpu-internals https://github.com/Bareflank/extended_apis_example_hook
I would be interested in Inline Hooks.
Some work on inline hooks without typedefs: https://github.com/stevemk14ebr/PolyHook_2_0/blob/inlineNOtypedef/UnitTests/TestAsmJit.cpp#L58
I've taken an approach here to making the typedef tunable at runtime, you still need to provide the type info for forwarding to work correctly and everything, but you can configure it at runtime now without recompiling the application. It JITs a 'Inline Callback" stub to translate the hooking function abi into the host abi using the AsmJit Library. Host ABI detection is automatic by the library, the hooked function abi is specified by the asmjit::FuncSignature structure.
This is so so so so not done yet, but the P.O.C works, which is super exciting i think (continuation after redirection doesn't work yet).
@Randshot significant work has been done. I fixed a serious bug in relocation, and added JIT support for callbacks. Still need to add return value override, and return address spoofing but it's usable at this stage.
https://github.com/stevemk14ebr/PolyHook_2_0/pull/15 https://github.com/stevemk14ebr/PolyHook_2_0/blob/master/UnitTests/TestDetourNoTDx86.cpp#L82
@stevemk14ebr
I have taken a look at your example, and I must say, it looks very promising.
One question though, do you think it would be possible to somehow capture some/all registers at an arbitrary (e.g. mid function) location, read/modify them in a hook and then restore them with the modified version.
I thought that maybe you could use asmjit::x86::Assembler to do that, similar to what you have done in the example. What I am asking for basically, is register access like with breakpoints, but without any.
I don't know how realistic that is though.
At the moment I have a very hacky wrapper around minhook to do that, but it is neither efficient or clean.
If I can find the time, I may actually look into this myself. Just wanted to express my idea here :)
If you can emit the proper asm stub using asmjit you can do anything, it's pretty awesome. With PolyHook you get a free transfer to anywhere without stack or register spoiling. The rest is up to you, just point PolyHook's hook constructor 'callback' param to your Jit stub like my example, and do the rest in asm.
I really like this way because then we can effectively write little 'plugins' for the detours to add features. As is the ILCallback module gives you 'dynamic' typedefs and ret spoofing (not fully done though, modified structure params aren't written back yet nor ret value)
For example you can just point PolyHook to the middle of the function, and then emit a little asmjit stub to mov whatever you want out of the reg or w/e. Just be sure to call the trampoline to transfer back and not spoil stack or regs in your stub (alignment too). This may fail to fix up jmps that point into the overwritten section in the middle as instructions before the hook address are not considered when relocating, maybe I will work on this if it is a problem
I will be working on finishing ILCallback and then ZyDis integration and then we'll see about maybe a move into kernel (probably a big move, first time doing kernel). If you want to play around with midfunction stuff i can fix any bugs you find or maybe see if you need any features/fixes, let me know how it goes.
EDIT: P.S. make sure you're on the poc_ret_spoof branch for the asmjit stuff, that's most up to date
Adding PH2 to vcpkg would be great for getting new people to use the library.
I would personally use and recommend conan, but vcpkg would be fine too, I guess.
https://github.com/Microsoft/vcpkg/issues/4984 im fine with packaging. If anyone wants to submit packaging requests elsewhere go ahead, just let me know first
I've finished work on runtime callback generation. As of today i'm merging PLH::ILCallback to master, this module will take a function typedef as a string and generate a translation stub that will move all the parameters into a structure. A pointer to this structure, and the number of args, as well as a small buffer for spoofing return value are passed to a callback method. In this callback method you may modify the arguments in the structure, they will be written back before the original is called, and you can also optionally write a return value and it will overwrite the original functions just after it's called (as it is now it always writes return value, so you must set it if you function is non-void).
Here is an example: https://github.com/stevemk14ebr/PolyHook_2_0/blob/master/UnitTests/TestDetourNoTDx86.cpp#L416 the arguments are re-written to 5, if they are equal to the value 1337 coming in. The return value is also modified to be 1337. This is x86/x64 compatible and works with all calling conventions and basic types/pointers (returning/passing structures directly is not supported).
The goal of this was to make detours runtime compatible w/o needing to recompile your callback stubs. With this work GUI tools that 'detour', and integration with other languages, are now possible
I'm starting zydis integration today and then after that will work on packaging for first vcpkg then maybe more (zydis should finalize our last dependency addition for a while). If anyone wants to work on packaging master as-is for fun that work would be merged.
Zydis integration is probably pre-alpha ready. It passes my simple disassembler tests so if anyone wants to poke at it have fun. There's FOR SURE issues and cases not handled yet, just message me on gitter if you find some
#10
PolyHook has been added to vcpkg today! https://github.com/microsoft/vcpkg/issues/4984#issuecomment-547214332
C# bindings would be nice
@stevemk14ebr is it possible to use zydis with vcpkg? It always defaults to capstone. Also static linking by default would be nicer if it's possible to set with vcpkg. Now you need to configure your project to use static linking with special vcpkg tags
There's been some big changes to the way this projects cmake works that should make turning options like this on and off much easier. Unfortunately vcpkg uses and older version where this is harder. If you would be interested in a making a PR on Microsoft's vcpkg repo to update the configuration there, I would be appreciative. I'm not motivated enough to change that anytime soon if I am honest.
Hi, What about Linux and MacOS support ? I guess you only need to implement memory allocators and memory protectors. I'm trying to port it here: https://github.com/Nemirtingas/PolyHook_2_0/tree/cross_platform_impl.
I already made a small detour lib for all 3 oses: https://github.com/Nemirtingas/mini_detour
Cross platform would be awesome! You're correct that the allocators and memory protectors are the primary concerns. I believe i've fully abstracted these already so hopefully it's not too bad to implement new OSes. The actual logic of any of the hooks would not have to be changed, I didn't make assumptions about the ABI or binary layout anywhere.
The cmake will also need to be modified so that when not building on windows hooks types such as EAT, IAT, VEH (HWBP and BP) are disabled. The first two EAT and IAT dont make sense on anything except windows and the all hooks that use VEH would have to be re-written to the point seperate implementations would be preferred.
- Folder Exceptions: disabled
- Folder PE: disabled
I personally lost motivation to do this myself, but if you get it finished i'd happily merge. Just make sure you don't break the existing windows implementation, and follow the object oriented layout of the project. You might need to abstract FBAllocator a bit.
Linux port should be working now, I successfuly hooked some functions like puts. https://github.com/Nemirtingas/PolyHook_2_0/tree/cross_platform_impl
Are you comfortable writing unit tests for Linux functionality? This will help me verify both windows and linux implementations work correctly. Once this is done and you feel comfortable in the implementation please submit a PR and I will perform a review when I have time.
One could use the github actions CI, it has native Windows/Linux/MacOS runners that could run your project tests.
CI would be awesome, for now just need unit tests
For now, I just run your tests but on Linux/MacOS. TestMemProtector.cpp TestDisassembler.cpp TestDetourx86.cpp TestDetourx64.cpp
At least some of the cases of those tests require windows APIS, are you ifdef-ing those portions with linux apis when appropriate? ex: https://github.com/stevemk14ebr/PolyHook_2_0/blob/01ec7c7ddee1d0da9cc49c4adf930eb5d6a86ba1/UnitTests/TestDetourx64.cpp#L141
I've split the tests into directories, 1 for each OS. Obviously I removed Windows specific stuff from Linux tests.
@Nemirtingas i merged your branch under https://github.com/stevemk14ebr/PolyHook_2_0/tree/unix
Hi, Ok, I wasn't working on this recently. Apple's code might not work at all but if I remember correctly, linux was working on an Ubuntu VM but was not working in the github worflows.
Something i've been looking for a long time and i haven't seen any hooking engine or library implement is something like microsoft detours binary edits.
If we could modify the binary in a way it doesn't need injection that'd be very usefull. Microsoft detours does it by creating additional sections to the PE.
Also hooking local - non windows apis would be great. Suppose i have/know a function offset relative to binary start address(the file on disk). If we could hook those that'd be very usefull.
Also hooking local - non windows apis would be great. Suppose i have/know a function offset relative to binary start address(the file on disk).
Polyhook can already do this at runtime, which is what i think you're talking about here? For the on-file hooks I agree that would be cool, if you have the time I would review a PR for that!
Language Bindings -> rust and support windows kernel mode
Rust bindings would be great.