views:

288

answers:

5

I have a pointer to a function (which i get from a vtable) and I want to edit the function by changing the assembler code (changing a few bytes) at runtime. I tried using memset and also tried assigning the new value directly (something like mPtr[0] = X, mPtr[1] = Y etc.) but I keep getting segmentation fault. How can I change the code?

(I'm using C++)

OS is windows.

+2  A: 

Short answer: It isn't possible (at least with the popular desktop OSes like Windows and Linux).

Longer answer: the code is stored in a "code segment" (executable page) that's inaccessible for writing by the process. Hence the OS will throw and exception every time you try to write it.

The only real options for dynamically modifiable code in C and C++ are:

  1. Embed some language on top: like Lua or Python
  2. Generate new code at runtime, compile it and link dynamically to your program. This is complex to tie in together, but can provide the results you need - it's actually being used by some commercial tools in the area of simulation for getting high performance.
Eli Bendersky
where does MS detour it?
Kugel
The only documentation of how Detours does it: http://research.microsoft.com/pubs/68568/huntusenixnt99.pdf
Travis Gockel
+3  A: 

Depending on Operating System and/or architecture you may or may not write to executable pages.

Check documentation about marking pages as executable or read-only in the Intel (IA-32e) manuals. The code may be located in a read only section, therefore, you may not write to it.

You may mark the code not to reside in read only pages, but it's compiler specific (JIT compilers do this).

Under MSVC, you can use the #pragma section to create a read-write section and use #pragma alloc_text to put functions in it.

Aram Hăvărneanu
A: 

Memory sections where your code reside are usually marked as readonly. That's why you get segmentation failure. You can try to remove this flag from section by either special keys for compiler (not sure about that) or by modifying binary file (again, not 100% that it is possible)

Andrey
A: 

In general, you are trying to write to the code segment, something new operating systems will prevent you to do. This is the way some viruses worked.

There are APIs to remove that protection, but they are operating system dependent.

elcuco
+5  A: 

In generally: if memory is allocated with API call VirtualAlloc than you can change the memory attributes with API call VirtualProtect. Check first memory attributes with API call VirtualQuery

GJ
Thanks,this is exactly what I was looking for
Pagis