Sign in to follow this  
Followers 0
SteveO

Memory Read Issue.

6 posts in this topic

What am I doing wrong here? :)

Im trying to make a program to read the health and mana values of Dynamic Memory in a game (Guild Wars)...It just doesn't seem to want to read, and I know it's probably my syntax.

#include <GUIConstants.au3>
#include <NomadMemory.au3>

Global $GameID
Global $HPointer=0x0802bde0
Global $HOffset=0
Global $Health

$Form1 = GUICreate("Stats Reader", 163, 91, 193, 125)
$Label1 = GUICtrlCreateLabel("Stats Reader", 8, 8, 66, 17)
$Label2 = GUICtrlCreateLabel("HEALTH : ", 8, 40, 56, 17)
$Label3 = GUICtrlCreateLabel("ENERGY : ", 8, 56, 58, 17)
$Label4 = GUICtrlCreateLabel("0", 72, 40, 11, 17)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
GUICtrlSetColor(-1, 0xFF0000)
$Label5 = GUICtrlCreateLabel("0", 72, 56, 11, 17)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
GUICtrlSetColor(-1, 0x0000FF)
$Button1 = GUICtrlCreateButton("Start", 96, 32, 59, 49, 0)
GUISetState(@SW_SHOW)


While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $Button1
        GetHealth()
        
    Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
WEnd


Func GetHealth()
$GameID = _MemoryOpen(ProcessExists("Gw.exe"))
$Address=_MemoryPointerRead($HPointer, $GameID, $HOffset, '4 bytes')
$Health=_MemoryRead($Address,$GameID)
GUICtrlSetData($Label4, $Health)

EndFunc

Share this post


Link to post
Share on other sites



What am I doing wrong here? :)

Im trying to make a program to read the health and mana values of Dynamic Memory in a game (Guild Wars)...It just doesn't seem to want to read, and I know it's probably my syntax.

#include <GUIConstants.au3>
#include <NomadMemory.au3>

Global $GameID
Global $HPointer=0x0802bde0
Global $HOffset=0
Global $Health

$Form1 = GUICreate("Stats Reader", 163, 91, 193, 125)
$Label1 = GUICtrlCreateLabel("Stats Reader", 8, 8, 66, 17)
$Label2 = GUICtrlCreateLabel("HEALTH : ", 8, 40, 56, 17)
$Label3 = GUICtrlCreateLabel("ENERGY : ", 8, 56, 58, 17)
$Label4 = GUICtrlCreateLabel("0", 72, 40, 11, 17)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
GUICtrlSetColor(-1, 0xFF0000)
$Label5 = GUICtrlCreateLabel("0", 72, 56, 11, 17)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
GUICtrlSetColor(-1, 0x0000FF)
$Button1 = GUICtrlCreateButton("Start", 96, 32, 59, 49, 0)
GUISetState(@SW_SHOW)


While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $Button1
        GetHealth()
        
    Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
WEnd


Func GetHealth()
$GameID = _MemoryOpen(ProcessExists("Gw.exe"))
$Address=_MemoryPointerRead($HPointer, $GameID, $HOffset, '4 bytes')
$Health=_MemoryRead($Address,$GameID)
GUICtrlSetData($Label4, $Health)

EndFunc

What is _MemoryPointerRead? It's not in the version of NomadMemory I use.


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Oh, sry, saw that in another topic, n I just added it in.

