Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions STROOP.Core/GameMemoryAccess/DolphinProcessIO.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Diagnostics;
using STROOP.Win32;
using System.Diagnostics;
using System.Runtime.InteropServices;
using static STROOP.Core.Kernal32NativeMethods;
using Windows.Win32.Foundation;
using Windows.Win32.System.ProcessStatus;

namespace STROOP.Core.GameMemoryAccess;

Expand All @@ -13,14 +15,13 @@ public DolphinProcessIO(Process process, Emulator emulator)

protected override void CalculateOffset()
{
MemoryBasicInformation info;
IntPtr infoSize = (IntPtr)Marshal.SizeOf(typeof(MemoryBasicInformation));
uint setInfoSize = (uint)Marshal.SizeOf(typeof(PsapiWorkingSetExInformation));
VirtualQueryEx.MemoryBasicInformation info;
IntPtr infoSize = (IntPtr)Marshal.SizeOf(typeof(VirtualQueryEx.MemoryBasicInformation));

_baseOffset = (UIntPtr)0;
bool mem1Found = false;
for (IntPtr p = new IntPtr();
VQueryEx(_processHandle, p, out info, infoSize) == infoSize;
VirtualQueryEx.Invoke(_processHandle, p, out info, infoSize) == infoSize;
p = (IntPtr)(p.ToInt64() + info.RegionSize.ToInt64()))
{
if (mem1Found)
Expand All @@ -37,17 +38,15 @@ protected override void CalculateOffset()
continue;
}

if (info.RegionSize == (IntPtr)0x2000000 && info.Type == MemoryType.MEM_MAPPED)
if (info.RegionSize == (IntPtr)0x2000000 && info.Type == VirtualQueryEx.MemoryType.MEM_MAPPED)
{
// Here, it's likely the right page, but it can happen that multiple pages with these criteria
// exists and have nothing to do with the emulated memory. Only the right page has valid
// working set information so an additional check is required that it is backed by physical
// memory.
PsapiWorkingSetExInformation wsInfo;
wsInfo.VirtualAddress = (IntPtr)info.BaseAddress.ToUInt64();
if (QWorkingSetEx(_processHandle, out wsInfo, setInfoSize))
if (NativeMethodWrappers.QueryWorkingSetEx((HANDLE)_processHandle, info.BaseAddress, out PSAPI_WORKING_SET_EX_INFORMATION wsInfo))
{
if ((wsInfo.VirtualAttributes & 0x01) != 0)
if ((wsInfo.VirtualAttributes.Flags & 0x01) != 0)
{
_baseOffset = info.BaseAddress;
mem1Found = true;
Expand Down
10 changes: 2 additions & 8 deletions STROOP.Core/GameMemoryAccess/SigScanSharp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
*/

using System.Diagnostics;
using System.Runtime.InteropServices;
using STROOP.Win32;

namespace STROOP.Core.GameMemoryAccess;

Expand All @@ -52,7 +52,7 @@ public bool SelectModule(ProcessModule targetModule)
g_dictStringPatterns.Clear();
try
{
return Win32.ReadProcessMemory(g_hProcess, g_lpModuleBase, g_arrModuleBuffer, (IntPtr)targetModule.ModuleMemorySize);
return NativeMethodWrappers.ReadProcessMemory(g_hProcess, (UIntPtr)g_lpModuleBase, g_arrModuleBuffer);
}
catch (AccessViolationException)
{
Expand Down Expand Up @@ -112,10 +112,4 @@ private byte[] ParsePatternString(string szPattern)

return patternbytes.ToArray();
}

private static class Win32
{
[DllImport("kernel32.dll")]
public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, IntPtr dwSize, IntPtr lpNumberOfBytesRead = default(IntPtr));
}
}
49 changes: 25 additions & 24 deletions STROOP.Core/GameMemoryAccess/WindowsProcessIO.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
using System.ComponentModel;
using STROOP.Win32;
using System.ComponentModel;
using System.Diagnostics;
using static STROOP.Core.Kernal32NativeMethods;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.System.Threading;
using static STROOP.Core.ProcessHelper;

namespace STROOP.Core.GameMemoryAccess;

Expand Down Expand Up @@ -29,16 +33,20 @@ public WindowsProcessRamIO(Process process, Emulator emulator) : base()

_process.EnableRaisingEvents = true;

ProcessAccess accessFlags = ProcessAccess.PROCESS_QUERY_LIMITED_INFORMATION | ProcessAccess.SUSPEND_RESUME
| ProcessAccess.VM_OPERATION | ProcessAccess.VM_READ | ProcessAccess.VM_WRITE;
_processHandle = ProcessGetHandleFromId(accessFlags, false, _process.Id);
var accessFlags = PROCESS_ACCESS_RIGHTS.PROCESS_QUERY_LIMITED_INFORMATION
| PROCESS_ACCESS_RIGHTS.PROCESS_SUSPEND_RESUME
| PROCESS_ACCESS_RIGHTS.PROCESS_VM_OPERATION
| PROCESS_ACCESS_RIGHTS.PROCESS_VM_READ
| PROCESS_ACCESS_RIGHTS.PROCESS_VM_WRITE;

_processHandle = PInvoke.OpenProcess(accessFlags, false, (uint)_process.Id);
try
{
CalculateOffset();
}
catch (Exception e)
{
CloseProcess(_processHandle);
PInvoke.CloseHandle((HANDLE)_processHandle);
throw;
}

Expand All @@ -52,16 +60,10 @@ private void _process_Exited(object sender, EventArgs e)
}

protected override bool ReadFunc(UIntPtr address, byte[] buffer)
{
int numOfBytes = 0;
return ProcessReadMemory(_processHandle, address, buffer, (IntPtr)buffer.Length, ref numOfBytes);
}
=> NativeMethodWrappers.ReadProcessMemory(_processHandle, address, buffer);

protected override bool WriteFunc(UIntPtr address, byte[] buffer)
{
int numOfBytes = 0;
return ProcessWriteMemory(_processHandle, address, buffer, (IntPtr)buffer.Length, ref numOfBytes);
}
=> NativeMethodWrappers.WriteProcessMemory(_processHandle, address, buffer);

public override byte[] ReadAllMemory()
{
Expand All @@ -71,8 +73,8 @@ public override byte[] ReadAllMemory()

for (uint address = 0; true; address++)
{
bool success = ProcessReadMemory(_processHandle, (UIntPtr)address, buffer, (IntPtr)buffer.Length, ref numBytes);
if (!success) break;
if (!NativeMethodWrappers.ReadProcessMemory(_processHandle, address, buffer))
break;
output.Add(buffer[0]);
}

Expand All @@ -91,38 +93,37 @@ private bool CompareBytes(byte[] a, byte[] b)
// see https://msdn.microsoft.com/en-us/library/windows/desktop/ms684139%28v=vs.85%29.aspx
public static bool Is64Bit(Process process)
=> Environment.Is64BitOperatingSystem
&& IsWow64Process(process.Handle, out bool isWow64)
&& PInvoke.IsWow64Process(process.SafeHandle, out var isWow64)
? !isWow64
: throw new Win32Exception();

protected virtual void CalculateOffset()
{
// Find CORE_RDRAM export from mupen if present
Win32SymbolInfo symbol = Win32SymbolInfo.Create();
if (SymInitialize(_process.Handle, null, true))
if (PInvoke.SymInitialize(_process.SafeHandle, null, true))
{
try
{
if (SymFromName(_process.Handle, "CORE_RDRAM", ref symbol))
if (NativeMethodWrappers.GetSymbolAddress(_process.SafeHandle, "CORE_RDRAM", out var address))
{
bool is64Bit = Is64Bit(_process);
byte[]? buffer = new byte[is64Bit ? 8 : 4];
ReadAbsolute((UIntPtr)symbol.Address, buffer, EndiannessType.Little);
ReadAbsolute((UIntPtr)address, buffer, EndiannessType.Little);
_baseOffset = (UIntPtr)(is64Bit ? BitConverter.ToUInt64(buffer, 0) : (ulong)BitConverter.ToUInt32(buffer, 0));
return;
}
}
finally
{
if (!SymCleanup(_process.Handle))
if (!PInvoke.SymCleanup(_process.SafeHandle))
throw new Win32Exception();
}
}
else
{
// documentation doesn't say what to do when SymInitialize returns false, so just call this and don't care for its result for good (or bad) measure :shrug:
// https://learn.microsoft.com/en-us/windows/win32/api/dbghelp/nf-dbghelp-syminitialize
SymCleanup(_process.Handle);
PInvoke.SymCleanup(_process.SafeHandle);
}

// Find DLL offset if needed
Expand Down Expand Up @@ -243,7 +244,7 @@ protected virtual void Dispose(bool disposing)
}

// Close old process
CloseProcess(_processHandle);
PInvoke.CloseHandle((HANDLE)_processHandle);

disposedValue = true;
}
Expand Down
188 changes: 0 additions & 188 deletions STROOP.Core/Kernal32NativeMethods.cs

This file was deleted.

Loading