###User Defined Function###
_MemoryPointerWrite

###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 writes the specified data there and returns the address.  In order to use this function, you must have a static memory address and the necessary offsets for all of the pointers.

###Syntax###
_MemoryPointerWrite ($iv_Address, $ah_Handle, $av_Offset, $v_Data[, $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.
$v_Data
	The data to be written.
$sv_Type
	The "Type" of value to write at the destination address.  This is set to 'dword' by default.
@@End@@

###ReturnValue###
@@ReturnTable@@
Success:	The destination address.
Failure:	0.
@Error:		0 = No error.
		1 = $av_Offset is not an array.
		2 = Invalid $ah_Handle.
		3 = Failed to read from the specified process.
		4 = $sv_Type was not a string.
		5 = $sv_Type is an unknown data type.
		6 = Failed to allocate the memory needed for the DllStructure.
		7 = Error allocating memory for $sv_Type.
		8 = $v_Data is not in the proper format to be used with the "Type" selected for $sv_Type, or it is out of range.
		9 = Failed to write to 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 value located at the destination address is replaced by $v_Data.
	The format and size of $v_Data must match the $sv_Type selected.
	The destination address is returned by the function.

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 at all)
	$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 to be written should be in ASCII format, otherwise the data to be written should be in Decimal format.  Also, the size ('char[size]') for all 'char' types should be 1 greater than the actual size.

For help on creating "Types", see DllStructCreate.


###Related###
_MemoryOpen, _MemoryClose, _MemoryWrite, _MemoryPointerRead, _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)

;write the 'dword' value at the destination address
$Data = 0987654321
$Value = _MemoryPointerWrite($Address, $Handle, $Offset, $Data)

#cs
;or if the value is a 11 character 'char' type
$Data = 'Hello World'
$Type = 'char[12]' ;<= add 1 char more
$Value = _MemoryPointerWrite($Address, $Handle, $Offset, $Data, $Type)
#ce

;display the destination address
MsgBox(4096, "Returned", "Address = " & $Value)

;read the address just written ('dword')
MsgBox(4096, "Value", _MemoryPointerRead($Address, $Handle, $Offset))

#cs
;or read the address just written ('char[12]')
MsgBox(4096, "Value", _MemoryPointerRead($Address, $Handle, $Offset, $Type))
#ce

;close the open process
_MemoryClose($Handle)
@@End@@