;=================================================================================================
; Function:   _MemoryPointerRead ($iv_Address, $ah_Handle, $av_Offset[, $sv_Type])
; Description:    Reads a chain of pointers and returns an array containing the destination
;               address and the data at the address.
; Parameter(s):  $iv_Address - The static memory address you want to start at. It must be in
;                          hex format (0x00000000).
;               $ah_Handle - An array containing the Dll handle and the handle of the open
;                         process as returned by _MemoryOpen().
;               $av_Offset - An array of offsets for the pointers.  Each pointer must have an
;                         offset.  If there is no offset for a pointer, enter 0 for that
;                         array dimension.
;               $sv_Type - (optional) The "Type" of data you intend to read at the destination
;                         address.  This is set to 'dword'(32bit(4byte) signed integer) by
;                         default.  See the help file for DllStructCreate for all types.
; Requirement(s):   The $ah_Handle returned from _MemoryOpen.
; Return Value(s):  On Success - Returns an array containing the destination address and the value
;                         located at the address.
;               On Failure - Returns 0
;               @Error - 0 = No error.
;                      1 = $av_Offset is not an array.
;                      2 = Invalid $ah_Handle.
;                      3 = $sv_Type is not a string.
;                      4 = $sv_Type is an unknown data type.
;                      5 = Failed to allocate the memory needed for the DllStructure.
;                      6 = Error allocating memory for $sv_Type.
;                      7 = Failed to read from the specified process.
; Author(s):        Nomad
; Note(s):      Values returned are in Decimal format, unless a 'char' type is selected.
;               Set $av_Offset like this:
;               $av_Offset[0] = NULL (not used)
;               $av_Offset[1] = Offset for pointer 1 (all offsets must be in Decimal)
;               $av_Offset[2] = Offset for pointer 2
;               etc...
;               (The number of array dimensions determines the number of pointers)
;=================================================================================================
Func _MemoryPointerRead ($iv_Address, $ah_Handle, $av_Offset, $sv_Type = 'dword')
   
    If IsArray($av_Offset) Then
        If IsArray($ah_Handle) Then
            Local $iv_PointerCount = UBound($av_Offset) - 1
        Else
            SetError(2)
            Return 0
        EndIf
    Else
        SetError(1)
        Return 0
    EndIf
   
    Local $iv_Data[2], $i
    Local $v_Buffer = DllStructCreate('dword')
   
    For $i = 0 to $iv_PointerCount
       
        If $i = $iv_PointerCount Then
            $v_Buffer = DllStructCreate($sv_Type)
            If @Error Then
                SetError(@Error + 2)
                Return 0
            EndIf
           
            $iv_Address = '0x' & hex($iv_Data[1] + $av_Offset[$i])
            DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
            If @Error Then
                SetError(7)
                Return 0
            EndIf
           
            $iv_Data[1] = DllStructGetData($v_Buffer, 1)
           
        ElseIf $i = 0 Then
            DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
            If @Error Then
                SetError(7)
                Return 0
            EndIf
           
            $iv_Data[1] = DllStructGetData($v_Buffer, 1)
           
        Else
            $iv_Address = '0x' & hex($iv_Data[1] + $av_Offset[$i])
            DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
            If @Error Then
                SetError(7)
                Return 0
            EndIf
           
            $iv_Data[1] = DllStructGetData($v_Buffer, 1)
           
        EndIf
       
    Next
   
    $iv_Data[0] = $iv_Address
   
    Return $iv_Data

EndFunc

Share this post


Link to post
Share on other sites

Oh, sry, saw that in another topic, n I just added it in.

;=================================================================================================
; Function:   _MemoryPointerRead ($iv_Address, $ah_Handle, $av_Offset[, $sv_Type])
; Description:    Reads a chain of pointers and returns an array containing the destination
;               address and the data at the address.
; Parameter(s):  $iv_Address - The static memory address you want to start at. It must be in
;                          hex format (0x00000000).
;               $ah_Handle - An array containing the Dll handle and the handle of the open
;                         process as returned by _MemoryOpen().
;               $av_Offset - An array of offsets for the pointers.  Each pointer must have an
;                         offset.  If there is no offset for a pointer, enter 0 for that
;                         array dimension.
;               $sv_Type - (optional) The "Type" of data you intend to read at the destination
;                         address.  This is set to 'dword'(32bit(4byte) signed integer) by
;                         default.  See the help file for DllStructCreate for all types.
; Requirement(s):   The $ah_Handle returned from _MemoryOpen.
; Return Value(s):  On Success - Returns an array containing the destination address and the value
;                    
     located at the address.
