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

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.