0

When programming in Win32, one can execute data as follows:

#include <iostream>

using namespace std;

typedef double(*func)(void);

int main()
{
        // The sample program to display the PI number
    uint8_t code[] = { 0xD9,0xEB,0xC3 }; // fldpi; ret
    uint8_t* p = code;
    func f = reinterpret_cast<func>(p);
    cout << f() << endl;
    return 0;
}

This trick allows to speed up some numeric calculations when the expression to calculate is initially unknown. The only thing you need to do this in Win32 is to disable data execution protection by using the /NXCOMPAT:NO Visual Studio Option. But how to do this in Win64? Is this even possible?

AVK
  • 2,130
  • 3
  • 15
  • 25
  • If you want to use assembler and use C++ variables in your assembly code, there are much better solutions. For example *inline assembly*, or just pass the variables as arguments to the assembly functions. Of course, first you have to consider if you really can write better assembly than a modern optimizing compiler can (which these days is highly unlikely). – Some programmer dude Oct 13 '19 at 13:16
  • What you are looking for is called _self-modifying code_. – Erlkoenig Oct 13 '19 at 13:23
  • @Some programmer dude In order to use inline assembly, you need to invoke the compiler. This is not the case when you need fast calculations. In addition, it will be strange to require the user to install Visual Studio so that he can run the program – AVK Oct 13 '19 at 13:24
  • @Erlkoenig Yes, I know. I don't know how to make it work in Win64 – AVK Oct 13 '19 at 13:25
  • Inline assembly is inlined by the compiler when ***you*** build your program. There's no compilation or assembling done at run-time. Besides, self-modifying code and code in data or stack segments are these days mostly only used for exploits, and many anti-virus programs will flag it as such if the OS even allows it. It's a bad habit, and always have been (even before systems with caches where modifying such data will incur cache refreshes which will lower your expected gains in "speed"). – Some programmer dude Oct 13 '19 at 13:28
  • There are even [video tutorials](https://youtu.be/8-9ImxdpaK0) for that. Doesn't that help? – Erlkoenig Oct 13 '19 at 13:28
  • @Erlkoenig Exactly, in this video its author uses his own segment available to read and execute. I want to make the C++ program data segment available to execute so that it will be possible to execute code that is placed in a memory block allocated by `new` or statically. – AVK Oct 13 '19 at 13:39
  • @Some programmer dude The problem is that it is not known what to compile at compile time – AVK Oct 13 '19 at 13:51
  • But with both inline assembly and with stand-alone assembly files with function you call you can pass *run-time* values through variables that are written to when you run your program. Calling an assembly function can be done just like calling a plain C++ function. – Some programmer dude Oct 13 '19 at 13:55
  • And if you need to "modify" the code itself, make several functions for different cases, and invoke the correct one through a table (or other emulated polymorphic mean). There are *always* better solutions than self-modifying code! – Some programmer dude Oct 13 '19 at 13:56
  • @Erlkoenig: That's not really SMC, it's just JIT into a buffer. (But still the risk of a pipeline nuke is there from executing bytes you just stored.) Anyway, you just need to VirtualProtect your buffer to make it executable, or VirtualAlloc an executable+writeable page. – Peter Cordes Oct 13 '19 at 14:18
  • 1
    Note that with compilers other than MSVC, you need to stop them from optimizing away the stores: calling the buffer as a function pointer isn't seen by the optimizer as reading the data. In GNU C you use `__builtin___clear_cache` (which doesn't actually clear any cache on x86, it just tells the optimizer that stores to the memory need to have actually happened). I added [\_\_asm\_\_ gcc call to a memory address](//stackoverflow.com/q/22367792) to the duplicate list because it explains that; future readers might be using GCC on Windows. – Peter Cordes Oct 13 '19 at 14:24

0 Answers0