Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

ReadProcessMemory / WriteProcessMemory


  • Please log in to reply
33 replies to this topic
ULTRA
  • Members
  • 19 posts
  • Last active: Mar 11 2012 09:39 PM
  • Joined: 15 Feb 2005
Hi Chris,

I'd like to have the ReadProcessMemory and WriteProcessMemory Functions
from winapi in AHK. The commands should look like this:

ReadProcessMemory, Address, Byte, WinTitle
WriteProcessMemory, Address, Var, WinTitle

ReadProcessMemory should store the numeric value of the byte at "Address" in "WinTitle"'s memory space into "Byte".
WriteProcessMemory should write the value in "Var" to "Address" of "WinTitle"'s memory space.

Both functions should set ErrorLevel to FAIL if there was a problem.

For example we could use them to read the name of the track currently
played by Winamp in a reliable way. Take a look at the following code:

; Get the index of the currently played track from winamp.
; 0x0400 = WM_USER     0x7D = IPC_GETLISTPOS
; Answer is stored in ErrorLevel.
SendMessage, 0x0400, 0, 0x7D, , ahk_class Winamp v1.x

; Error checking - i.e. Winamp is not running
if ErrorLevel = FAIL
{
	Exit
}

; Now tell Winamp to give us a pointer to the string of the track
; whose index we have to provide. The pointer is valid inside winamp's
; memory space.
; 0xD4 = IPC_GETPLAYLISTTITLE
; Answer is again stored in ErrorLevel.
SendMessage, 0x0400, %ErrorLevel%, 0xD4, , ahk_class Winamp v1.x

; Error checking - i.e. Winamp is not running
if ErrorLevel = FAIL
{
	Exit
}

; Store the address in a new var.
lpszTitle = %ErrorLevel%

; Now we have the pointer stored in lpszTitle. To proceed we have to
; use ReadProcessMemory and read starting at the returned address.
; We have to read byte after byte until we encounter a "00" byte (string ends).

; clear the variable that will hold the track's name
teststr = 

Loop
{
	ReadProcessMemory, %lpszTitle%, char, ahk_class Winamp v1.x
	
	; Error checking - i.e. no permission for reading from the process's memory
	if ErrorLevel = FAIL
	{
	  Exit
	}
	
	; now char holds the numeric value of the byte read from the given address
		
	; If the value of the byte read is zero we are at the end of the string.
	; So quit the loop!	
	if char = 0
	{
		break
	}
	
	; Transform the obtained byte's value to a character
	Transform, char, Chr, %char%
	
	; Append the character to our teststr variable that will hold the whole title string
	teststr = %teststr%%char%
	
	; Increment address by one to obtain next byte
	lpszTitle++
}

; Display our track's title
MsgBox, %teststr%

It would be great. This would make AHK more powerful for advanced users!

I think this is no problem for you to implement in AHK. These functions
internally need 4 API calls: OpenProcess, CloseHandle, ReadProcessMemory, WriteProcessMemory :D
In a world without walls and fences who needs windows and gates?

Serenity
  • Members
  • 1271 posts
  • Last active:
  • Joined: 07 Nov 2004
You've given a really detailed and specific example but I am not sure how this can be applied to other things. Would you give some other examples of how this can be used?
"Anything worth doing is worth doing slowly." - Mae West
Posted Image

ULTRA
  • Members
  • 19 posts
  • Last active: Mar 11 2012 09:39 PM
  • Joined: 15 Feb 2005
You could generate score statistics of your favourite game by reading
your score from the game's memory.

You can read everything from any program even if it doesn't give you an
interface to do it. Obtaining information from alien processes has no limits.
In a world without walls and fences who needs windows and gates?

Serenity
  • Members
  • 1271 posts
  • Last active:
  • Joined: 07 Nov 2004
Thanks Ultra, this sounds like it could be really useful and powerful. I'm wondering how you find what to put in- for the example you gave, the memory address was returned in the errorlevel after posting a message IPC_GETPLAYLISTTITLE, a command that sounds specific to Winamp. How would you go about finding similar messages for other applications? Also, it sounds like you could change quite a bit about an application if you could overwrite its memory addresses during run time.
"Anything worth doing is worth doing slowly." - Mae West
Posted Image

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Thanks Ultra. I'll see if this can be added sometime after the next version comes out (unless someone else wants to write the code sooner). It seems fairly simple but my top priority now is getting function calling done so that this next version can be released (hopefully within the next 5 days).

ULTRA
  • Members
  • 19 posts
  • Last active: Mar 11 2012 09:39 PM
  • Joined: 15 Feb 2005

I'm wondering how you find what to put in- for the example you gave, the memory address was returned in the errorlevel after posting a message IPC_GETPLAYLISTTITLE, a command that sounds specific to Winamp.

Yup, its a winamp specific message. It is documented in the winamp sdk.

How would you go about finding similar messages for other applications?

If you know what you are looking for (e.g. you have a string displayed in a
program) then you can search for it in the process's memory and then look
for a pointer to its buffer. Another way is to debug the program in question
with a debugger (such as OllyDbg). There you can easily locate the addresses
where pointers to buffers are stored.

Also, it sounds like you could change quite a bit about an application if you could overwrite its memory addresses during run time.

Yup, everything is possible. You could inject new functions or modify existing ones :)
But all this is very difficult without basic knowledge of ASM.

