/// <summary> /// Read a generic value from a memory address. /// </summary> /// <typeparam name="T">The type to read.</typeparam> /// <param name="memaddress"></param> /// <returns></returns> public T ReadGeneric <T>(long memaddress) where T : struct { int size = GenericBitConverter.GetTypeSize(typeof(T)); byte[] bytes = ReadByteArray(memaddress, size); return(GenericBitConverter.ToStruct <T>(bytes)); }
/// <summary> /// Get the value this object points to as the specified type, if possible. /// </summary> /// <returns></returns> public T GetValue() { // Get the bytes and handle the null case byte[] bytes = GetBytes(TargetSize); if (bytes == null) { return(default(T)); } return(GenericBitConverter.ToStruct <T>(bytes)); }
/// <summary> /// Execute code after loading the given arguments into the processes's memory. /// Pointers to those arguments are then inserted in the original assembly code. /// </summary> /// <param name="asm"></param> /// <param name="arguments"></param> /// <param name="syncWait">Sync timeout in milliseconds (0ms = async).</param> public static void ExecuteFunction(IntPtr pHandle, byte[] asm, Dictionary<int, object> arguments = null, int timeout = 3000) { if (arguments == null) arguments = new Dictionary<int, object>(); Dictionary<int, byte[]> argData = new Dictionary<int, byte[]>(); foreach (int idx in arguments.Keys) argData[idx] = GenericBitConverter.ToBytes(arguments[idx]); int argSz = argData.Sum(p => p.Value.Length); long asmAddr = 0, argAddr = 0; asmAddr = Kernel32.VirtualAllocEx(pHandle, 0, asm.Length, MemOpType.Reserve | MemOpType.Commit, MemProtect.ExecuteReadWrite); if (asmAddr == 0) throw new Exception("VirtualAllocEx failed"); if (arguments.Count > 0) { argAddr = Kernel32.VirtualAllocEx(pHandle, 0, argSz, MemOpType.Reserve | MemOpType.Commit, MemProtect.ExecuteReadWrite); if (argAddr == 0) { Kernel32.VirtualFreeEx(pHandle, asmAddr, 0, MemOpType.Release); throw new Exception("VirtualAllocEx failed"); } } try { long cAddr = argAddr; foreach (int idx in arguments.Keys) { WriteByteArray(pHandle, cAddr, argData[idx]); Array.Copy(BitConverter.GetBytes(cAddr), 0, asm, idx, 8); cAddr += argData[idx].Length; } WriteByteArray(pHandle, asmAddr, asm); IntPtr hThread = Kernel32.CreateRemoteThread(pHandle, IntPtr.Zero, 0, asmAddr, IntPtr.Zero, 0, out int threadId); if (hThread != IntPtr.Zero && timeout != 0) Kernel32.WaitForSingleObject(hThread, timeout); } finally { Kernel32.VirtualFreeEx(pHandle, asmAddr, 0, MemOpType.Release); if (argAddr != 0) Kernel32.VirtualFreeEx(pHandle, argAddr, 0, MemOpType.Release); } }
/// <summary> /// Write a generic value to a memory address. /// </summary> /// <typeparam name="T">The type to read.</typeparam> /// <param name="memaddress">The memory address to write to.</param> /// <param name="value">The generic value.</param> /// <returns></returns> public static void WriteGeneric<T>(IntPtr pHandle, long memaddress, T value) where T : struct { byte[] bytes = GenericBitConverter.ToBytes(value); WriteByteArray(pHandle, memaddress, bytes); }
/// <summary> /// Read a generic value from a memory address. /// </summary> /// <typeparam name="T">The type to read.</typeparam> /// <param name="memaddress"></param> /// <returns></returns> public static T ReadGeneric<T>(IntPtr pHandle, long memaddress) where T : struct { int size = GenericBitConverter.GetTypeSize(typeof(T)); byte[] bytes = ReadByteArray(pHandle, memaddress, size); return GenericBitConverter.ToStruct<T>(bytes); }
/// <summary> /// Write a generic value to a memory address. /// </summary> /// <typeparam name="T">The type to read.</typeparam> /// <param name="memaddress">The memory address to write to.</param> /// <param name="value">The generic value.</param> /// <returns></returns> public void WriteGeneric <T>(long memaddress, T value) where T : struct { byte[] bytes = GenericBitConverter.ToBytes(value); WriteByteArray(memaddress, bytes); }
/// <summary> /// Write the value this object points to, if possible. /// </summary> /// <param name="value">The value to write.</param> /// <returns>A bool indicating the success of this operation</returns> public bool SetValue(T value) { byte[] bytes = GenericBitConverter.ToBytes(value); return(SetBytes(bytes)); }
/// <summary> /// Create a DeepPointer from a process name and module name. /// </summary> /// <param name="pname">The name of the process to read from.</param> /// <param name="mname">The name of a specific module in the process.</param> /// <param name="sAddress">The static address to start reading from.</param> /// <param name="offsets">The offsets between each read in memory.</param> public DeepPointer(string pname, string mname, long sAddress, params int[] offsets) : base(pname, mname, sAddress, offsets) { TargetSize = GenericBitConverter.GetTypeSize(typeof(T)); }
/// <summary> /// Create a DeepPointer from an already known handle and module address. /// </summary> /// <param name="pHandle">The handle of the process to read from.</param> /// <param name="mbAddress">The base address of a specific module in the process.</param> /// <param name="sAddress">The static address to start reading from.</param> /// <param name="offsets">The offsets between each read in memory.</param> public DeepPointer(IntPtr pHandle, long mbAddress, long sAddress, params int[] offsets) : base(pHandle, mbAddress, sAddress, offsets) { TargetSize = GenericBitConverter.GetTypeSize(typeof(T)); }