c++constexprxor

constexpr Values with Addresses to Functions


I am attempting to have the address of a function be stored in a xor'ed form in memory similar to the XorStr function that is widely used for strings which just takes a string. Stores it in a semi-encrypted form so that basic reverse engineer attempts cannot see the strings outright. I am trying to achieve a similar thing with the call of a function. The code below is currently how I am attempting to achieve it, and when I look at it in IDA the "salt" is completely revealed and stored in the file. Which defeats the whole purpose

Basic Function Encryption Code

__forceinline constexpr uintptr_t EncryptFunctionCall(uintptr_t PointerToFunction, uintptr_t Salt)
{
    return PointerToFunction ^ Salt;
}

Reproducible Example

__forceinline constexpr uintptr_t EncryptFunctionCall(uintptr_t PointerToFunction, uintptr_t Salt)
{
    return PointerToFunction ^ Salt;
}

__declspec(noinline) void HiddenFunctionCall()
{
    std::cout << "Hello\n";
}

__declspec(noinline) void MainThread()
{
    std::cout << EncryptFunctionCall((uintptr_t)&HiddenFunctionCall, 0x999) << "\n";
}

The current (undesired) result in IDA is this: (unsigned __int64)HiddenFunctionCall ^ 0x999

Desired Result: (unsigned __int64)7FF9673A1859

I assume the issue is passing the pointer to a function so I am either asking for an alternative or a fix to my current code if one is known. Any help much appreciated.


Solution

  • The standard language currently does not allow you to do that, already because it is impossible to do the conversion from function pointer to uintptr_t in a constant expression.

    Even as an optimization this isn't feasible for the compiler, because the numeric value of the address of the function is decided only when linking, not by the compilation step.

    This functionality would need to be implemented in the linking step or after that by direct modification of the executable.

    And if ASLR is enabled (as normally is the case nowadays), then the numeric value of the function address even changes in each run of the program, so it is completely impossible to do the XOR at build time.