Thanks Ultra. I'll see if this can be added sometime after the next version comes out.

Great :D

(unless someone else wants to write the code sooner)

Is that a broad hint? :wink:
In a world without walls and fences who needs windows and gates?

ULTRA
  • Members
  • 19 posts
  • Last active: Mar 11 2012 09:39 PM
  • Joined: 15 Feb 2005
Okay, I added my ReadProcessMemory and WriteProcessMemory commands
to the source code of AHK. It works perfectly. I changed the order of the arguments
a bit to match the other AHK commands in their syntax.

It is now like this:

ReadProcessMemory, OutputVar, Address [,  WinTitle, WinText, ExcludeTitle, ExcludeText]
WriteProcessMemory, Byte, Address [,  WinTitle, WinText, ExcludeTitle, ExcludeText]

Both commands also have the ability to use the "Last Found Window" by omitting
the last four parameters (exactly the same as in SendMessage).

Both commands set ErrorLevel to "FAIL" if there was a problem when accessing memory.

The argument "Byte" of WriteProcessMemory can be one character
(unicode or ansi, it doesn't matter) or a numeric value between 0 and 255
(0x00 - 0xFF). If you pass a string longer than 1 characters ErrorLevel will
be set to 1.

I tried my Winamp example above with it. It works perfectly! I only had
to add "AutoTrim, Off", otherwise all spaces I tried to append were deleted.

Ah, Chris, how should I tell you what I changed in your sourcecode?
In a world without walls and fences who needs windows and gates?

compuboy_r
  • Members
  • 68 posts
  • Last active: Oct 29 2005 03:17 PM
  • Joined: 04 May 2004
@ULTRA

Can i have that custom compiled Autohotkey with Read Process/Write Process.

Actually i have made ControlAmp1.4 (in AHK) and had to use a own codded VC++ utlility do certain thigns related to this


Latest version can be found at

http://compuboy.cjb.net (Self Hosted so might be down)

Would like to have this.

Compuboy
Posted Image

ULTRA
  • Members
  • 19 posts
  • Last active: Mar 11 2012 09:39 PM
  • Joined: 15 Feb 2005
k, no problem. Be careful with what you do with the commands. It is no problem
to kill an app by reading/writing memory to/from its memory space.

My compiled version is also based on the old version of AHK so you don't
have the new fancy stuff.

I don't know if it's okay. I have uploaded a zip with only the exe and the
working winamp example in it.

You can download it here.

Syntax is:

ReadProcessMemory, OutputVar, Address [,  WinTitle, WinText, ExcludeTitle, ExcludeText]
WriteProcessMemory, Byte, Address [,  WinTitle, WinText, ExcludeTitle, ExcludeText]

(Just like all the other commands)

Btw, last exam on tuesday 8)
In a world without walls and fences who needs windows and gates?

compuboy_r
  • Members
  • 68 posts
  • Last active: Oct 29 2005 03:17 PM
  • Joined: 04 May 2004
Thanks for the exe but can i get the compiler for the script also


Hey Chris, This is working like cream. Why dont u have it in the Autohotkey itself.


Regards
Posted Image

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Because these functions would be so rarely used (probably by fewer than 1 out of 100 users), it seemed best to wait until the command APICall/DllCall is available. Once that has been added, a function can be created that does the same thing as Read/WriteProcessMemory. This would also improve flexibililty since you would be calling the Windows API directly and could decide how many bytes you want, when you want to close the process handle, etc.

Rajat
  • Members
  • 1904 posts
  • Last active: Jul 17 2015 07:45 AM
  • Joined: 28 Mar 2004

wait until the command APICall/DllCall is available. Once that has been added, a function can be created that does the same thing as Read/WriteProcessMemory.

next major step, eh? (i can hardly wait)... also, using functions for this is a very good idea!

MIA

CleanNews.in : Bite sized latest news headlines from India with zero bloat


ULTRA
  • Members
  • 19 posts
  • Last active: Mar 11 2012 09:39 PM
  • Joined: 15 Feb 2005

Because these functions would be so rarely used (probably by fewer than 1 out of 100 users), it seemed best to wait until the command APICall/DllCall is available. Once that has been added, a function can be created that does the same thing as Read/WriteProcessMemory. This would also improve flexibililty since you would be calling the Windows API directly and could decide how many bytes you want, when you want to close the process handle, etc.


Yes, and I will be the one to code it :D

I had my last exam today and I will definitely start on this one today afternoon :wink:

Edit: here is the sc file for the ahk2exe program. Put the .bin in the directory
where the "Ahk2Exe.exe" is.
In a world without walls and fences who needs windows and gates?

Rajat
  • Members
  • 1904 posts
  • Last active: Jul 17 2015 07:45 AM
  • Joined: 28 Mar 2004

Yes, and I will be the one to code it :D

I had my last exam today and I will definitely start on this one today afternoon :wink:

hey ULTRA, do u mean the memory function or the dll/api call command itself?

MIA

CleanNews.in : Bite sized latest news headlines from India with zero bloat


ULTRA
  • Members
  • 19 posts
  • Last active: Mar 11 2012 09:39 PM
  • Joined: 15 Feb 2005
I mean the dll function calling.
In a world without walls and fences who needs windows and gates?