• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 469
  • Last Modified:

ReadProcessMemory Succeeds, WriteProcessMemory Fails

I have a small problem, I'm developing a trainer(1st one) just for kicks for Minesweeper. All i'm trying to do is to change the mine display to a number different then its current display. When I read the process at that address I get 10, which is the display for the mines at the beginner level. But when i write to the process it fails although all parameters are accounted for and should work. Here's the source for you all.

' Needs the game "Minesweeper" open
' Needs two command buttons one named cmdPoke, the
' other cmd refresh
' Needs a listbox named lstHistory
' The form needs to be named frmMain
'Reserved for Constants
Private Const PROCESS_ALL_ACCESS = &H1F0FFF
'Reserved for Declarations
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVallpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal Classname As String, ByVal WindowName As String) As Long
'Reserved for Dim's
Dim uHwnd As Long
Dim uPID As Long
Dim uProcID As Long
Dim uName As String
Dim uNull As String

Private Sub cmdPoke_Click()
Dim Status
Call Peek(uPID, &H1005194)
Call Poke(uPID, &H1005194, &H99)
End Sub

Private Sub cmdRefresh_Click()
lstHistory.Clear
Call Connectto_Process
End Sub

Private Sub Poke(PokeHandle As Long, PokeAddress As Long, PokeValue As Variant)
Dim Status As Long
Status = WriteProcessMemory(PokeHandle, PokeAddress, PokeValue, Len(PokeValue), 0&)
If Status <> 0 Then
lstHistory.AddItem "Poking succeeded."
Else
lstHistory.AddItem "Poking failed."
End If
End Sub

Private Sub Peek(PeekHandle As Long, PeekAddress As Long)
Dim Status As Integer
Dim Buffer As Long
Status = ReadProcessMemory(PeekHandle, PeekAddress, Buffer, 2, 0&)
If Status <> 0 Then
lstHistory.AddItem "Peeking succeeded."
lstHistory.AddItem "Peeked Value: " & Buffer
Else
lstHistory.AddItem "Peeking failed."
End If
End Sub

Private Sub Connectto_Process()
uName = "MineSweeper"
uHwnd = FindWindow(vbNullString, uName)
If uHwnd <> 0 Then
lstHistory.AddItem "Found Program: " & uName
lstHistory.AddItem "Handle Located."
lstHistory.AddItem "Handle: " & uHwnd
GetWindowThreadProcessId uHwnd, uProcID
uPID = OpenProcess(PROCESS_ALL_ACCESS, False, uProcID)
If uPID <> 0 Then
lstHistory.AddItem "ProcessID Located."
lstHistory.AddItem "ProcessID: " & uProcID
Else
lstHistory.AddItem "ProcessID Not Found."
End If
Else
lstHistory.AddItem "Error Locating: " & uName
End If
End Sub

Private Sub Form_Load()
Call Connectto_Process
End Sub
0
neoaikon
Asked:
neoaikon
  • 2
1 Solution
 
grayeCommented:
It'd be helpful to know what OS...

Generally speaking it's considered a "no-no" to allow one program to alter another programs virtual memory.   This has become an even bigger deal with WinXP SP2, where writing to the code space is blocked.

So, unless you're willing to write a program/service in the Kernel mode (ring 0) I think this approach isn't gonna work.
0
 
neoaikonAuthor Commented:
I'm running XP with no service packs.
0
 
neoaikonAuthor Commented:
I managed to get it to work. XP has 2 functions written specically for the purpose of poking addresses. they are

Private Declare Function WriteString Lib "kernel32" Alias "WriteProcessMemory" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, ByVal lpNumberOfBytesWritten As Long) As Long

Private Declare Function WriteValue Lib "kernel32" Alias "WriteProcessMemory" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, ByVal lpNumberOfBytesWritten As Long) As Long

They allowed me to edit the value of mines in minesweeper and the score in solitare and spider solitare
0
 
IvanCroatiaCommented:
You can try to write a simple debugger-like  application. You would use CreateProcess API for this purpose. Then you will have all the rights for reading and writing the process's memory.
0

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now