ReadProcessMemory is always false

Hello,

Long story shot, I cannot get RPM to work. It never works. Heres my code below.

#region Token

[StructLayout(LayoutKind.Sequential)]
public struct LUID
{
public int LowPart;
public int HighPart;
}

[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_PRIVILEGES
{
public LUID Luid;
public int Attributes;
public int PrivilegeCount;
}

[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int OpenProcessToken( int ProcessHandle,
int DesiredAccess,
ref int tokenhandle
);

[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int LookupPrivilegeValue( string lpsystemname,
string lpname,
[MarshalAs(UnmanagedType.Struct)] ref LUID lpLuid
);

[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int AdjustTokenPrivileges( int tokenhandle, int disableprivs,
[MarshalAs(UnmanagedType.Struct)]ref TOKEN_PRIVILEGES Newstate,
int bufferlength,
int PreivousState,
int Returnlength
);

public const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
public const int TOKEN_QUERY = 0x00000008;
public const int SE_PRIVILEGE_ENABLED = 0x00000002;
public const string SE_RESTORE_NAME = "SeRestorePrivilege";

public bool EnablePrivilege( int intProcessHandle )
{
int intReturnValue = 0;
int intToken = 0;

TOKEN_PRIVILEGES tpMain = new TOKEN_PRIVILEGES();
LUID ldNew = new LUID();

intReturnValue = OpenProcessToken(intProcessHandle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref intToken);
if ( intReturnValue > 0 )
{
intReturnValue = LookupPrivilegeValue(null, SE_RESTORE_NAME, ref ldNew);
if ( intReturnValue > 0 )
{
tpMain.PrivilegeCount = 1;
tpMain.Attributes = SE_PRIVILEGE_ENABLED;
tpMain.Luid = ldNew;

intReturnValue = AdjustTokenPrivileges(intToken, 0, ref tpMain, 1024, 0, 0);

return ( intReturnValue > 0 );
}
else
{
return ( intReturnValue > 0 );
}
}
else
{
return ( intReturnValue > 0 );
}
}

#endregion

#region Memory
public const uint PROCESS_VM_READ = 0x0010;

[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess( UInt32 dwDesiredAccess,
bool bInheritHandle,
UInt32 dwProcessId
);

[DllImport("kernel32.dll")]
public static extern Int32 CloseHandle( IntPtr hObject );

[DllImport("kernel32.dll")]
static extern bool ReadProcessMemory( IntPtr hProcess,
IntPtr lpBaseAddress,
IntPtr lpBuffer,
int dwSize,
IntPtr lpNumberOfBytesRead
);
#endregion

#region Diablo
private const int GLOBAL_PLAYER = 0x6FBCC1E0;

public struct player_stats
{
public ushort unk;
public ushort statnum;
public uint statval;
}

public struct player_data
{
public unsafe fixed uint dw[9]; //+0x00
public unsafe player_stats* stats; //+0x24
}

public struct player
{
public unsafe fixed uint dw[23]; //+0x00
public unsafe player_data* data; //+0x5c
}
#endregion

private void doall()
{
Process[] pD2 = Process.GetProcessesByName("Game");

if ( pD2.Length == 0 )
{
Console.WriteLine("no d2 found");
return;
}

int intMyHandle = Process.GetCurrentProcess().Handle.ToInt32();
int intD2Handle = pD2[0].Handle.ToInt32();

if ( EnablePrivilege(intMyHandle) == false )
{
Console.WriteLine("token failed");
return;
}

IntPtr hwndOpen = OpenProcess(PROCESS_VM_READ, false, (uint)pD2[0].Id);

if ( hwndOpen == IntPtr.Zero )
{
Console.WriteLine("openprocess failed");
return;
}

IntPtr lpBuffer = IntPtr.Zero;
IntPtr bytesRead = IntPtr.Zero;

if ( ReadProcessMemory(pD2[0].Handle, (IntPtr)GLOBAL_PLAYER, lpBuffer, sizeof(int), bytesRead) )
{
Console.WriteLine("read went okay...");
}


int intClose = CloseHandle(hwndOpen);

if ( intClose == 0 )
{
Console.WriteLine("closehandle failed");
return;
}


Console.WriteLine("end");
}

#endregion

I've made the problem lines red. And yes, I've tried replacing "pD2[0].Handle" with "hwndOpen" and it still fails. It gives no errors. I know it's failing becuase its not writing to the console, and the buffer is always empty. Anyone have any ideas




Answer this question

ReadProcessMemory is always false

  • woodsy99

    Thanks for the reply.

    GetLastWin32Error returned zero. I ended up rewriting everything, and even wrote my own classes for doing tokens, (With the right structs this time ) and reading the memory, and now it works perfectly.



  • visualbasicming

    You should add SetLastError=true to the DllImport attribute and then check Marshal.LastWin32Error after the call to find out why it fails.

    The first thing I noticed is that your TOKEN_PRIVILEGES struct is incorrect. See http://www.pinvoke.net/default.aspx/Structures/TOKEN_PRIVILEGES.html

    Using a hardcoded memory address is bound to fail eventually.



  • ReadProcessMemory is always false