Code:
#include <NomadMemory.au3>
Global $kernel32 = DllOpen('kernel32.dll')
Global $pid = ProcessExists('elementclient.exe')
Global $ph = _MemoryOpen($pid)
Global $baseCall = 0xC0C68C; ; v731
; Offset chain to find guiCommand() function call
Global $guiCommandCallOffsets[7] = [0, 0x1C, 0x18, 0x8, 0, 0x14, 0]
Global $guiCommandCall = _MemoryPointerRead($baseCall, $ph, $guiCommandCallOffsets)
$guiCommandCall = $guiCommandCall[0]
; Offsets chain to find currently focused dialogue object
Global $focusedDialogueOffsets[5] = [0, 0x1C, 0x18, 0x8, 0x74]
Global $focusedDialogue = _MemoryPointerRead($baseCall, $ph, $focusedDialogueOffsets)
$focusedDialogue = $focusedDialogue[0]
; For debugging purposes
ConsoleWrite(Hex($guiCommandCall) & @CRLF)
ConsoleWrite(Hex($focusedDialogue) & @CRLF)
; Close that window!
guiCommand("Btn_Close", $focusedDialogue)
Func guiCommand($command, $guiObjPtr)
; Declare local variables
Local $pRemoteThread, $vBuffer, $loop, $result, $OPcode, $processHandle, $stringAddress, $stringSize
$processHandle = memOpen($pid)
; First let's write the command string to somewhere in the client memory
$stringSize = StringLen($command)
; Allocate memory for the string to be sent and retrieve the address for this
$stringAddress = DllCall($kernel32, 'int', 'VirtualAllocEx', 'int', $processHandle, 'ptr', 0, 'int', $stringSize, 'int', 0x1000, 'int', 0x40)
ConsoleWrite("String Address: " & Hex($stringAddress[0]) & @CRLF)
; Put the string into a struct for later memory writing
$vBuffer = DllStructCreate('byte[' & StringLen($command) & ']')
For $loop = 1 To DllStructGetSize($vBuffer)
DllStructSetData($vBuffer, 1, $command)
Next
; Write the string to previously allocated memory
DllCall($kernel32, 'int', 'WriteProcessMemory', 'int', $processHandle, 'int', $stringAddress[0], 'int', DllStructGetPtr($vBuffer), 'int', DllStructGetSize($vBuffer), 'int', 0)
; Allocate memory for the OpCode and retrieve address for this
$functionAddress = DllCall($kernel32, 'int', 'VirtualAllocEx', 'int', $processHandle, 'ptr', 0, 'int', 0x46, 'int', 0x1000, 'int', 0x40)
; Construct the OpCode for calling the 'guiCommand' function
$OPcode &= '60' ; PUSHAD
$OPcode &= 'A1' & _hex($guiObjPtr) ; MOV EAX, guiObjPtr
$OPcode &= '50' ; PUSH EAX
$OPcode &= '68' & _hex($stringAddress[0]) ; PUSH commandString
$OPcode &= 'B8' & _hex($guiCommandCall) ; MOV EAX, guiCommandCall
$OPcode &= 'FFD0' ; CALL EAX
$OPcode &= '61' ; POPAD
$OPcode &= 'C3' ; RETN
; 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, '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, '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, 'int', 'CloseHandle', 'int', $hRemoteThread[0])
; Free the previously allocated memory
DllCall($kernel32, 'ptr', 'VirtualFreeEx', 'hwnd', $processHandle, 'int', $functionAddress[0], 'int', 0, 'int', 0x8000)
DllCall($kernel32, 'ptr', 'VirtualFreeEx', 'hwnd', $processHandle, 'int', $stringAddress[0], 'int', 0, 'int', 0x8000)
memClose($processHandle)
Return True
EndFunc ;==>guiCommand
Func _hex($value, $size = 8)
Local $tmp1, $tmp2, $i
$tmp1 = StringRight("000000000" & Hex($value), $size)
For $i = 0 To StringLen($tmp1) / 2 - 1
$tmp2 = $tmp2 & StringMid($tmp1, StringLen($tmp1) - 1 - 2 * $i, 2)
Next
Return $tmp2
EndFunc ;==>_hex
Func memopen($pid)
Local $mid = DllCall($kernel32, 'int', 'OpenProcess', 'int', 0x1F0FFF, 'int', 1, 'int', $pid)
Return $mid[0]
EndFunc ;==>memopen
Func memclose($mid)
DllCall($kernel32, 'int', 'CloseHandle', 'int', $mid)
EndFunc ;==>memclose