Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate

ReadMemory function


  • Please log in to reply
109 replies to this topic
Drangon
  • Guests
  • Last active:
  • Joined: --


This function should execute at a speed on par with simply looping ReadProcessMemory between OpenProcess and CloseHandle.

; Automatically closes handle when a new (or null) program is indicated
; Otherwise, keeps the process handle open between calls that specify the
; same program. When finished reading memory, call this function with no
; parameters to close the process handle i.e: "Closed := ReadMemory()"

ReadMemory(MADDRESS=0,PROGRAM="")
{
	Static OLDPROC, ProcessHandle
	VarSetCapacity(MVALUE,4,0)
	If PROGRAM != %OLDPROC%
	{
		WinGet, pid, pid, % OLDPROC := PROGRAM
		ProcessHandle := ( ProcessHandle ? 0*(closed:=DllCall("CloseHandle"
		,"UInt",ProcessHandle)) : 0 )+(pid ? DllCall("OpenProcess"
		,"Int",16,"Int",0,"UInt",pid) : 0)
	}
	If (ProcessHandle) && DllCall("ReadProcessMemory","UInt"
	,ProcessHandle,"UInt",MADDRESS,"Str",MVALUE,"UInt",4,"UInt *",0)
	return *(&MVALUE+3)<<24 | *(&MVALUE+2)<<16 | *(&MVALUE+1)<<8 | *(&MVALUE)
	return !ProcessHandle ? "Handle Closed: " closed : "Fail"
}


Helllo VxE, can you pleease tell me why this code block below returns FAIL instead of 10 as it should? I first have open Calculator before running, but is still not working. :(

ReadMemory(MADDRESS=0,PROGRAM="")
{
   Static OLDPROC, ProcessHandle
   VarSetCapacity(MVALUE,4,0)
   If PROGRAM != %OLDPROC%
   {
      WinGet, pid, pid, % OLDPROC := PROGRAM
      ProcessHandle := ( ProcessHandle ? 0*(closed:=DllCall("CloseHandle"
      ,"UInt",ProcessHandle)) : 0 )+(pid ? DllCall("OpenProcess"
      ,"Int",16,"Int",0,"UInt",pid) : 0)
   }
   If (ProcessHandle) && DllCall("ReadProcessMemory","UInt"
   ,ProcessHandle,"UInt",MADDRESS,"Str",MVALUE,"UInt",4,"UInt *",0)
   return *(&MVALUE+3)<<24 | *(&MVALUE+2)<<16 | *(&MVALUE+1)<<8 | *(&MVALUE)
   return !ProcessHandle ? "Handle Closed: " closed : "Fail"
}
WriteMemory(WVALUE,MADDRESS,PROGRAM)
{
winget, pid, PID, %PROGRAM%

ProcessHandle := DllCall("OpenProcess", "int", 2035711, "char", 0, "UInt", PID, "UInt")
DllCall("WriteProcessMemory", "UInt", ProcessHandle, "UInt", MADDRESS, "Uint*", WVALUE, 

"Uint", 4, "Uint *", 0)

DllCall("CloseHandle", "int", ProcessHandle)
return
}

WriteMemory(10, 0x41000C,"Calc")

sleep, 1000

value:=ReadMemory(0x41000C,"Calc")

msgbox, Memory address 0x41000C = %value%


What am I possibly doing wrong here?:)

VxE
  • Moderators
  • 3622 posts
  • Last active: Dec 24 2015 02:21 AM
  • Joined: 07 Oct 2006

What am I possibly doing wrong here?:)

You're probably trying to access a memory address that lies outside the process's memory or is invalid for some other reason.

Where did you get the address 0x41000C ?

Deicer
  • Members
  • 43 posts
  • Last active: Aug 18 2011 12:11 PM
  • Joined: 22 Dec 2006
Anybody?

When I use ReadMemory on a adress value eg. HELLO it returns 1919595761 (Wrong)

VxE
  • Moderators
  • 3622 posts
  • Last active: Dec 24 2015 02:21 AM
  • Joined: 07 Oct 2006

Anybody?

When I use ReadMemory on a adress value eg. HELLO it returns 1919595761 (Wrong)

MyString = Hello World!
Loop % StrLen(MyString)//4
	nums .= (A_Index=1 ? "" : "`n")
		. (*(&MyString+A_Index*4-4) << 24)
		+ (*(&MyString+A_Index*4-3) << 16)
		+ (*(&MyString+A_Index*4-2) << 8)
		+ *(&MyString+A_Index*4-1)
msgbox %nums%
All strings are stored as numbers in memory. When you explicitly read a memory address, you have to know whether you need to convert the numbers into a string. BTW: this function (as-is) is not designed for string retrieval.

Drangon
  • Guests
  • Last active:
  • Joined: --

What am I possibly doing wrong here?:)

You're probably trying to access a memory address that lies outside the process's memory or is invalid for some other reason.

Where did you get the address 0x41000C ?


VxE, I was using 0x41000C from earlier post. Can you just show something which works? :)

Deicer
  • Members
  • 43 posts
  • Last active: Aug 18 2011 12:11 PM
  • Joined: 22 Dec 2006
Thanks !

Sephiroth2906
  • Members
  • 86 posts
  • Last active: Dec 31 2012 04:28 PM
  • Joined: 28 Apr 2007
I am sure this is a noob question, but I do not have a lib folder in my autohotkey folder, so, of course, I cannot put the scripts there so they can be used. Why is that?

Drangon
  • Guests
  • Last active:
  • Joined: --
I re-read my post, and probably didn't provide enough information, sorry out there! :)

