diff --git a/src/CxbxDebugger/Debugger/DebuggerProcess.cs b/src/CxbxDebugger/Debugger/DebuggerProcess.cs index 05df3d4a1..0f0c3983c 100644 --- a/src/CxbxDebugger/Debugger/DebuggerProcess.cs +++ b/src/CxbxDebugger/Debugger/DebuggerProcess.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Runtime.InteropServices; using WinProcesses = VsChromium.Core.Win32.Processes; namespace CxbxDebugger @@ -51,22 +52,87 @@ namespace CxbxDebugger } } - public uint ReadMemory(IntPtr addr) + private byte[] ReadMemoryInternal(IntPtr Address, int Size) { - byte[] buffer = new byte[4]; + byte[] buffer = new byte[Size]; - uint numRead = 0; + int numRead = 0; WinProcesses.NativeMethods.ReadProcessMemory ( Handle, - addr, + Address, buffer, 4, out numRead ); - return BitConverter.ToUInt32(buffer, 0); + // Not handling errors for now + return buffer; } + public T ReadMemory(IntPtr Address) + { + var size = Marshal.SizeOf(typeof(T)); + byte[] Data = ReadMemoryInternal(Address, size); + + object Value = default(T); + + TypeCode TType = Type.GetTypeCode(typeof(T)); + switch (TType) + { + case TypeCode.Byte: + Value = Data[0]; + break; + + case TypeCode.UInt32: + Value = BitConverter.ToUInt32(Data, 0); + break; + + default: + throw new Exception(string.Format("Unhandled type code {0}", TType.ToString())); + } + + return (T)Value; + } + + private void WriteMemoryInternal(IntPtr Address, byte[] Data) + { + int numWritten = 0; + WinProcesses.NativeMethods.WriteProcessMemory + ( + Handle, + Address, + Data, + (uint)Data.Length, + out numWritten + ); + } + + public void WriteMemory(IntPtr Address, T Value) + { + byte[] Data = null; + + object GenericValue = Value; + + TypeCode TType = Type.GetTypeCode(Value.GetType()); + switch (TType) + { + case TypeCode.Byte: + Data = new byte[] { (byte)GenericValue }; + break; + + case TypeCode.UInt32: + Data = BitConverter.GetBytes((uint)GenericValue); + break; + + default: + throw new Exception(string.Format("Unhandled type code {0}", TType.ToString())); + } + + if (Data != null) + { + WriteMemoryInternal(Address, Data); + } + } } } diff --git a/src/CxbxDebugger/Debugger/DebuggerThread.cs b/src/CxbxDebugger/Debugger/DebuggerThread.cs index 3f70bee59..0ea323088 100644 --- a/src/CxbxDebugger/Debugger/DebuggerThread.cs +++ b/src/CxbxDebugger/Debugger/DebuggerThread.cs @@ -50,8 +50,8 @@ namespace CxbxDebugger do { - var ReturnAddr = OwningProcess.ReadMemory(new IntPtr(ebp + 4)); - ebp = OwningProcess.ReadMemory(new IntPtr(ebp)); + var ReturnAddr = OwningProcess.ReadMemory(new IntPtr(ebp + 4)); + ebp = OwningProcess.ReadMemory(new IntPtr(ebp)); if (ebp == 0 || ReturnAddr == ebp) break; diff --git a/src/CxbxDebugger/Win32/Processes/NativeMethods.cs b/src/CxbxDebugger/Win32/Processes/NativeMethods.cs index 5b2e7403d..20052de37 100644 --- a/src/CxbxDebugger/Win32/Processes/NativeMethods.cs +++ b/src/CxbxDebugger/Win32/Processes/NativeMethods.cs @@ -70,8 +70,12 @@ namespace VsChromium.Core.Win32.Processes // x1nix: added [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, - [Out] byte[] buffer, uint size, out uint lpNumberOfBytesRead); + public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] buffer, uint size, out int lpNumberOfBytesRead); + + // x1nix: added + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out int lpNumberOfBytesWritten); [DllImport("ntdll.dll", SetLastError = true)] public static extern int NtQueryInformationProcess(SafeProcessHandle hProcess, ProcessInfoClass pic, ref ProcessBasicInformation pbi, int cb, out int pSize);