[AutoIT3] Get HP Using Hooks (works with v5128+)

05/23/2009 07:28 clintonselke#1
Ok, calling some functions with CreateRemoteThread() has been crashing with me since the new patch. So here is another way to get the current HP for use in an autopotter.

This method hooks the gethp() function of the new version of co, instead of calling it.

VERY IMPORTANT
Run This First at the Log On Screen to make sure the code does not execute over the coding being replaced while its being replaced (This needs to be done because i write the code byte by byte)

Other than that, the next time u run it on the same conquer process, it will recognize the hook was already established and will not overwrite the hook (it will make use of it instead)

Also note, this is currently configured to press F10 when ur HP is less than 1000.

PHP Code:
#include "NomadMemory.au3"

$PID ProcessExists("Conquer.exe")
If 
$PID == 0 Then
    MsgBox
(0"Error""Conquer must be running first.")
    Exit
EndIf
$MemID _MemoryOpen($PID)

Global 
$HP_ADDR
If _MemoryRead(0x0056953E$MemID"byte") == -23 Then
    $num 
_MemoryRead(0x0056953F$MemID'dword')
    
$HP_ADDR BitAnd($num 0x0056953E 50xFFFFFFFF) - 4
Else
    
$HP_ADDR AllocMemory(24$PID)
    
    ; 
Fill in the code we're gonna overwrite in the cave.
    $Code =         "0f84" & RelativePos($HP_ADDR+5, 0x00569554)  ; je 00569554
    $Code = $Code & "48"                                          ; dec eax
    $Code = $Code & "0f84" & RelativePos($HP_ADDR+5+StringLen($Code)/2, 0x00569549) ; je 00569549

    ; Put in our copy code (to copy the HP value)
    $Code = $Code & "8915" & Int2Hex($HP_ADDR, 8) ; mov [$HP_ADDR],edx

    ; Then our jump back code
    $Code = $Code & "e9" & RelativePos($HP_ADDR+23, 0x00569543) ; jmp 00569543
    
    ; Write our code
    For $i = 0 To StringLen($Code)/2-1
        _MemoryWrite($HP_ADDR+4+$i, $MemID, Dec(StringMid($Code, $i * 2 + 1, 2)), "byte")
    Next

    ; Patch the jump
    $Code = "e9" & RelativePos(0x0056953E, $HP_ADDR+4)
    For $i = 0 To StringLen($Code)/2-1
        _MemoryWrite(0x0056953E+$i, $MemID, Dec(StringMid($Code, $i * 2 + 1, 2)), "byte")
    Next
EndIf

HotKeySet("!x", "ExitProg")

While 1
    $HP = _MemoryRead($HP_ADDR, $MemID)
    ToolTip(Hex($HP_ADDR) & ":AutoPotter Running (" & $HP & "). Alt+X to exit.", 20, 20)
    If $HP < 1000 Then
        Send("{F10}")
    EndIf
    Sleep(500)
WEnd

Exit(0)

Func ExitProg()
    _MemoryClose($PID)
    Exit(0)
EndFunc

Func AllocMemory($Size, $PID)
    Const $PAGE_EXECUTE_READWRITE = 0x40
    Const $MEM_COMMIT = 0x1000
    Const $MEM_DECOMMIT = 0x4000
    Const $MEM_RELEASE = 0x8000
    Const $PROCESS_ALL_ACCESS = 0x1F0FFF
    Local $kernel32, $hProcess
    Local $result
    Local $pRemoteMem
    
    $kernel32 = DllOpen("kernel32.dll")

    $hProcess = DllCall($kernel32, "int", "OpenProcess", "int", $PROCESS_ALL_ACCESS, "int", 0, "int", $pid)
    If IsArray($hProcess) And $hProcess[0] <> 0 Then
        $hProcess = $hProcess[0]
    Else
        ConsoleWrite("error -4");
        SetError(-4)
        Return False
    EndIf
    
    ; Allocate romote memory to sit the code
    $pRemoteMem = DllCall($kernel32, "ptr", "VirtualAllocEx", "int", $hProcess, "ptr", 0, "int", $Size, "int", $MEM_COMMIT, "int", $PAGE_EXECUTE_READWRITE)
    If IsArray($pRemoteMem) And $pRemoteMem[0] <> 0 Then
        $pRemoteMem = $pRemoteMem[0]
    Else
        ConsoleWrite("error -5");
        SetError(-5)
        Return False
    EndIf

    
    DllCall($kernel32, "int", "CloseHandle", "int", $hProcess)

    DllClose($kernel32)
    
    Return $pRemoteMem
