static readonly byte[] returnTrue = new byte[] { 0x6A, 0x01, 0x58, 0xC3 }; // push 1 / pop eax / retn static bool WriteBytes(CorProcess process, ulong addr, byte[] data) { if (process == null || addr == 0 || data == null) { return(false); } var hProcess = process.Handle; uint oldProtect; if (!NativeMethods.VirtualProtectEx(hProcess, new IntPtr((long)addr), data.Length, NativeMethods.PAGE_EXECUTE_READWRITE, out oldProtect)) { return(false); } int sizeWritten; try { process.WriteMemory(addr, data, 0, data.Length, out sizeWritten); } finally { NativeMethods.VirtualProtectEx(hProcess, new IntPtr((long)addr), data.Length, oldProtect, out oldProtect); } return(sizeWritten == data.Length); }
/// <summary> /// Writes a new value. Can be called if <see cref="IsGeneric"/> is true /// </summary> /// <param name="data">Data</param> /// <param name="process">Process to use if first method call fails</param> /// <returns></returns> public unsafe int WriteGenericValue(byte[] data, CorProcess process = null) { if (data == null || (uint)data.Length != Size) { return(-1); } var g = obj as ICorDebugGenericValue; if (g == null) { return(-1); } int hr; fixed(byte *p = &data[0]) { // This sometimes fails with CORDBG_E_CLASS_NOT_LOADED (ImmutableArray<T>, debugging VS2017). // If it fails, use process.WriteMemory(). hr = g.SetValue(new IntPtr(p)); if (hr < 0 && process != null) { hr = process.WriteMemory(address, data, 0, data.Length, out var sizeWritten); if (sizeWritten != data.Length && hr >= 0) { hr = -1; } } } return(hr); }