/// <summary> /// Create a VBS enclave. /// </summary> /// <param name="process">The process to create the enclave in.</param> /// <param name="size">Size of the enclave.</param> /// <param name="flags">Flags for the enclave.</param> /// <param name="owner_id">Owner ID. Must be 32 bytes.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The created enclave.</returns> public static NtResult <NtEnclaveVBS> Create( SafeKernelObjectHandle process, long size, LdrEnclaveVBSFlags flags, byte[] owner_id, bool throw_on_error) { if (owner_id is null) { owner_id = new byte[32]; } if (owner_id.Length != 32) { throw new ArgumentException("Owner ID must be 32 bytes.", nameof(owner_id)); } IntPtr base_address_value = IntPtr.Zero; var create_info = new EnclaveCreateInfoVBS() { Flags = flags, OwnerID = owner_id }; using (var buffer = create_info.ToBuffer()) { return(NtLdrNative.LdrCreateEnclave(process, ref base_address_value, IntPtr.Zero, new IntPtr(size), IntPtr.Zero, LdrEnclaveType.VBS, buffer, buffer.Length, out int error) .CreateResult(throw_on_error, () => new NtEnclaveVBS(new SafeEnclaveHandle(base_address_value), process))); } }
/// <summary> /// Call a method in the enclave. /// </summary> /// <param name="routine">The routine address to call.</param> /// <param name="parameter">The parameter to pass to the routine.</param> /// <param name="wait_for_threads">True to wait for a free thread.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The return value from the call.</returns> public static NtResult <long> Call(long routine, long parameter, bool wait_for_threads, bool throw_on_error) { IntPtr ptr = new IntPtr(parameter); return(NtLdrNative.LdrCallEnclave(new IntPtr(routine), wait_for_threads, ref ptr).CreateResult(throw_on_error, () => ptr.ToInt64())); }
/// <summary> /// Initialize the enclave. /// </summary> /// <param name="thread_count">The number of threads to create.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The number of created threads.</returns> public NtResult <int> Initialize(int thread_count, bool throw_on_error) { EnclaveInitInfoVBS init_info = new EnclaveInitInfoVBS() { Length = Marshal.SizeOf(typeof(EnclaveInitInfoVBS)), ThreadCount = thread_count }; using (var buffer = init_info.ToBuffer()) { return(NtLdrNative.LdrInitializeEnclave(_process, _handle, buffer, buffer.Length, out int error).CreateResult(throw_on_error, () => buffer.Result.ThreadCount)); } }
/// <summary> /// Load a module into the enclave. /// </summary> /// <param name="module_name">The name of the module</param> /// <param name="flags">Flags or path.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The NT status.</returns> public NtStatus LoadModule(string module_name, IntPtr flags, bool throw_on_error) { return(NtLdrNative.LdrLoadEnclaveModule(_handle, flags, new UnicodeString(module_name)).ToNtException(throw_on_error)); }
/// <summary> /// Get address of a procedure in a mapped image. /// </summary> /// <param name="dll_handle">The handle to the mapped image.</param> /// <param name="name">The name of the procedure to find.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The procedure address.</returns> public static NtResult <IntPtr> GetProcedureAddress(IntPtr dll_handle, string name, bool throw_on_error) { return(NtLdrNative.LdrGetProcedureAddress(dll_handle, new AnsiString(name), 0, out IntPtr addr).CreateResult(throw_on_error, () => addr)); }