2

I have a (so-called) function with multiple entry points but only one ret.

I am trying to understand how to add a hook to the function.

The main problem I'm facing is the code that is placed right after this function - it can be executed at any time so I need to make sure that it won't crash the program.

My idea was to replace the ret instruction with a nop instruction, and then jump to my hook. At this point I'll check whether the return address matches a call to the said function, or to the function that occurs after the ret.

I am not satisfied with this because I can't be sure that the code after ret is the prologue of a function - it may be any code, and I have no idea how the stack will look at this point - meaning that maybe the data that was pushed into it matches a call to the function I am trying to hook.

Does anyone here have a better idea?

Edit: Forgot to mention that I can't add more than 2 jumps.

2
  • 2
    is this a dynamic hook or a static hook? what tool are you using? You should look at how shadow stack works as it is used to protect backward paths.
    – R4444
    Commented Jun 8, 2021 at 23:40
  • Are you sure all the entry points aren't just part of the same "bigger than you realised" function? I know this is a common problem when reverse engineering obfuscated code, perhaps no so much otherwise. You can hook the middle (or the near-end) of a function, assuming certain conditions. I wouldn't go so far as to say it was a general rule, but it is certainly possible in some situations where you don't have to deal with stack variables. You can also use a 2 byte jump to somewhere close (127 bytes +/-) the end of your function, if you can find some unused space. Elsewise, what Rolf said. Commented Jun 13, 2021 at 3:13

2 Answers 2

1

Hook all of the entrypoints and divert the return address to something you control. If you're doing this for compiler-generated code on x64, you'll need to be careful to preserve exceptions thrown across function boundaries -- but it doesn't seem like compiler-generated code, if you're talking about a "function with multiple entrypoints".

3
  • I'm sorry I should have mentioned that I can add 2 hooks maximum
    – EL_9
    Commented Jun 8, 2021 at 22:18
  • Why? Where does that constraint come from? Commented Jun 8, 2021 at 22:26
  • My instructor added this constraint to make it more complicated basically.
    – EL_9
    Commented Jun 8, 2021 at 22:32
0

If there is a single RET then all entrypoints must eventually converge on the path that reaches it. The first few instructions of the common path would be the ideal location to place your single hook. If you need the function to complete execution in order to produce the proper side-effects or whatever, then you can run the replaced instructions from a local buffer in your code, then call the remaining instructions in the function, and finally return to the caller.

If the common path is simply the RET instruction itself (because the multiple entrypoints branch or jump to the RET), then you can redirect them all to your single JMP instruction, thereby achieving the hook without using multiple jumps, only multiple modifications.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.