csharp/am0nsec/SharpHellsGate/SharpHellsGate/Module/MemoryUtil.cs

MemoryUtil.cs
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace SharpHellsGate.Module {
    /// 
    /// Used to manipulate and extract information from a memory stream.
    /// In this case the memory stream is the NTDLL module.
    /// 
    public clast MemoryUtil : IDisposable {

        /// 
        /// The memory stream representation of the NTDLL module.
        /// 
        protected Stream ModuleStream { get; set; }

        /// 
        /// Dispose the memory stream when no longer needed.
        /// 
        ~MemoryUtil() => Dispose();

        /// 
        /// Dispose the memory stream when no longer needed.
        /// 
        public void Dispose() {
            this.ModuleStream.Dispose();
            this.ModuleStream.Close();
            GC.SuppressFinalize(this);
        }

        /// 
        /// Extract a structure from the memory stream.
        /// 
        /// The Type of the structure to extract.
        /// The offset in the memory stream where the structure is located.
        /// The structure populated or the default structure.
        protected T GetStructureFromBlob(Int64 offset) where T : struct {
            Span bytes = this.GetStructureBytesFromOffset(offset);
            if (Marshal.SizeOf() != bytes.Length)
                return default;

            IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf());
            Marshal.Copy(bytes.ToArray(), 0, ptr, bytes.Length);
            T s = Marshal.PtrToStructure(ptr);

            Marshal.FreeHGlobal(ptr);
            return s;
        }

        /// 
        /// Extract the code from a native Windows function.
        /// 
        /// The location of the function in the memory stream.
        /// The 24 bytes representing the code of the function.
        protected Span GetFunctionOpCode(Int64 offset) {
            Span s = stackalloc byte[24];
            this.ModuleStream.Seek(offset, SeekOrigin.Begin);
            this.ModuleStream.Read(s);
            return s.ToArray();
        }

        /// 
        /// Extract a DWORD value from the memory stream.
        /// 
        /// The location of the DWORD in the memory stream.
        /// The value of the DWORD.
        protected UInt32 ReadPtr32(Int64 offset) {
            Span s = stackalloc byte[4];
            this.ModuleStream.Seek(offset, SeekOrigin.Begin);
            this.ModuleStream.Read(s);
            return BitConverter.ToUInt32(s);
        }

        /// 
        /// Extract a QWORD value from the memory stream.
        /// 
        /// The location of the QWORD in the memory stream.
        /// The value of the QWORD.
        protected UInt64 ReadPtr64(Int64 offset) {
            Span s = stackalloc byte[8];
            this.ModuleStream.Seek(offset, SeekOrigin.Begin);
            this.ModuleStream.Read(s);
            return BitConverter.ToUInt64(s);
        }

        /// 
        /// Extract a WORD value from the memory stream.
        /// 
        /// The location of the WORD in the memory stream.
        /// The value of the WORD.
        protected UInt16 ReadUShort(Int64 offset) {
            Span s = stackalloc byte[2];
            this.ModuleStream.Seek(offset, SeekOrigin.Begin);
            this.ModuleStream.Read(s);
            return BitConverter.ToUInt16(s);
        }

        /// 
        /// Extract an ASCII string from the memory stream.
        /// 
        /// The location of the ASCII string in the memory stream.
        /// The ASCII string.
        protected string ReadAscii(Int64 offset) {
            int length = 0;
            this.ModuleStream.Seek(offset, SeekOrigin.Begin);
            while (this.ModuleStream.ReadByte() != 0x00)
                length++;

            Span s = length = 1024 ? new byte[size] : stackalloc byte[size];
            this.ModuleStream.Seek(offset, SeekOrigin.Begin);
            this.ModuleStream.Read(s);
            return s.ToArray();
        }
    }
}