###User Defined Function###
_MemoryPointerRead

###Description###
Reads a series of pointers and adds offsets to the value of the pointers to reach a destination dynamic memory address.  After reaching the destination, it returns an array containing the destination address as well as the value located there.  In order to use this function, you must have a static memory address and the necessary offsets for all of the pointers.

###Syntax###
_MemoryPointerRead ($iv_Address, $ah_Handle, $av_Offset[, $sv_Type])

###Parameters###
@@ParamTable@@
$iv_Address
	The static memory address 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.  If a pointer has no offset, enter 0 for that array dimension.  All offsets must be in Decimal format, do not use Hexadecimal.
$sv_Type
	The "Type" of value to read at the destination address.  The default type is 'dword'.
@@End@@

###ReturnValue###
@@ReturnTable@@
Success:	An array containing the destination address and the value located there.
Failure:	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.
@@End@@


###Remarks###
How this function operates:
	Reads the value located at the static memory address.
	Adds $av_Offset[1] to that value, then converts the new value to Hexadecimal.
	The new Hexadecimal value becomes Pointer 1.
	Reads the value located at Pointer 1.
	Adds $av_Offset[2] to that value, then converts the new value to Hexadecimal.
	The new Hexadecimal value becomes Pointer 2.

	...This continues until all offsets have been used.
	
	The last offset is used to create the last pointer (destination address).
	The destination address is returned in an array with the value stored there.
	The format and size of the returned value is determined by $sv_Type.

	Array[0] = destination address
	Array[1] = value stored at the destination address

The number of pointers to read is determined by the size of $av_Offset, so an array dimension must be created for every pointer.  Set $av_Offset like this before calling the function:

	$av_Offset[0] = NULL (not used)
	$av_Offset[1] = 56 (Offset for the 1st pointer)
	$av_Offset[2] = 0 (Offset for the 2nd pointer (none))
	$av_Offset[3] = 24 (Offset for the 3rd pointer)
	etc...

If the "Type" is of the 'char' type, the data returned is in ASCII format, otherwise the data returned is in Decimal format.  Also, the size ('char[size]') for all 'char' types should be 1 greater than the actual size.

For more help on creating "Types", see DllStructCreate.


###Related###
_MemoryOpen, _MemoryClose, _MemoryRead, _MemoryWrite, _MemoryPointerWrite


###Example###
@@IncludeExample@@
;This is just a structural example it will not function
;unless the correct information is entered.
#include <Memory.au3>

;get the process ID
$ProcessID = WinGetProcess("Any Window")

;set the static address
$Address = 0x6FBCC1E0

;set the pointer offsets in Decimal
Dim $Offset[4]
$Offset[0] = 56  ;0x38 in Hex
$Offset[1] = 0   ;no offset for pointer 2
$Offset[2] = 200 ;0xC8 in Hex
$Offset[3] = 0   ;no offset for pointer 4

;open the process and get the handle
$Handle = _MemoryOpen($ProcessID)

;read the 'dword' value at the destination address
$Value = _MemoryPointerRead($Address, $Handle, $Offset)

#cs
;or if the value is a 9 character 'char' type
$Type = 'char[10]'
$Value = _MemoryPointerRead($Address, $Handle, $Offset, $Type)
#ce

;close the open process
_MemoryClose($Handle)

;display the value and the destination address
MsgBox(4096, "Returned", "Address = " & $Value[0] & @CRLF & "Value =" & $Value[1])
@@End@@