Non-local App Memory Manipulation

BlitzMax Forums/BlitzMax Programming/Non-local App Memory Manipulation

Zenn Lee(Posted 2007) [#1]
I've starting this topic earlier without any success and have decided to respawn it with a clearer question, better stated question. I hate to bug you guys, but there seems to have been many topics addressing this very questions without really any answers. It seem that there have been may people interested, especially me:), and it would be great to get it answered.

My questions is, is there a way to point to variables outside of your blitzmax application. If so, how would you go about doing that?

Let’s say you wrote a program that created a spot in memory to place an integer, let's say the integer’s value was 1521. You ran that program and from another application you wanted to change that integer to 1522, how would you do that.

You would have to loop through your memory until you found the value of 1521, right. Then you would have to place 1522 in that memory location. How would this program work?

Thanks for all this help,
Hopefully somebody knows how to do this:)


ziggy(Posted 2007) [#2]
This is not possible. On windows is a memory address violation.


GW(Posted 2007) [#3]
It is possible to specify a 'global' memory space and have it read and written to from separate applications using a dll.


ninjarat(Posted 2007) [#4]
If you want to communicate data between programs in memory, you can set up a pipe, although that's said to be tricky, and I don't know how. Anyone?


ziggy(Posted 2007) [#5]
Using pipes is the best choice, take a look to the standardout and standardin streaming, and the TProcess class. But keep in mind that using pipes will force a sort of 'syncronization' as the data read and write is performed on separate threads, but the 'shared' buffer is ussually 4 Kbytes long.

Each instance of a running application has its own private memory area, and when an application uses an external DLL, this DLL uses the same private memory area. If there's any way to 'break' this, it will be considered by the OS a memory access violation. So, even if it is possible, I would not recomend it. Not to talk about all the possible threading problems on uncontrolled 'shared' data access...


Koriolis(Posted 2007) [#6]
That's not totally true Ziggy. Regarding DLLs, this is only the standard behaviour, but not the only one possible.
GW was totally right, you can write a DLL that contains a special *shared* part.
Every program loading this DLL, when accessing to this specific memory section, will indeed access the same shared memory.
http://support.microsoft.com/kb/100634

It is also possible to use file mappings to implement a shared block of memory (CreateFileMapping with hFile = INVALID_HANDLE_VALUE):

http://msdn2.microsoft.com/EN-US/library/aa366537.aspx
http://msdn2.microsoft.com/en-us/library/ms686958.aspx


These two solutions are very common, but obviously they are windows specific.


ziggy(Posted 2007) [#7]
@Koriolis: I knew that but i don't think (I can be wrong) it is compatible with managed code. And I think that shared blocks of memory on filemapping can only be shared by the creator process and child processes. But I'm not sure.


xlsior(Posted 2007) [#8]
It is possible to specify a 'global' memory space and have it read and written to from separate applications using a dll.


Or without a DLL -- there's some blitzMax code here to deal with shared memory, written by Budman:

' Simple program to demonstrate sharing memory between process
' compile as console program and run one or more times the first run sets the 
' shared memory
' additonal runs read it

SuperStrict
Extern "Win32"
    Function CloseHandle:Int(Handle:Int)
	Function MapViewOfFile:Byte Ptr(hFileMappingObject: Int,dwDesiredAccess: Int, dwFileOffsetHigh:Int, dwFileOffsetLow:Int, dwNumberOfBytesToMap:Int)
	Function UnmapViewOfFile:Int(lpBaseAddress: Byte Ptr)
	Function CreateFileMappingA:Int(hFile: Int, lpFileMappingAttributes: Byte Ptr,flProtect:Int, dwMaximumSizeHigh:Int, dwMaximumSizeLow:Int, lpName$z)
	Function GetLastError:Int()
End Extern

Const PAGE_READWRITE : Int=4
Const FILE_MAP_WRITE : Int=2

Type TSharedMemory 
	Field _Handle : Int
	Field _Name   : String
	Field _Size   : Int
    Field _Owner  : Int
	Field _Data   : Byte Ptr

   
	Method Delete()
		Close
	End Method
	Method Open:Int(Name: String, Size: Int)
		Close()
   		_Name = Name
    	_Size = Size
       ' CreateFileMapping, when called with $FFFFFFFF For the hanlde value, creates a region of shared memory }
   		_Handle = CreateFileMappingA($FFFFFFFF, Null, PAGE_READWRITE, 0,_Size,_Name)
    	If _Handle = 0 Then Return False
        _Owner = GetLastError() = 0
       ' We still need To map a pointer To the handle of the shared memory region 
        _Data= MapViewOfFile(_Handle, FILE_MAP_WRITE, 0, 0, _Size)
    	If Not _Data
			Close
			Return False
		End If
		Return True
	End Method 
	Method Close()
  		If _Data
	    	UnmapViewOfFile(_Data);
			_Data=Null
		End If
		If _Handle 
			CloseHandle(_Handle)
			_Handle=0
		End If 		
	End Method
End Type

Print "Test Share Mem"
Local mem:TSharedMemory = New TSharedMemory 
mem.Open("TESTMEM",30)
If mem._Owner
	Print "Setting Title"
	MemClear mem._Data,30
	Local title:String="Budman Rocks"
	Local pTitle:Byte Ptr=title.toCString()
	MemCopy mem._Data,pTitle,title.length+1
	MemFree pTitle
Else
	Print "Getting Title"
	Local title : String = string.FromCString(mem._Data)		
	Print "The Title is "+title
End If
Input
mem.Close


(See this thread for the full story: http://www.blitzbasic.com/Community/posts.php?topic=65705 )


Who was John Galt?(Posted 2007) [#9]
An alternative is SKN[3]AC's code using OpenProcessMemory() <Windows only> that's in the code archives. It should be quite easy to write a simple game trainer with this (if that's what you are trying to do). Generally you search for a memory location by matching the value as you say, but you may well get more than one 'hit' so you modify the value in the target program (eg by losing a life) and seeing which of the original hits contains the new value. I'm starting to sound like a parrot now.. this question has come up a bunch of times... but he used the code to make a mod for Pro Evolution Soccer IV to allow people to play over the internet.


Zenn Lee(Posted 2007) [#10]
You guys are excellent, thanks!


ziggy(Posted 2007) [#11]
Thanks for the code samples :D