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();
}
}
}