ruptura
ruptura copied to clipboard
Support injecting NativeAOT-compiled DLLs (.NET 8)
In theory, Ruptura + NativeAOT is a match made in heaven. We could just inject a NativeAOT-compiled DLL and directly invoke an entry point method in it, skipping ruptura-<arch>.dll
and all the ceremony around .NET hosting entirely.
For this to work, the source generator would need to export a function that we can invoke to pass in these parameters:
https://github.com/vezel-dev/ruptura/blob/adc65b4532d70c0f61e6c4a0aafd29e1466408a5/src/module/main.h#L3-L12
That function would then do all the initialization that the native module currently does (e.g. calling InjectedProgramContext.Initialize()
), and then call the user's IInjectedProgram.RunAsync()
implementation.
NativeAOT does come with a number of disadvantages that are inherent to that model of compilation: Very limited reflection, no dynamic code generation, forced IL trimming, and more. This means that any NativeAOT support would exist alongside our current hosting model so that users can choose the approach that makes the most sense for them.
NativeAOT support in .NET 8 should be good enough that we can do this.
When we do this, we should just document the exported entry point that Vezel.Ruptura.Injection will support. That way, it can effectively be used to inject arbitrary native DLLs that conform to that signature. Something like:
typedef struct
{
size_t size;
const wchar_t *nonnull *nonnull argument_vector;
uint32_t argument_count;
uint32_t injector_process_id;
uint32_t main_thread_id;
} ruptura_native_parameters;
__declspec(dllexport) uint32_t ruptura_native_main(ruptura_native_parameters *nonnull parameters);