EndFunc

Func FreeMemory($pMem, $PID)
    Const $PAGE_EXECUTE_READWRITE = 0x40
    Const $MEM_COMMIT = 0x1000
    Const $MEM_DECOMMIT = 0x4000
    Const $MEM_RELEASE = 0x8000
    Const $PROCESS_ALL_ACCESS = 0x1F0FFF
    Local $kernel32, $hProcess
    Local $result
    
    $kernel32 = DllOpen("kernel32.dll")
    $hProcess = DllCall($kernel32, "int", "OpenProcess", "int", $PROCESS_ALL_ACCESS, "int", 0, "int", $pid)
    If IsArray($hProcess) And $hProcess[0] <> 0 Then
        $hProcess = $hProcess[0]
    Else
        ConsoleWrite("error -4");
        SetError(-4)
        Return False
    EndIf
    
    DllCall($kernel32, "ptr", "VirtualFreeEx", "hwnd", $hProcess, "ptr", $pMem, "int", 0, "int", $MEM_RELEASE)
    
    DllCall($kernel32, "int", "CloseHandle", "int", $hProcess)

    DllClose($kernel32)
EndFunc

Func Int2Hex($Value, $n)
    Local $tmp1, $tmp2, $i 
    $tmp1 = StringRight("0000000" & Hex($Value), $n) 
    For $i = 0 To StringLen($tmp1) / 2 - 1 
        $tmp2 = $tmp2 & StringMid($tmp1, StringLen($tmp1) - 1 - 2 * $i, 2)
    Next
    Return $tmp2
EndFunc

Func RelativePos($src_addr, $dst_addr)
    $num = BitAnd($dst_addr + BitXOR($src_addr+5, 0xFFFFFFFF) + 1, 0xFFFFFFFF)
    Return Int2Hex($num, 8)
EndFunc 
05/23/2009 14:47 ace_heart#2
it's good i try use ur code on Spanish version and find address and change it ur code but still can't read HP can help me , i think problem when write code in empty address !!
05/23/2009 17:19 clintonselke#3
Thats funny, i ran it just now again and it suddenly stopped working... something must not be static and this is not ready for release.

#request delete
05/23/2009 17:32 ace_heart#4
i test it on English version 6 times wok fine in 4 and 2 times fail, i don't need u make another for Spanish
i just need tell me what my wrong after i change a memory , i need learn not get tool
05/23/2009 18:04 clintonselke#5
Well, what i did for it was i used CE to find the HP memory address using a binary search. Then after finding this (non-static) value, i went right click "Find was accesses this address", and it gave me a line of assembly from the conquer process "MOV EDX,[EDI]", and i added a breakpoint to that line, and i noticed it was being executed once per frame. So i used autoit to allocate some memory, write some code into that allocated memory that restores the assembly instructions that my 5 byte jump will overwrite as well as storing the HP value in a static location, then at the end of the code in the allocated memory i had another jmp instruction that jumps back to just after my jump to my ram code. That way i was hooking that EDX value to retrieve the current HP... but its not working 100% of the time, so i was wrong to assume that the conquer code will always cross that path every frame.
05/23/2009 21:32 IAmHawtness#6
Quote:
Originally Posted by clintonselke View Post
#request delete
To delete this thread, go to the first post -> press edit -> press "Delete" :)
05/24/2009 08:56 clintonselke#7
Quote:
Originally Posted by IAmHawtness View Post
To delete this thread, go to the first post -> press edit -> press "Delete" :)
Just had a look... and... its not there xD ... i swear i saw that delete button b4.
Maybe can't delete a thread after someone else has posted on it???
05/28/2009 17:32 clintonselke#8
Never mind that hooks method, I think the following is static

$ID=_MemoryOpen(ProcessExists("conquer.exe"))
$PlayerBase = _MemoryRead(0x0064FF48, $ID)

$Base2 = _MemoryRead($PlayerBase + 0x800, $ID)

$CurrentHP = _MemoryRead($Base2 + 0x1D00, $ID)
05/30/2009 10:56 BigSoltan22#9
plz thats nice but iam new at the foroum and i dont know how too use that file