0

Is it possible to add N count of bytes at the end of the function?

My simple idea is to add the following code:

_asm {
    NOP
    NOP
    NOP
    NOP
    NOP
}

Are there any other ways to do it? (with code, compiler or other methods)

I need it for the hotpatching the function. I have a function that has some IF statements, the function is called 10 times a second or more often. So, in order to increase performance I need to make less checks like "do I need to execute that code?". The boolean in IF statement is not changed so often (i'd say very rarely). I also want to achieve that if I don't need to execute some code, I don't need to check for that.

RIscRIpt
  • 163
  • 3
  • 12
  • I would say bad idea for 10 times per second. Especially you may hit platform/OS that will not allow that. – Slava Mar 06 '13 at 21:46

4 Answers4

1

MSVC has the compiler option /hotpatch whick allows the linker option /functionpadmin which modifies the processing of the final binary in such a way that hotpatching should work for valid functions. You can specify the number of reserved bytes to allow for hotpatching. See the link for details.

Jake H
  • 1,720
  • 1
  • 12
  • 13
  • MSDN says: "When /hotpatch is used in a compilation, the compiler ensures that *first* instruction of each function is *two bytes*, which is required for hot patching." I need at the end of a function and N count. – RIscRIpt Mar 06 '13 at 21:23
  • 1
    Ahh, indeed. Close but no cigar. You could manually map the function into a new executable memory section, copying the machine code and then dynamically spacing the function with X bytes before the prologue, rather than relying on things during compile time. This generally makes AV software freak out, in my experience though. – Jake H Mar 06 '13 at 21:30
1

In general, yes, although you'll need to write your function in assembly to do so.

On the other hand, it looks like what you're doing is micro-optimising your code rather than benchmarking it. BOOLs and conditionals in C++ are really, really fast, and the cost of patching opcodes on modern systems can cause really really surprisingly bad performance penalties (for example, the call to VirtualProtect to make the code writable is going to cost hundreds of thousands more than a single conditional, and you'll force pipeline stalls and cache misses by changing the function inline even if you're running on an embedded system).

So in summary, yes, what you're doing is possible. But unless you are doing this as an "out of interest" excercise or run in a very strange environment where performance of conditionals is critically important but you still write in C, then you probably want to just benchmark your code instead and find the real places where it's slow, instead of going to huge amount of pain and effort to patch things that aren't actually performance critical.

SecurityMatt
  • 6,593
  • 1
  • 22
  • 28
  • 1
    Actually, there are legitimate reasons to do this sort of thing. Consider a binary that detects whether the system is UP or MP and for UP optimizes away certain locking operations/primitives. Please note that I'm not saying that *hotpatching* is the right solution to the OPs problem. Only that there are legitimate reasons to want this sort of thing. – Nik Bougalis Mar 06 '13 at 21:27
  • @NikBougalis: Even in such a scenario, any rational person would either use an interface (SingleProcImpl : IImpl versus MultiProcImpl : IImpl) or swap out the module as a whole (LoadLibrary(isMP? "mod_sp.dll" : "mod_mp.dll")). Hotpatching is really hard, really dirty and can cause really nasty and hard to debug performance and security penalties across your application. – SecurityMatt Mar 06 '13 at 21:31
  • Perhaps - but *rational* is a somewhat relative term especially in certain environments where one has to operate under specific (often ipso facto irrational) restrictions. – Nik Bougalis Mar 06 '13 at 21:33
  • @NikBougalis: Hence why I answered the question for such cases: **yes, although you'll need to write your function in assembly to do so**. – SecurityMatt Mar 06 '13 at 21:37
  • @SecurityMatt, Sorry, I didn't mention that I would rather save performance on a function that is called so many times. But not on a function that is called seldom to hotpactch. As I am still learning, I am interested in this. And I'd _maybe_ implement this not in a HUGE project, so I am not afraid of debugging, crashes and errors. – RIscRIpt Mar 06 '13 at 21:58
  • @RIscRIpt I'm sorry, but if you are still learning then you aren't a good candidate for doing this sort of thing to begin with. – Nik Bougalis Mar 06 '13 at 22:00
  • @NikBougalis, you are right, but I am also interested in alternatives and best variants, so I am here. – RIscRIpt Mar 06 '13 at 22:17
1

You could write the function with a one point return and add in NOPs before the return statement. Although this is platform dependent.

Another method is to place garbage code before the return statement and jump around the garbage code using a label and a goto.

Be aware of compiler and linker optimizations that may remove unused code.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
0

the function is called 10 times a second or more often. So, in order to increase performance

Is your function taking 50-100 milliseconds of time to complete? I mean, is there really a perf problem here? 10 times a second is nothing for simple and regular functions, but can be a lot for some computationally intensive stuff.

There's no universal way of forcing a compiler to do that, to reserve some space. You might be able to find a special way for a specific compiler, but a better approach would be to have multiple versions of the same code or constructing the code on the fly at run time.

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180