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/

Comments

  1. A very interesting article - thanks! But you did miss DMT hooking :)

    ReplyDelete
  2. Nicholas 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.

    ReplyDelete
  3. I 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.

    ReplyDelete
  4. Nice article! Re your actual hooking code, you might want to consider using FlushInstructionCache afterwards. Otherwise the CPU's cache may not reflect the changes.

    Is 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.

    ReplyDelete
  5. 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).

    ReplyDelete
  6. David 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 !
    DDetours 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).

    ReplyDelete
  7. Stefan Glienke, Mahdi Safsafi Very interesting, thanks. Also Mahdi, v3 sounds great.

    ReplyDelete
  8. Mahdi 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.

    But 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?

    ReplyDelete
  9. 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 !

    For 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.

    ReplyDelete
  10. 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.

    However, I tried to use mprotect on executable memory pages on iOS and Android, but it failed with an EACCESS error...

    ReplyDelete
  11. What about Linux ? Did it fail too ?

    ReplyDelete
  12. Mahdi Safsafi No. mprotect for detour-style hooking succeeds on Linux.

    ReplyDelete

Post a Comment