If you're never had a chance to play with it, Detours, the more complex alternative to the hot-patch strategy Chen is talking about, is really slick.
What you do in Detours is, freeze the process, disassemble the first several instructions of the function you want to hook, copy out enough of them to make room for a full jump instruction, copy in your hook function somewhere in memory, followed by the instructions you stole to make room for the jump, followed by a jump back to the original function. Then you patch in a jump to that location and unfreeze the process.
The example programs for Detours do this, for instance, on every libc function to implement library tracing.
That this "just works" with Microsoft's Detours package is kind of mindboggling.
This is a great project to tackle if you want to write programmable debuggers. We've done it for Win32 (you need a full build environment to use Detours; we have the whole thing in Ruby), OS X, and Linux. It's crazy useful.
Detours is really cool. Last I checked (last year?) it was free for 32-bit code, but you had to pay for or license the 64-bit version. There's an open-source (but not 100% functionally-equivalent) alternative called EasyHook: http://easyhook.codeplex.com/
An anecdote: I've got a Sony VAIO Z series laptop, one of the 2010 models with "Switchable Hybrid" graphics -- that is, there's a switch marked "Auto"/"Speed"/"Stamina" which you can use to switch between the embedded Intel GPU and the discrete nVidia GPU. The laptop itself is great -- probably the best developer's laptop I've ever seen/used -- but drivers have always been a real pain. Anyway, as it turns out, I was updating the drivers last week and just happened to notice the Detours DLL within the driver installer files; so it seems that the graphics driver actually just checks the position of the switch and uses Detours to direct any calls to the "real" driver for whatever hardware is selected.
Does that handle double detours, where two different programs each patch the same function?
That was the most entertaining/frustrating (depending on your world view; it made the journey way more interesting, but also a lot longer) part of hacking classic Mac OS.
You would have a zillion extensions (apple and third party) each patch tens of OS calls, both at startup and, in cases where the Finder reset patches, after the Finder launched, or even after every application launched (to get your code running at such times, you would have to patch another OS call). On PowerPC machines you would have the added fun of patching PPC code with 68k code and vice versa.
That that _sometimes_ worked was really mind boggling. Relative to that, patching your own libc seems easy.
>Does that handle double detours, where two different programs each patch the same function?
I believe Detours patches the import table inside a single process, it does not patch the call on a system wide basis, so there really is no 'two different programs each patching the same function'. In theory you could have two different pieces of code running in the same process doing that (i.e. each patching a given function), but Detours gives you a 'trampoline' function to invoke the original thing you are patching so I believe the second to patch, when invoking the trampoline function would simply invoke the first patch, which when invoking its own trampoline would invoke the original, though I haven't tried that so it may not work that way :)
VS uses this mechanism allow you to run as non-admin even though there is TONS of VS and third party code that expects to do things like write to HKLM which is a no-no if you are not an admin.
It doesn't actually patch the import table, but actually finds the functions address in memory. This has the benefit of working for statically linked libraries and run-time dynamic linking (loading). You're correct in all other respects. My casual impression is that the technique would allow more than one library to hook into the target function.
Ahh okay, that makes sense. Modifying the actual page the instructions live on in memory would force it to be marked as dirty and thus if paged out it would actually need to hit the page file instead of just being able to discard it and when it is needed again fetch it from the original dll no? I suppose that is a minor concern assuming you aren't patching tons and tons of things that reside on lots of different pages.
I'm a little fuzzy on whether they had to deal with paging or not. At the very least they'd have to mark the pages as dirty, but I think that happens when you mark it as write-able.
I used Detours years ago to hook into the Wave I/O API and DirectSound to capture the audio I/O. I was blown away by the power of API Hooking. Nothing concrete came out of it but it was a lot of fun.
If all you need is to trap a few functions Intel published a paper on how to intercept API call. It can be very useful if you need to fix some function inside a DLL you load, modify it's behavior or log calls for debugging. There is a lot of potential uses and it's a fun technique that teaches you some things about cache control and assembly.
That's coincidental. I once made a Linux kernel function hijacking module and I had the exact same idea. Well, without the freezing of other (kernel) threads, I didn't realize the problems yet.
Now that I think about it I'm even more surprised it worked in the first place. I thought Linux had w^x protection?
Comments
If you're never had a chance to play with it, Detours, the more complex alternative to the hot-patch strategy Chen is talking about, is really slick.
What you do in Detours is, freeze the process, disassemble the first several instructions of the function you want to hook, copy out enough of them to make room for a full jump instruction, copy in your hook function somewhere in memory, followed by the instructions you stole to make room for the jump, followed by a jump back to the original function. Then you patch in a jump to that location and unfreeze the process.
The example programs for Detours do this, for instance, on every libc function to implement library tracing.
That this "just works" with Microsoft's Detours package is kind of mindboggling.
This is a great project to tackle if you want to write programmable debuggers. We've done it for Win32 (you need a full build environment to use Detours; we have the whole thing in Ruby), OS X, and Linux. It's crazy useful.
Detours is really cool. Last I checked (last year?) it was free for 32-bit code, but you had to pay for or license the 64-bit version. There's an open-source (but not 100% functionally-equivalent) alternative called EasyHook: http://easyhook.codeplex.com/
An anecdote: I've got a Sony VAIO Z series laptop, one of the 2010 models with "Switchable Hybrid" graphics -- that is, there's a switch marked "Auto"/"Speed"/"Stamina" which you can use to switch between the embedded Intel GPU and the discrete nVidia GPU. The laptop itself is great -- probably the best developer's laptop I've ever seen/used -- but drivers have always been a real pain. Anyway, as it turns out, I was updating the drivers last week and just happened to notice the Detours DLL within the driver installer files; so it seems that the graphics driver actually just checks the position of the switch and uses Detours to direct any calls to the "real" driver for whatever hardware is selected.
Does that handle double detours, where two different programs each patch the same function?
That was the most entertaining/frustrating (depending on your world view; it made the journey way more interesting, but also a lot longer) part of hacking classic Mac OS.
You would have a zillion extensions (apple and third party) each patch tens of OS calls, both at startup and, in cases where the Finder reset patches, after the Finder launched, or even after every application launched (to get your code running at such times, you would have to patch another OS call). On PowerPC machines you would have the added fun of patching PPC code with 68k code and vice versa.
That that _sometimes_ worked was really mind boggling. Relative to that, patching your own libc seems easy.
>Does that handle double detours, where two different programs each patch the same function?
I believe Detours patches the import table inside a single process, it does not patch the call on a system wide basis, so there really is no 'two different programs each patching the same function'. In theory you could have two different pieces of code running in the same process doing that (i.e. each patching a given function), but Detours gives you a 'trampoline' function to invoke the original thing you are patching so I believe the second to patch, when invoking the trampoline function would simply invoke the first patch, which when invoking its own trampoline would invoke the original, though I haven't tried that so it may not work that way :)
VS uses this mechanism allow you to run as non-admin even though there is TONS of VS and third party code that expects to do things like write to HKLM which is a no-no if you are not an admin.
It doesn't actually patch the import table, but actually finds the functions address in memory. This has the benefit of working for statically linked libraries and run-time dynamic linking (loading). You're correct in all other respects. My casual impression is that the technique would allow more than one library to hook into the target function.
Ahh okay, that makes sense. Modifying the actual page the instructions live on in memory would force it to be marked as dirty and thus if paged out it would actually need to hit the page file instead of just being able to discard it and when it is needed again fetch it from the original dll no? I suppose that is a minor concern assuming you aren't patching tons and tons of things that reside on lots of different pages.
I'm a little fuzzy on whether they had to deal with paging or not. At the very least they'd have to mark the pages as dirty, but I think that happens when you mark it as write-able.
I used Detours years ago to hook into the Wave I/O API and DirectSound to capture the audio I/O. I was blown away by the power of API Hooking. Nothing concrete came out of it but it was a lot of fun.
If all you need is to trap a few functions Intel published a paper on how to intercept API call. It can be very useful if you need to fix some function inside a DLL you load, modify it's behavior or log calls for debugging. There is a lot of potential uses and it's a fun technique that teaches you some things about cache control and assembly.
http://software.intel.com/en-us/articles/intercepting-system...
That's coincidental. I once made a Linux kernel function hijacking module and I had the exact same idea. Well, without the freezing of other (kernel) threads, I didn't realize the problems yet.
Now that I think about it I'm even more surprised it worked in the first place. I thought Linux had w^x protection?
It does, but you have to explicitly turn it on for the pages you care about.