Code:
#include <NomadMemory.au3>
Global $GAME_CLIENT = "elementclient.exe"
Global $GAME_PID = ProcessExists($GAME_CLIENT)
Global $GAME_PROCESS = _MemoryOpen($GAME_PID)
Global $ADDRESS_BASE = 0xD22C74
Global $OFFSET_ACTIONBASE = 0x13EC
Func FollowPlayer()
$ADDRESS_ACTION1 = 0x49FF80
$ADDRESS_FOLLOW = 0x6820C0
$ADDRESS_ACTION3 = 0x4A0590
;Construct the OpCode for calling the 'FollowPlayer' function
$OPcode = "60" ;60 PUSHAD
$OPcode &= "B9" & _Hex($ADDRESS_BASE) ;B8 00000000 MOV ECX, $ADDRESS_BASE
$OPcode &= "8B09" ;8B009 MOV ECX,DWORD PTR DS:[ECX]
$OPcode &= "8B491C" ;8B49 1C MOV ECX,DWORD PTR DS:[ECX+1C]
$OPcode &= "8B7128" ;8B71 28 MOV ESI,DWORD PTR DS:[ECX+28] ; |
$OPcode &= "8B8E" & _Hex($OFFSET_ACTIONBASE);8B8E EC130000 MOV ECX,DWORD PTR DS:[ESI+13EC]
$OPcode &= "57" ;57 PUSH EDI (EDI=0x26)
$OPcode &= "6A07" ;6A 07 PUSH 7
$OPcode &= "BA" & _Hex($ADDRESS_ACTION1) ;BA 00000000 MOV EDX, $ADDRESS_ACTION1
$OPcode &= "FFD2" ;FFD2 CALL EDX
$OPcode &= "8BF8" ;8BF8 MOV EDI,EAX
$OPcode &= "BB" & _Hex($TARGET) ;B8 00000000 MOV EBX, Target ID
$OPcode &= "53" ;53 PUSH EBX (PLAYER ID)
$OPcode &= "8BCF" ;8BCF MOV ECX,EDI
$OPcode &= "BA" & _Hex($ADDRESS_FOLLOW) ;BA 00000000 MOV EDX, $ADDRESS_FOLLOW
$OPcode &= "FFD2" ;FFD2 CALL EDX
$OPcode &= "B9" & _Hex($ADDRESS_BASE) ;B8 00000000 MOV ECX, $ADDRESS_BASE
$OPcode &= "8B09" ;8B009 MOV ECX,DWORD PTR DS:[ECX]
$OPcode &= "8B491C" ;8B49 1C MOV ECX,DWORD PTR DS:[ECX+1C]
$OPcode &= "8B7128" ;8B71 28 MOV ESI,DWORD PTR DS:[ECX+28] ; |
$OPcode &= "8B8E" & _Hex($OFFSET_ACTIONBASE);8B8E EC130000 MOV ECX,DWORD PTR DS:[ESI+13EC]
$OPcode &= "6A00" ;6A 00 PUSH 0
$OPcode &= "57" ;57 PUSH EDI
$OPcode &= "6A01" ;6A 01 PUSH 1
$OPcode &= "BA" & _Hex($ADDRESS_ACTION3) ;BA 00000000 MOV EDX, $ADDRESS_ACTION3
$OPcode &= "FFD2" ;FFD2 CALL EDX
$OPcode &= "61" ;61 POPAD
$OPcode &= "C3" ;C3 RETN
InjectCode($OPcode)
EndFunc
Func InjectCode($OPcode)
;Declare local variables
;Open process for given processId
$processHandle = $GAME_PROCESS[1]
;Allocate memory for the OpCode and retrieve address for this
$functionAddress = DllCall('kernel32.dll', 'int', 'VirtualAllocEx', 'int', $processHandle, 'ptr', 0, 'int', 100, 'int', 0x1000, 'int', 0x40)
;Construct the OpCode for calling the function
;Put the OpCode into a struct for later memory writing
$vBuffer = DllStructCreate('byte[' & StringLen($OPcode) / 2 & ']')
For $loop = 1 To DllStructGetSize($vBuffer)
DllStructSetData($vBuffer, 1, Dec(StringMid($OPcode, ($loop - 1) * 2 + 1, 2)), $loop)
Next
;Write the OpCode to previously allocated memory
DllCall('kernel32.dll', 'int', 'WriteProcessMemory', 'int', $processHandle, 'int', $functionAddress[0], 'int', DllStructGetPtr($vBuffer), 'int', DllStructGetSize($vBuffer), 'int', 0)
;Create a remote thread in order to run the OpCode
$hRemoteThread = DllCall('kernel32.dll', 'int', 'CreateRemoteThread', 'int', $processHandle, 'int', 0, 'int', 0, 'int', $functionAddress[0], 'ptr', 0, 'int', 0, 'int', 0)
;Wait for the remote thread to finish
Do
$result = DllCall('kernel32.dll', 'int', 'WaitForSingleObject', 'int', $hRemoteThread[0], 'int', 50)
Until $result[0] <> 258
;Close the handle to the previously created remote thread
DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $hRemoteThread[0])
;Free the previously allocated memory
DllCall('kernel32.dll', 'ptr', 'VirtualFreeEx', 'hwnd', $processHandle, 'int', $functionAddress[0], 'int', 0, 'int', 0x8000)
Return True
EndFunc