Reflection Concerns? #2425
-
|
With C++26 Reflection on the horizon and its planned integration into Glaze, are there any structural concerns regarding reverse engineering? Specifically, will the metadata generated for reflection significantly increase the ease of reconstructing source-level information from the compiled binary, or is the reflection data strictly stripped/obfuscated during the build process? How will Glaze's implementation of C++26 Reflection impact binary security? I'm curious if the reflection system will inadvertently expose internal class structures or member names in a way that makes reverse engineering trivial compared to current macro-based or manual registration methods. We’ve seen with Unity’s IL2CPP (via global-metadata.dat) and Unreal Engine’s reflection system that providing a rich metadata layer makes reverse engineering significantly more trivial. Tools like Il2CppDumper can reconstruct entire class structures, method signatures, and field offsets just by reading the reflection data. As Glaze moves toward more 'automatic' reflection, are there concerns about source-level information leaking into the final binary? Will there be built-in ways to obfuscate or 'strip' this metadata for production builds, or will developers need to manually manage the visibility of their reflected types to prevent giving away the 'blueprint' of their code? Unreal Engine: Unreal’s UProperty and UFunction macros tell the UnrealHeaderTool to generate metadata. This metadata allows the engine to do things like "Blueprints," but it also means a reverse engineer can easily find exactly where your game logic lives by searching for the reflected names in memory. If Glaze moves to a model where everything is automatically reflected by default to save boilerplate, does that change the security profile? I'm worried about a 'blanket' reflection making it too easy for a dumper to map out the entire binary data structures. Please let me know what you thoughts are about all this thank you. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
|
The great news is that C++26 does not bring risks binary security and actually makes it easier to keep the binary secure. In Glaze's C++23 implementation we had to make sure to instantiate a second static string that is just the portion of the source location so that the compiler would optimize away source information that would both bloat the binary and potentially leak some context (albeit minimal). With C++26 reflection we don't have to use source location hacks to get field metadata, which means that we only embed the reflection field names that are actually needed. You can see a simple example of this on compiler explorer: Here's the JSON writing code and we'll compile using the current C++23 approach with Clang: #include <iostream>
#include "glaze/glaze.hpp"
struct my_struct {
std::string text = "Awesome!";
std::string hello = "Hello World";
};
int main() {
my_struct obj{};
std::cout << glz::write_json(obj).value_or("error") << '\n';
return 0;
}In the assembly produced you can see glz::detail::make_static<std::__1::array<char, 8ul>{"\"text\":"}>::value:
.asciz "\"text\":"
...
glz::detail::make_static<std::__1::array<char, 10ul>{",\"hello\":"}>::value:
.asciz ",\"hello\":"So, the If you switch to a GCC compiler you can't even find these strings as it optimizes them to raw bytes to be written out. For C++26, it's even easier to achieve this minimal binary without leaking anything about the program. It's the beauty of true compile time reflection! Here is an example with C++26 reflection and GCC: https://gcc.godbolt.org/z/b15esrj9o |
Beta Was this translation helpful? Give feedback.
The great news is that C++26 does not bring risks binary security and actually makes it easier to keep the binary secure. In Glaze's C++23 implementation we had to make sure to instantiate a second static string that is just the portion of the source location so that the compiler would optimize away source information that would both bloat the binary and potentially leak some context (albeit minimal). With C++26 reflection we don't have to use source location hacks to get field metadata, which means that we only embed the reflection field names that are actually needed.
You can see a simple example of this on compiler explorer:
https://gcc.godbolt.org/z/KnsYe9nvf
Here's the JSON writing c…