Basically what I was hoping for is to secretly place data in a empty memory location in my running AHK application (READ IN/READ OUT). How would I best go about achieving this feat? :D I appreciate any assistance...

evan
  • Guests
  • Last active:
  • Joined: --
library folder, u have to create one by urself, check help file for library

//
i am not sure why u would prefer using memory storing than just using a variable in ur AHK program
but all compiled AHK exe file 0x00000001 address seems free
u can memory write there

Drangon
  • Guests
  • Last active:
  • Joined: --

library folder, u have to create one by urself, check help file for library

//
i am not sure why u would prefer using memory storing than just using a variable in ur AHK program
but all compiled AHK exe file 0x00000001 address seems free
u can memory write there


Hi evan, here is my procedure, maybe you can see why this is not working;

I created a executable, try.exe (ahk executable script)

; then i run this code against it;;; the PID for try.exe does appear, so it seems to notice try.exe :)


ReadMemory(MADDRESS=0,PROGRAM="")
{
   Static OLDPROC, ProcessHandle
   VarSetCapacity(MVALUE,4,0)
   If PROGRAM != %OLDPROC%
   {
      WinGet, pid, pid, % OLDPROC := PROGRAM
      ProcessHandle := ( ProcessHandle ? 0*(closed:=DllCall("CloseHandle"
      ,"UInt",ProcessHandle)) : 0 )+(pid ? DllCall("OpenProcess"
      ,"Int",16,"Int",0,"UInt",pid) : 0)
   }
   If (ProcessHandle) && DllCall("ReadProcessMemory","UInt"
   ,ProcessHandle,"UInt",MADDRESS,"Str",MVALUE,"UInt",4,"UInt *",0)
   return *(&MVALUE+3)<<24 | *(&MVALUE+2)<<16 | *(&MVALUE+1)<<8 | *(&MVALUE)
   return !ProcessHandle ? "Handle Closed: " closed : "Fail"
}
WriteMemory(WVALUE,MADDRESS,PROGRAM)
{
winget, pid, PID, %PROGRAM%

MsgBox, %pid%

ProcessHandle := DllCall("OpenProcess", "int", 2035711, "char", 0, "UInt", PID, "UInt")
DllCall("WriteProcessMemory", "UInt", ProcessHandle, "UInt", MADDRESS, "Uint*", WVALUE,"Uint", 4, "Uint *", 0)

DllCall("CloseHandle", "int", ProcessHandle)
return
}

WriteMemory(10, 0x00000001,"try")

sleep, 1000

value:=ReadMemory(0x00000001,"try")

msgbox, Memory address = %value%



... but when I run this, I get a FAIL. I am however running 64-bit windows, maybe this is the issue? :? Thank you for checking if you can, or can diagnose my woes thanks

David Andersen
  • Members
  • 140 posts
  • Last active: Jun 28 2011 04:54 PM
  • Joined: 15 Jul 2005
Deicer!

The following is a working example on how to retrieve a string from memory. My problem is how to retrieve more than the 10 chars, which seems to be the maximum (try setting NUMBER_OF_CHARS_TO_RETRIEVE = 1000) and notice that only 10 chars are retrieved. I need to retrieve about one megabyte of data in order to search for a string. I have found another post regarding this, though there were no solutions. Any help is appreciated. I attempted to incrementally retrieve one megabyte, though it is very inefficient and took more than two seconds (this was to retrieve the same 10 chars 100000 times, not searching or anything), which is too much for me.

DetectHiddenWindows, On
SetTitleMatchMode, Slow
SetBatchLines, -1 

#x::
{
	address = 0x4676B99
	value:=ReadMemory(address,"Window Title", 10) 
}

ReadMemory(MADDRESS,PROGRAM, NUMBER_OF_CHARS_TO_RETRIEVE) 
{ 
	SetFormat, integer, hex
	winget, pid, PID, %PROGRAM% 
	global  ProcessHandle := DllCall("OpenProcess", "Int", 24, "Char", 0, "UInt", pid, "UInt") 

	VarSetCapacity(MVALUE,NUMBER_OF_CHARS_TO_RETRIEVE) 
	DllCall("ReadProcessMemory","UInt",ProcessHandle,"UInt",MADDRESS,"Str",MVALUE,"UInt",NUMBER_OF_CHARS_TO_RETRIEVE,"UInt *",0) 
	msgbox, "%mvalue%"
	return, result  
}

#2::reload

Any help is appreciated.

  • Guests
  • Last active:
  • Joined: --
@David Andersen

I'd try a program like this rather than reinvent the wheel :D

<!-- m -->http://www.codefromt...s.org/poke.aspx<!-- m -->

David Andersen
  • Members
  • 140 posts
  • Last active: Jun 28 2011 04:54 PM
  • Joined: 15 Jul 2005
Hi Guest,

Thanks for the link. There are however, two issues with the Poke program.
1. It only has ha graphical user interface, which means that I cannot operate it from Autohotkey in the background without disturbing the user
2. One cannot search for a string, only Word and DWord values.

Thanks!

  • Guests
  • Last active:
  • Joined: --

One cannot search for a string, only Word and DWord values.


Maybe this will give you an idea of how your strings are stored in memory:
a = This is a very long string that takes up some memory. The quick brown fox jumps over the lazy dog. The sky isn't really blue.

Loop, % StrLen(a)
	FileAppend, % &a+(A_Index-1) . A_Tab . Chr(*(&a+(A_Index-1))) . "`n", test.txt


David Andersen
  • Members
  • 140 posts
  • Last active: Jun 28 2011 04:54 PM
  • Joined: 15 Jul 2005
Hi Guest,

A funny example you gave me there. Kind of interesting, but not useful to read string from the memory of other running processes.

Regards,

David