;               On Failure - Returns 0
;               @Error - 0 = No error.
;                      1 = $av_Offset is not an array.
;                      2 = Invalid $ah_Handle.
;                      3 = $sv_Type is not a string.
;                      4 = $sv_Type is an unknown data type.
;                      5 = Failed to allocate the memory needed for the DllStructure.
;                      6 = Error allocating memory for $sv_Type.
;                      7 = Failed to read from the specified process.
; Author(s):        Nomad
; Note(s):      Values returned are in Decimal format, unless a 'char' type is selected.
;               Set $av_Offset like this:
;               $av_Offset[0] = NULL (not used)
;               $av_Offset[1] = Offset for pointer 1 (all offsets must be in Decimal)
;               $av_Offset[2] = Offset for pointer 2
;               etc...
;               (The number of array dimensions determines the number of pointers)
;=================================================================================================
Func _MemoryPointerRead ($iv_Address, $ah_Handle, $av_Offset, $sv_Type = 'dword')
   
    If IsArray($av_Offset) Then
        If IsArray($ah_Handle) Then
            Local $iv_PointerCount = UBound($av_Offset) - 1
        Else
            SetError(2)
            Return 0
        EndIf
    Else
        SetError(1)
        Return 0
    EndIf
   
    Local $iv_Data[2], $i
    Local $v_Buffer = DllStructCreate('dword')
   
    For $i = 0 to $iv_PointerCount
       
        If $i = $iv_PointerCount Then
            $v_Buffer = DllStructCreate($sv_Type)
            If @Error Then
                SetError(@Error + 2)
                Return 0
            EndIf
           
            $iv_Address = '0x' & hex($iv_Data[1] + $av_Offset[$i])
            DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
            If @Error Then
                SetError(7)
                Return 0
            EndIf
           
            $iv_Data[1] = DllStructGetData($v_Buffer, 1)
           
        ElseIf $i = 0 Then
            DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
            If @Error Then
                SetError(7)
                Return 0
            EndIf
           
            $iv_Data[1] = DllStructGetData($v_Buffer, 1)
           
        Else
            $iv_Address = '0x' & hex($iv_Data[1] + $av_Offset[$i])
            DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
            If @Error Then
                SetError(7)
                Return 0
            EndIf
           
            $iv_Data[1] = DllStructGetData($v_Buffer, 1)
           
        EndIf
       
    Next
   
    $iv_Data[0] = $iv_Address
   
    Return $iv_Data

EndFunc
Thanks, I've added that to my copy of NomadMemory.

The function _MemoryPointerRead returns either 0 or an array, but you are using the returned value as a hex address, so maybe that's the problem.

Also you give the type as '4 byte' but you should be saying 'dword' I think.

If you know the memory address and the offset then possibly all you need to do is

Func GetHealth()
$GameID = _MemoryOpen(ProcessExists("Gw.exe"))
$Address=_MemoryRead(AddrCalc($Address,$Hoffset),$GameID,'int')
GUICtrlSetData($Label4, $Health)
_MemoryClose($GameID)
EndFunc

Func AddrCalc($StartAddr, $Offset)
    Return '0x' & Hex(number($StartAddr) + $Offset, 8)
EndFunc

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Thanks, I've added that to my copy of NomadMemory.

The function _MemoryPointerRead returns either 0 or an array, but you are using the returned value as a hex address, so maybe that's the problem.

Also you give the type as '4 byte' but you should be saying 'dword' I think.

If you know the memory address and the offset then possibly all you need to do is

Func GetHealth()
$GameID = _MemoryOpen(ProcessExists("Gw.exe"))
$Address=_MemoryRead(AddrCalc($Address,$Hoffset),$GameID,'int')
GUICtrlSetData($Label4, $Health)
_MemoryClose($GameID)
EndFunc

Func AddrCalc($StartAddr, $Offset)
    Return '0x' & Hex(number($StartAddr) + $Offset, 8)
EndFunc

Okay, that defiantly answers some questions. But, my problem is I don't know the address. All I know is the pointer. The address changes every time you load into a new area. That's why I was using the _MemoryPointerRead. So the _MemoryPointerRead returns an array with the addresses? Does it return all possible addresses from that pointer?


Share this post


Link to post
Share on other sites

Okay, that defiantly answers some questions. But, my problem is I don't know the address. All I know is the pointer. The address changes every time you load into a new area. That's why I was using the _MemoryPointerRead. So the _MemoryPointerRead returns an array with the addresses? Does it return all possible addresses from that pointer?

I've had a look at the function _MemoryPointerRead and it looks like it's full of bugs to me. It is supposed to return an array of pointers and values based on the array of pointers passed to it, but the return array has only 2 elements, and as it goes through the values passed to it the values in the return array get overwritten. It says it was written by Nomad but either I am confused or he was having a bad day.

