/// <summary> /// Read memory from a process. /// </summary> /// <param name="process">The process to read from.</param> /// <param name="base_address">The base address in the process.</param> /// <param name="length">The length to read.</param> /// <returns>The array of bytes read from the location. /// If a read is short then returns fewer bytes than requested.</returns> /// <exception cref="NtException">Thrown on error.</exception> public static byte[] ReadMemory(SafeKernelObjectHandle process, long base_address, int length) { using (SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(length)) { NtStatus status = NtSystemCalls.NtReadVirtualMemory(process, new IntPtr(base_address), buffer, buffer.Length, out int return_length); if (status != NtStatus.STATUS_PARTIAL_COPY) { status.ToNtException(); } return(buffer.ReadBytes(return_length)); } }
/// <summary> /// Query state data for the WNF object. /// </summary> /// <param name="type_id">Optional Type ID.</param> /// <param name="explicit_scope">Optional explicit scope.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The state data.</returns> public NtResult <WnfStateData> QueryStateData(WnfTypeId type_id, IntPtr explicit_scope, bool throw_on_error) { int tries = 10; int size = 4096; while (tries-- > 0) { using (var buffer = new SafeHGlobalBuffer(size)) { ulong state_name = StateName; NtStatus status = NtSystemCalls.NtQueryWnfStateData(ref state_name, type_id, explicit_scope, out int changestamp, buffer, ref size); if (status == NtStatus.STATUS_BUFFER_TOO_SMALL) { continue; } return(status.CreateResult(throw_on_error, () => new WnfStateData(buffer.ReadBytes(size), changestamp))); } } return(NtStatus.STATUS_BUFFER_TOO_SMALL.CreateResultFromError <WnfStateData>(throw_on_error)); }