We show a legitimate use case for hooking into code at run-time, and demonstrate how this can be done in a way that works on all platforms.
We show a legitimate use case for hooking into code at run-time, and demonstrate how this can be done in a way that works on all platforms.
https://blog.grijjy.com/2017/07/26/cross-platform-code-hooking/
https://blog.grijjy.com/2017/07/26/cross-platform-code-hooking/
Great article! Thanks for sharing!
ReplyDeleteA very interesting article - thanks! But you did miss DMT hooking :)
ReplyDeleteHere is an article about it: hallvards.blogspot.com.au - Hack#15: Overriding message and dynamic methods at run-time :)
ReplyDeleteNicholas Ring I didn't look into DMT hooking myself, since outside of the Windows VCL, dynamic methods aren't used a lot. Interesting article about it though. I hadn't read it, but the algorithms Hallvard uses can easily be adapted to be cross-platfom using the techniques I used for VMT patching.
ReplyDeleteI was wondering about the use of VirtualProtect. I have been using WriteProcessMemory to patch all kinds of stuff without any problems because we always write to the memory of the own process which it has access to. The only case where I had to use VirtualProtect was when I injected some self allocated memory as executable memory because that had to be marked properly in order to not let DEP complain.
ReplyDeleteNice article! Re your actual hooking code, you might want to consider using FlushInstructionCache afterwards. Otherwise the CPU's cache may not reflect the changes.
ReplyDeleteIs Delphi Detours based on your Detours library from 2004? I had thought it was a separate implementation. Mahdi Safsafi might have info.
As a side note, DDetours 2 has a really nice feature supporting multiple methods detouring from a single method, I think via a linked list of methods that are called. I've found this very useful myself. I'm not sure if DDetours is cross-platform, but if not I'd suggest it's well worth looking into contributing to.
David Millington I once read that modern CPUs have a mechanism to detect changes so they don't require manually flushing their cache (source: http://blog.onlinedisassembler.com/blog/?p=133).
ReplyDeleteDavid Millington Fllushinstructioncache is not necessary under x86 ! MS implemented it just in case if they export windows to run on others CPU than x86. If you disasm the function (under Win7), you will find that it does nothing !
ReplyDeleteDDetours v2 isn't based on Erik library and only works under Windows. I'm working on v3 that will support cross platforms (Linux and Android). Right now I'm stuck with ARM decoding.
Stefan Glienke It's better to use VortualProtect over WriteProcessMemory if the modifier belongs to the same process. WriteProcessMemory do internally many checks which makes it slower than (VP+Direct write).
Stefan Glienke, Mahdi Safsafi Very interesting, thanks. Also Mahdi, v3 sounds great.
ReplyDeleteMahdi Safsafi I guess ARM instruction decoding can be challenging, especially since Arm32 and Arm64 are very different. Some things should be easier compared to x86. For example, every Arm32 instruction is either 2 or 4 bytes in size. But you have to take Thumb modes into account, and encoding/decoding jump addresses is more involved.
ReplyDeleteBut the issue I encountered is that mprotect does not seem to work on executable memory pages on iOS and Android, making a Detours-like approach difficult or impossible. Have you found a way to override executable code on ARM platforms?
Erik van Bilsen Truly ARM has a fixed instruction size (4 on ARM, 2 or 4 for thumb) But decoding the instruction itself is a challenge. Instructions there don't use a common format compared to x86 (ModRm, SIB,...). And that's explaining the reason why there is only couple of ARM decoder on the market !
ReplyDeleteFor mprotect, I didn't test on Android yet, but I think it's more likely works the same on Linux. I wrote a SetMemoryPermission function which wraps mprotect. It should works on MSWIN and POSIX-Like. You can find it here : github.com - delphi-detours-library
Please test and let me know.
Mahdi Safsafi I tried to do a quick test of the OsBridge unit, but it seems to be written for FPC for now (based on the BaseUnix and pthreads units it used). So I cannot quickly test this with Delphi yet.
ReplyDeleteHowever, I tried to use mprotect on executable memory pages on iOS and Android, but it failed with an EACCESS error...
What about Linux ? Did it fail too ?
ReplyDeleteMahdi Safsafi No. mprotect for detour-style hooking succeeds on Linux.
ReplyDelete