Here is my modified version which I think will work.

; Function:   _MemoryPointerRead ($iv_Address, $ah_Handle, $av_Offset[, $sv_Type])
; Description:  Reads a chain of pointers and returns an array containing the destination
;              address and the data at the address.
; Parameter(s):  $iv_Address - The static memory address you want to start at. It must be in
;                         hex format (0x00000000).
;              $ah_Handle - An array containing the Dll handle and the handle of the open
;                        process as returned by _MemoryOpen().
;              $av_Offset - An array of offsets for the pointers.  Each pointer must have an
;                        offset.  If there is no offset for a pointer, enter 0 for that
;                        array dimension.
;              $sv_Type - (optional) The "Type" of data you intend to read at the destination
;                        address.  This is set to 'dword'(32bit(4byte) signed integer) by
;                        default.  See the help file for DllStructCreate for all types.
; Requirement(s):   The $ah_Handle returned from _MemoryOpen.
; Return Value(s):  On Success - Returns an array containing the destination address and the value for each pointer + offset
;                        located at the address.
;              On Failure - Returns 0
;              @Error - 0 = No error.
;                     1 = $av_Offset is not an array.
;                     2 = Invalid $ah_Handle.
;                     3 = $sv_Type is not a string.
;                     4 = $sv_Type is an unknown data type.
;                     5 = Failed to allocate the memory needed for the DllStructure.
;                     6 = Error allocating memory for $sv_Type.
;                     7 = Failed to read from the specified process.
; Author(s):        Nomad
;              modified by martin (mg)- added 2nd dimension to $iv_Data 28th Dec 2007
; Note(s):    Values returned are in Decimal format, unless a 'char' type is selected.
;              Set $av_Offset like this:
;              $av_Offset[0] = NULL (not used)
;              $av_Offset[1] = Offset for pointer 1 (all offsets must be in Decimal)
;              $av_Offset[2] = Offset for pointer 2
;              etc...
;              (The number of array dimensions determines the number of pointers)
;=================================================================================================
Func _MemoryPointerRead ($iv_Address, $ah_Handle, $av_Offset, $sv_Type = 'dword')
   
    If IsArray($av_Offset) Then
        If IsArray($ah_Handle) Then
            Local $iv_PointerCount = UBound($av_Offset) - 1
        Else
            SetError(2)
            Return 0
        EndIf
    Else
        SetError(1)
        Return 0
    EndIf
   
    Local $iv_Data[2][$iv_PointerCount], $i;<-Was $iv_Data[2]-mg
    Local $v_Buffer = DllStructCreate('dword')
   
    For $i = 0 to $iv_PointerCount
       
        If $i = $iv_PointerCount Then
            $v_Buffer = DllStructCreate($sv_Type)
            If @Error Then
                SetError(@Error + 2)
                Return 0
            EndIf
           
            $iv_Address = '0x' & hex($iv_Data[1] + $av_Offset[$i])
            DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
            If @Error Then
                SetError(7)
                Return 0
            EndIf
           
            $iv_Data[1][$i] = DllStructGetData($v_Buffer, 1);<-Was $iv_Data[1]-mg
           
        ElseIf $i = 0 Then
            DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
            If @Error Then
                SetError(7)
                Return 0
            EndIf
           
            $iv_Data[1][$i] = DllStructGetData($v_Buffer, 1);<-Was $iv_Data[1]-mg
           
        Else
            $iv_Address = '0x' & hex($iv_Data[1] + $av_Offset[$i])
            DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
            If @Error Then
                SetError(7)
                Return 0
            EndIf
           
            $iv_Data[1][$i] = DllStructGetData($v_Buffer, 1);;<-Was $iv_Data[1]
           
        EndIf
       $iv_Data[0][$i] = $iv_Address;<-Was $iv_Data[0], and was after the 'Next' line below-mg
    Next
   
    
   
    Return $iv_Data

EndFunc

I'm not sure this is such a useful function anyway

.

You got the address

Global $HPointer=0x0802bde0

from somewhere, so maybe wherever you got that there is more information on what is stored where and how. Without that information I can't say what should be done.

I'm afraid I know nothing about Guild Wars (or any other war come to that).


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0