Cannot Read Memory from Base Address + Offset

Ask gaming related questions (AHK v1.1 and older)
SnowPickle
Posts: 4
Joined: 10 Nov 2014, 14:51

Cannot Read Memory from Base Address + Offset

Post by SnowPickle » 13 Nov 2014, 01:45

Hi All,

I am just learning so trying to read the statistic of games played from Solitaire.
I have taken some functions from the forums here. GetProcessBaseAddress and ReadMemory.

I have run a pointer scan in CE to find my Base address and offset. If I read memory with an input address this works. However this is dynamic so ultimately I am doing this for testing and want to calculate this based on the base and offset assuming my understanding is correct and this is how things should be done.

Code: Select all

; Return values:
;   Null        The process's window couldn't be found.
;   0           The GetWindowLong or GetWindowLongPtr call failed.
;   Non-Zero    The base address of the process (success).

getProcessBaseAddress(WindowTitle, windowMatchMode := "3")    ;WindowTitle can be anything ahk_exe ahk_class etc
{
    if (windowMatchMode && A_TitleMatchMode != windowMatchMode)
    {
        mode := A_TitleMatchMode ; This is a string and will not contain the 0x prefix
        StringReplace, windowMatchMode, windowMatchMode, 0x ; remove hex prefix as SetTitleMatchMode will throw a run time error. This will occur if integer mode is set to hex and matchmode param is passed as an number not a string.
        SetTitleMatchMode, %windowMatchMode%    ;mode 3 is an exact match
    }
    WinGet, hWnd, ID, %WindowTitle%
    if mode
        SetTitleMatchMode, %mode%    ; In case executed in autoexec
    if !hWnd
        return ; return blank failed to find window
    else return DllCall( A_PtrSize = 4
                        	? "GetWindowLong"
                        	: "GetWindowLongPtr"
                        , "Ptr", hWnd
                        , "Int", -6
                        , "Int64") ; Use Int64 to prevent negative overflow when AHK is 32 bit and target process is 64bit
     ; If DLL call fails, returned value will = 0
}	

ReadMemory(MADDRESS,PROGRAM)
{
winget, pid, PID, %PROGRAM%

VarSetCapacity(MVALUE,4,0)
ProcessHandle := DllCall("OpenProcess", "Int", 24, "Char", 0, "UInt", pid, "UInt")
;DllCall("ReadProcessMemory","UInt",ProcessHandle,"UInt",MADDRESS,"Str",MVALUE,"UInt",4,"UInt *",0)
DllCall("ReadProcessMemory", "UInt", ProcessHandle, "Ptr", MADDRESS, "Ptr", &MVALUE, "Uint",4)
Loop 4
result += *(&MVALUE + A_Index-1) << 8*(A_Index-1)

return, result
}

Base := getProcessBaseAddress("ahk_exe Solitaire.exe")
msgbox, %Base%

o_stat := 0x000BB0E8 + 68 + 428 + 7bc
msgbox, %o_stat%

StatAdd := Base + o_stat
msgbox, %statadd%

; Base returning 4293066752
; offset 0x000BB0E8
; CE Pointed Result "solitaire.exe"+000BB0E8

; dynamic address for this instance 0x002D5CDC
;->002c8990 68 428 7bc

Mem := ReadMemory(0x002D5CDC, "ahk_exe Solitaire.exe")
msgbox, %mem%

Mem := ReadMemory(StatAdd, "ahk_exe Solitaire.exe")
msgbox, %mem%
Cheat Engine Shows me the following:
7bc -> 002D5520+7BC = 002D5CDC
428 -> 00353770 + 428 = 002D5520
68 -> 002C8990 + 68 = 00353770
"Solitaire.exe"+000BB0E8 = 002C8990

Thank you in advance for any help.
-SnowPickle

RHCP
Posts: 202
Joined: 30 Sep 2013, 10:59

Re: Cannot Read Memory from Base Address + Offset

Post by RHCP » 13 Nov 2014, 03:56

It's a pointer, so you can't just add the offsets. You need to read the stored value (memory address) at each level of the pointer. Hex numbers must also be prefixed with '0x' in AHK.

Reading a pointer should look something like this:

Code: Select all

Base := getProcessBaseAddress("ahk_exe Solitaire.exe")
msgbox, %Base% " Base"

pointerBase := base + 0x000BB0E8
p1 := ReadMemory(pointerBase, "ahk_exe Solitaire.exe")
p2 := ReadMemory(p1 + 0x68, "ahk_exe Solitaire.exe")
p3 := ReadMemory(p2 + 0x428, "ahk_exe Solitaire.exe")
gamesPlayed := ReadMemory(p3 + 0x7BC, "ahk_exe Solitaire.exe")

msgbox % gamesPlayed
https://github.com/Kalamity/SC2-MacroTr ... Memory.ahk
With the above class you can read a pointer in one call:

Code: Select all

if (_ClassMemory.__Class != "_ClassMemory")
    msgbox class memory not correctly installed. Or the (global class) variable "_ClassMemory" has been overwritten


mem := new _ClassMemory("ahk_exe Solitaire.exe", "", hProcessCopy) 
if !isObject(mem)
    msgbox failed to open a handle
if !hProcessCopy
    msgbox failed to open a handle. Error Code = %hProcessCopy%

msgbox % mem.BaseAddress
gamesPlayed := mem.read(mem.BaseAddress + 0x000BB0E8, "UInt", 0x68, 0x428, 0x7BC)
msgbox % gamesPlayed

Post Reply

Return to “Gaming Help (v1)”