Sign in to follow this  
Followers 0
zakoz

memory Pointer problem

19 posts in this topic

#1 ·  Posted (edited)

Hello

first of all i would like to apologize, the answer probably lie somewhere in the forum but the more i read the less i understand

okay so lets begin, im pretty new to autoit.

I wanted to make a program which will change values in specific memory adresses, i got nomadmemory functions like _memoryread / _memorywrite to work but im completely confused with memorypointerread/write, i can't get them to work

with simple script like this (its nomad's modified script)

Global $ah_handle


$ProcessID = WinGetProcess("classname=Knight OnLine Client", "")
If $ProcessID = -1 Then
    MsgBox(4096, "ERROR", "Failed to detect process.")

Exit
EndIf


$Val = Read_Memory()
MsgBox(0, "number", $Val)

Func Read_Memory()
    Local $Value
    $ah_handle = _MemoryOpen($ProcessID)
    If @Error Then
        MsgBox(4096, "ERROR", "Failed to open memory.")
        Exit
    EndIf
   
    $Value = _MemoryPointerRead(0x00E25B34, $ah_handle, 0x0A0)
    If @Error Then
        MsgBox(4096, "ERROR", "SSFailed to read memory.")
        Exit
    EndIf
   
    _MemoryClose($ah_handle)
    If @Error Then
        MsgBox(4096, "ERROR", "TTFailed to close memory.")
        Exit
    EndIf
   
    Return $Value
EndFunc

i get an error "SSFailed to Read memory" (i've added SS and TT to check in which part problem occurs)

i've got also some Pointer to Pointer adresses which i have no clue how to work with

pointer to pointer adress are like this:

(0x008189a0 + 0x7C) + 0xA0

in cheat engine

0x008189a0 + 0x7C points to -> 0x00E25AE4 + 0xA0 points to -> DMA Adress (0x00E4D8D0) with value im looking for.

How would it look like in autoit?

thanks in advance!

Edited by zakoz

Share this post


Link to post
Share on other sites



additional to my Pointer problem (help anyone?) i have a question

how do i revoke HotKeySet?

for example i made a form with checkbox and a script

Case $msg = $shortcut

If BitAnd(GUICtrlRead($shortcut),$GUI_CHECKED) Then

HotKeySet("^n", "Read_INN_Memory")

HotKeySet("^l", "Read_Anvil_Memory")

HotKeySet("^v", "Read_WoW_Memory")



endif

If BitAnd(GUICtrlRead($shortcut),$GUI_UNCHECKED) Then



endif

shortcut checkbox work for the first time - hotkeyset doesn't work when i start the program (checkbox is unchecked), and when i check the box hotkeyset start to work but when i uncheck the checkbox these still work and i want them to stop working when checkbox is unchecked. Any idea how to do that?

and another question

- is it possible to send hotkeys to our script/application when its not an active window?

for example i want my autoit script to run a function when hotkey is pressed but in another window/application.

Share this post


Link to post
Share on other sites

bump :)

Share this post


Link to post
Share on other sites

$Val = Read_Memory()

read what memory?

the code you have posted seems somewhat fragmented

ill have a look at this at home

i cant run scripts at work :)

also look into some of the other successfull bots out in the forums thell give you good pointers

also in most online games anything important tends to stay on the server side

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

additional to my Pointer problem (help anyone?) i have a question

how do i revoke HotKeySet?

for example i made a form with checkbox and a script

Case $msg = $shortcut

If BitAnd(GUICtrlRead($shortcut),$GUI_CHECKED) Then

HotKeySet("^n", "Read_INN_Memory")

HotKeySet("^l", "Read_Anvil_Memory")

HotKeySet("^v", "Read_WoW_Memory")



endif

If BitAnd(GUICtrlRead($shortcut),$GUI_UNCHECKED) Then



endif

shortcut checkbox work for the first time - hotkeyset doesn't work when i start the program (checkbox is unchecked), and when i check the box hotkeyset start to work but when i uncheck the checkbox these still work and i want them to stop working when checkbox is unchecked. Any idea how to do that?

and another question

- is it possible to send hotkeys to our script/application when its not an active window?

for example i want my autoit script to run a function when hotkey is pressed but in another window/application.

Why don't you post the whole script you're having problems with, it's a little hard to help you when only looking at fragments. :)

For reading memory, I've created a set of small functions(I still haven't tried nomad memory but I prefer it this way, it's simple enough):

Func _ReadProcessPointers(ByRef $hvProcess, $ivBaseAddress, $avOffsets)
    If Not IsArray($avOffsets) Then Return _ReadProcessMemory($hvProcess, $ivBaseAddress+$avOffsets, "ptr")
    $ivBaseAddress = _ReadProcessMemory($hvProcess, $ivBaseAddress, "ptr")
    
    For $i = 0 To UBound($avOffsets)-1
        $ivBaseAddress = _ReadProcessMemory($hvProcess, $ivBaseAddress+$avOffsets[$i], "ptr")
    Next
    Return $ivBaseAddress
EndFunc

Func _ReadProcessMemory(ByRef $hProcess, $pBaseAddress, $svDataType = "byte")
    
    Local $stRead = DllStructCreate("int Read")
    Local $stData = DllStructCreate($svDataType)
    Local $aResult = DllCall("Kernel32.dll", "int", "ReadProcessMemory", "int", $hProcess, "int", $pBaseAddress, "ptr", DllStructGetPtr($stData), "int", DllStructGetSize($stData), "ptr", DllStructGetPtr($stRead))
    
    Return(SetError(Not $aResult[0], DllStructGetData($stRead, "Read"), DllStructGetData($stData, 1)))
EndFunc

Func _WriteProcessMemory($hProcess, $pBaseAddress, $bvData, $svDataType = "byte")
    Local $stWritten = DllStructCreate("int Written")
    Local $stData = DllStructCreate($svDataType)
    DllStructSetData($stData, 1, $bvData)
    
    Local $aResult = DllCall("Kernel32.dll", "int", "WriteProcessMemory", "int", $hProcess, "int", $pBaseAddress, "ptr", DllStructGetPtr($stData), "int", DllStructGetSize($stData), "int", DllStructGetPtr($stWritten))
    
    Return(SetError(Not $aResult[0], 0, DllStructGetData($stWritten, "Written")))
EndFunc

To read from your process, you could use my functions like this:

#include <WinAPI.au3>; Required for _WinAPI_OpenProcess
#include <Constants.au3>; Required for $PROCESS_ALL_ACCESS

Dim $iProcess = WinGetProcess("[CLASS:Knight OnLine Client]"); Should maybe use ProcessExists to get the ProcessID instead, as the .exe name is probably a little more reliable
If Not ProcessExists($iProcess) Then Exit(MsgBox(0, "Error", "Please launch the game first")); Make sure it's running before starting the script(you could wait for it to start up if you wanted however)

Dim $hProcess = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, False, $iProcess, False); Get the required handle to the process with access rights to be able to read/write, etc. from the process

Dim $iHealthBasePointer = 0x008189a0; Base pointer('last' pointer in the list in cheat engine, ie. the static one)
Dim $aHealthPointerOffsets[2] = [0x7C, 0xA0]; Offsets to use with above pointer

Dim $iHealtAddress = _ReadProcessPointers($hProcess, $iHealthBasePointer, $aHealthPointerOffsets); This will iterate through the aHealthPointerOffsets array to get the DMA address you're after

Dim $iHealth = 0; Assuming that the address you're reading from contains your health
While 1
    $iHealth = _ReadProcessMemory($hProcess, $iHealtAddress, "float"); Assuming that the value it's reading is a float, if it's 4byte use dword
    ToolTip("Current Health: " & $iHealth)
    Sleep(250)
WEnd

Func _ReadProcessPointers(ByRef $hvProcess, $ivBaseAddress, $avOffsets)
    If Not IsArray($avOffsets) Then Return _ReadProcessMemory($hvProcess, $ivBaseAddress, "ptr")+$avOffsets
    $ivBaseAddress = _ReadProcessMemory($hvProcess, $ivBaseAddress, "ptr")
    
    For $i = 0 To UBound($avOffsets)-1
        $ivBaseAddress = _ReadProcessMemory($hvProcess, $ivBaseAddress+$avOffsets[$i], "ptr")
    Next
    Return $ivBaseAddress
EndFunc

Func _ReadProcessMemory(ByRef $hProcess, $pBaseAddress, $svDataType = "byte")
    
    Local $stRead = DllStructCreate("int Read")
    Local $stData = DllStructCreate($svDataType)
    Local $aResult = DllCall("Kernel32.dll", "int", "ReadProcessMemory", "int", $hProcess, "int", $pBaseAddress, "ptr", DllStructGetPtr($stData), "int", DllStructGetSize($stData), "ptr", DllStructGetPtr($stRead))
    
    Return(SetError(Not $aResult[0], DllStructGetData($stRead, "Read"), DllStructGetData($stData, 1)))
EndFunc

Func _WriteProcessMemory(ByRef $hProcess, $pBaseAddress, $bvData, $svDataType = "byte")
    Local $stWritten = DllStructCreate("int Written")
    Local $stData = DllStructCreate($svDataType)
    DllStructSetData($stData, 1, $bvData)
    
    Local $aResult = DllCall("Kernel32.dll", "int", "WriteProcessMemory", "int", $hProcess, "int", $pBaseAddress, "ptr", DllStructGetPtr($stData), "int", DllStructGetSize($stData), "int", DllStructGetPtr($stWritten))
    
    Return(SetError(Not $aResult[0], 0, DllStructGetData($stWritten, "Written")))
EndFunc

I do not have the game so it's not tested, but it 'should' work - assuming that you've got the correct addresses and offsets. :party:

Edited by FreeFry

Share this post


Link to post
Share on other sites

Are you following me? lol

Share this post


Link to post
Share on other sites

Hmm, I don't know. :)

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

sorry for confusing, i gave the wrong script (the other one doesn't differ much, just instead of _MemoryPointerRead it should be _MemoryPointerWrite (0x008189a0, $ah_Handle, [0x7C, 0xA0], 1, $sv_Type = 'dword') not sure if the offsets are used properly (but i've tried with another pointer that has just one offset, tried them in decimal etc.) so my target is to change(write) a value at an adress pointed by a pointer not read.

Anyway Freefry ur script always returns 0, even if the value is 1.

I've tried to mess with ur functions as well, _ReadProcessMemory doesn't seem to work for me and _WriteProcessMemory work but.. something strange happens :party:, instead of desired value ur function writes different one. for example i've used adress for speed (running speed) - 16256 is the normal value, 16320 after swift (in-game skill) while CE and NomanMemory function works like a charm, ur script properly changes to 16320 but when i wanted 16420 it changes to 16164 and for 16100 it changes to 16643 instead.

anyway thank you Thanubis and Freefry. any forward help would be appreciated :)

Edited by zakoz

Share this post


Link to post
Share on other sites

Are you sure you're writing the correct datatype? If it's a float, it has to be specified to read/write a float, same if it's a 4byte(which incase the data type would be dword). if it's 2byte, then the datatype would be byte[2].

Share this post


Link to post
Share on other sites

Are you sure you're writing the correct datatype? If it's a float, it has to be specified to read/write a float, same if it's a 4byte(which incase the data type would be dword). if it's 2byte, then the datatype would be byte[2].

oh yea, that was the problem with read/writeProcessMemory, now i get proper values :)

EDIT.

well im making progress, got ur _ReadProcessPointers to work, but in return i get value of DMA adress in hexadecimal, i would like to get just DMA adress instead, so i could send it to _WriteProcessMemory :party:

Share this post


Link to post
Share on other sites

hexdecimal or not it does not matter, they're in real the same value(but if you insist, you can use Decimal on the hex).

Mind showing the code you're having problem with? :)

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

hexdecimal or not it does not matter, they're in real the same value(but if you insist, you can use Decimal on the hex).

Mind showing the code you're having problem with? :party:

#include <WinAPI.au3>; Required for _WinAPI_OpenProcess
#include <Constants.au3>; Required for $PROCESS_ALL_ACCESS

Dim $iProcess = WinGetProcess("[CLASS:Knight OnLine Client]"); Should maybe use ProcessExists to get the ProcessID instead, as the .exe name is probably a little more reliable
If Not ProcessExists($iProcess) Then Exit(MsgBox(0, "Error", "Please launch the game first")); Make sure it's running before starting the script(you could wait for it to start up if you wanted however)

Dim $hProcess = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, False, $iProcess, False); Get the required handle to the process with access rights to be able to read/write, etc. from the process


Dim $hvProcess = $hProcess

Dim $avOffsets[2] = [0xCC, 0xA0]
Dim $BaseAddress = 0x008189a0


$PlayerHP = _ReadProcessPointers($hvProcess, $BaseAddress, $avOffsets)
MsgBox(0, "HP", $PlayerHP)


Func _ReadProcessPointers(ByRef $hvProcess, $ivBaseAddress, $avOffsets)
    If Not IsArray($avOffsets) Then Return _ReadProcessMemory($hvProcess, $ivBaseAddress, "ptr")+$avOffsets
    $ivBaseAddress = _ReadProcessMemory($hvProcess, $ivBaseAddress, "ptr")
    
    For $i = 0 To UBound($avOffsets)-1
    
    $ivBaseAddress = _ReadProcessMemory($hvProcess, $ivBaseAddress+$avOffsets[$i], "ptr")
    Next
    Return $ivBaseAddress
EndFunc

Func _ReadProcessMemory(ByRef $hProcess, $pBaseAddress, $svDataType = "dword")
    
    Local $stRead = DllStructCreate("int Read")
    Local $stData = DllStructCreate($svDataType)
    Local $aResult = DllCall("Kernel32.dll", "int", "ReadProcessMemory", "int", $hProcess, "int", $pBaseAddress, "ptr", DllStructGetPtr($stData), "int", DllStructGetSize($stData), "ptr", DllStructGetPtr($stRead))
    
    Return(SetError(Not $aResult[0], DllStructGetData($stRead, "Read"), DllStructGetData($stData, 1)))
EndFunc



Func _WriteProcessMemory($hProcess, $pBaseAddress, $bvData, $svDataType = "dword")
    Local $stWritten = DllStructCreate("int Written")
    Local $stData = DllStructCreate($svDataType)
    DllStructSetData($stData, 1, $bvData)
    
    Local $aResult = DllCall("Kernel32.dll", "int", "WriteProcessMemory", "int", $hProcess, "int", $pBaseAddress, "ptr", DllStructGetPtr($stData), "int", DllStructGetSize($stData), "int", DllStructGetPtr($stWritten))
    
    Return(SetError(Not $aResult[0], 0, DllStructGetData($stWritten, "Written")))
EndFunc

as i described i just want DMA adress in return from _ReadProcessPointers instead of value.

the script basicly is the same as u posted ur functions, i just got no idea how to modify it to get DMA adress. Then i want to send DMA adress as $pBaseAddress to _WriteProcessMemory. that's all :)

btw. i am just confused a bit with _ReadProcessPointers as im not sure where exactly the function changes DMA adress to value

Edited by zakoz

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

#include <WinAPI.au3>; Required for _WinAPI_OpenProcess
#include <Constants.au3>; Required for $PROCESS_ALL_ACCESS

Dim $iProcess = WinGetProcess("[CLASS:Knight OnLine Client]"); Should maybe use ProcessExists to get the ProcessID instead, as the .exe name is probably a little more reliable
If Not ProcessExists($iProcess) Then Exit(MsgBox(0, "Error", "Please launch the game first")); Make sure it's running before starting the script(you could wait for it to start up if you wanted however)

Dim $hProcess = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, False, $iProcess, False); Get the required handle to the process with access rights to be able to read/write, etc. from the process


Dim $hvProcess = $hProcess

Dim $avOffsets[2] = [0xCC, 0xA0]
Dim $BaseAddress = 0x008189a0


$PlayerHP = _ReadProcessPointers($hvProcess, $BaseAddress, $avOffsets)
MsgBox(0, "HP", $PlayerHP)


Func _ReadProcessPointers(ByRef $hvProcess, $ivBaseAddress, $avOffsets)
    If Not IsArray($avOffsets) Then Return _ReadProcessMemory($hvProcess, $ivBaseAddress+$avOffsets, "ptr")
    $ivBaseAddress = _ReadProcessMemory($hvProcess, $ivBaseAddress, "ptr")
    
    For $i = 0 To UBound($avOffsets)-1
    
    $ivBaseAddress = _ReadProcessMemory($hvProcess, $ivBaseAddress+$avOffsets[$i], "ptr")
    Next
    Return $ivBaseAddress
EndFunc

Func _ReadProcessMemory(ByRef $hProcess, $pBaseAddress, $svDataType = "dword")
    
    Local $stRead = DllStructCreate("int Read")
    Local $stData = DllStructCreate($svDataType)
    Local $aResult = DllCall("Kernel32.dll", "int", "ReadProcessMemory", "int", $hProcess, "int", $pBaseAddress, "ptr", DllStructGetPtr($stData), "int", DllStructGetSize($stData), "ptr", DllStructGetPtr($stRead))
    
    Return(SetError(Not $aResult[0], DllStructGetData($stRead, "Read"), DllStructGetData($stData, 1)))
EndFunc



Func _WriteProcessMemory($hProcess, $pBaseAddress, $bvData, $svDataType = "dword")
    Local $stWritten = DllStructCreate("int Written")
    Local $stData = DllStructCreate($svDataType)
    DllStructSetData($stData, 1, $bvData)
    
    Local $aResult = DllCall("Kernel32.dll", "int", "WriteProcessMemory", "int", $hProcess, "int", $pBaseAddress, "ptr", DllStructGetPtr($stData), "int", DllStructGetSize($stData), "int", DllStructGetPtr($stWritten))
    
    Return(SetError(Not $aResult[0], 0, DllStructGetData($stWritten, "Written")))
EndFunc

as i described i just want DMA adress in return from _ReadProcessPointers instead of value.

the script basicly is the same as u posted ur functions, i just got no idea how to modify it to get DMA adress. Then i want to send DMA adress as $pBaseAddress to _WriteProcessMemory. that's all :)

btw. i am just confused a bit with _ReadProcessPointers as im not sure where exactly the function changes DMA adress to value

_ReadProcessPointers returns the "DMA" address, so to get the value from it you need to use _ReadProcessMemory on the address that _ReadProcessPointers returns.

Also why have you changed the parameters of the read and write functions? They need not to be modified at all.

As long as the pointer you have is correct, and the offsets you gave in the first post is correct, this should work:

#include <WinAPI.au3>; Required for _WinAPI_OpenProcess
#include <Constants.au3>; Required for $PROCESS_ALL_ACCESS

Dim $iProcess = WinGetProcess("[CLASS:Knight OnLine Client]"); Should maybe use ProcessExists to get the ProcessID instead, as the .exe name is probably a little more reliable
If Not ProcessExists($iProcess) Then Exit(MsgBox(0, "Error", "Please launch the game first")); Make sure it's running before starting the script(you could wait for it to start up if you wanted however)

Dim $hProcess = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, False, $iProcess, False); Get the required handle to the process with access rights to be able to read/write, etc. from the process

Dim $HealthBasePointer = 0x008189a0
Dim $HealthBasePointerOffsets[2] = [0xCC, 0xA0]

$PlayerHPAddress = _ReadProcessPointers($hProcess, $HealthBasePointer, $HealthBasePointerOffsets); This gets the address where your health is stored - in other words not your health
$PlayerHP = _ReadProcessMemory($hProcess, $PlayerHPAddress, "dword")

MsgBox(0, "HP", $PlayerHP)

Func _ReadProcessPointers(ByRef $hvProcess, $ivBaseAddress, $avOffsets)
    If Not IsArray($avOffsets) Then Return _ReadProcessMemory($hvProcess, $ivBaseAddress, "ptr")+$avOffsets
    $ivBaseAddress = _ReadProcessMemory($hvProcess, $ivBaseAddress, "ptr")
    
    For $i = 0 To UBound($avOffsets)-1
        $ivBaseAddress = _ReadProcessMemory($hvProcess, $ivBaseAddress+$avOffsets[$i], "ptr")
    Next
    Return $ivBaseAddress
EndFunc

Func _WriteProcessMemory(ByRef $hvProcess, $ivAddress, $bvData, $svDataType = "byte")
    Local $stvWritten = DllStructCreate("int Written")
    Local $stvData = DllStructCreate($svDataType)
    DllStructSetData($stvData, 1, $bvData)
    Local $avResult = DllCall("Kernel32.dll", "int", "WriteProcessMemory", "int", $hvProcess, "int", $ivAddress, "ptr", DllStructGetPtr($stvData), "int", DllStructGetSize($stvData), "int", DllStructGetPtr($stvWritten))
    Return(SetError($avResult[0], 0, DllStructGetData($stvWritten, "Written")))
EndFunc

Func _ReadProcessMemory(ByRef $hvProcess, $ivAddress, $svDataType = "byte")
    Local $stvRead = DllStructCreate("int Read")
    Local $stvData = DllStructCreate($svDataType)
    Local $avResult = DllCall("Kernel32.dll", "int", "ReadProcessMemory", "int", $hvProcess, "int", $ivAddress, "ptr", DllStructGetPtr($stvData), "int", DllStructGetSize($stvData), "ptr", DllStructGetPtr($stvRead))
    Return(SetError(Not $avResult[0], DllStructGetData($stvRead, "Read"), DllStructGetData($stvData, 1)))
EndFunc
Edited by FreeFry

Share this post


Link to post
Share on other sites

_ReadProcessPointers returns the "DMA" address, so to get the value from it you need to use _ReadProcessMemory on the address that _ReadProcessPointers returns.

Also why have you changed the parameters of the read and write functions? They need not to be modified at all.

As long as the pointer you have is correct, and the offsets you gave in the first post is correct, this should work:

#include <WinAPI.au3>; Required for _WinAPI_OpenProcess
#include <Constants.au3>; Required for $PROCESS_ALL_ACCESS

Dim $iProcess = WinGetProcess("[CLASS:Knight OnLine Client]"); Should maybe use ProcessExists to get the ProcessID instead, as the .exe name is probably a little more reliable
If Not ProcessExists($iProcess) Then Exit(MsgBox(0, "Error", "Please launch the game first")); Make sure it's running before starting the script(you could wait for it to start up if you wanted however)

Dim $hProcess = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, False, $iProcess, False); Get the required handle to the process with access rights to be able to read/write, etc. from the process

Dim $HealthBasePointer = 0x008189a0
Dim $HealthBasePointerOffsets[2] = [0xCC, 0xA0]

$PlayerHPAddress = _ReadProcessPointers($hProcess, $HealthBasePointer, $HealthBasePointerOffsets); This gets the address where your health is stored - in other words not your health
$PlayerHP = _ReadProcessMemory($hProcess, $PlayerHPAddress, "dword")

MsgBox(0, "HP", $PlayerHP)

Func _ReadProcessPointers(ByRef $hvProcess, $ivBaseAddress, $avOffsets)
    If Not IsArray($avOffsets) Then Return _ReadProcessMemory($hvProcess, $ivBaseAddress, "ptr")+$avOffsets
    $ivBaseAddress = _ReadProcessMemory($hvProcess, $ivBaseAddress, "ptr")
    
    For $i = 0 To UBound($avOffsets)-1
        $ivBaseAddress = _ReadProcessMemory($hvProcess, $ivBaseAddress+$avOffsets[$i], "ptr")
    Next
    Return $ivBaseAddress
EndFunc

Func _WriteProcessMemory(ByRef $hvProcess, $ivAddress, $bvData, $svDataType = "byte")
    Local $stvWritten = DllStructCreate("int Written")
    Local $stvData = DllStructCreate($svDataType)
    DllStructSetData($stvData, 1, $bvData)
    Local $avResult = DllCall("Kernel32.dll", "int", "WriteProcessMemory", "int", $hvProcess, "int", $ivAddress, "ptr", DllStructGetPtr($stvData), "int", DllStructGetSize($stvData), "int", DllStructGetPtr($stvWritten))
    Return(SetError($avResult[0], 0, DllStructGetData($stvWritten, "Written")))
EndFunc

Func _ReadProcessMemory(ByRef $hvProcess, $ivAddress, $svDataType = "byte")
    Local $stvRead = DllStructCreate("int Read")
    Local $stvData = DllStructCreate($svDataType)
    Local $avResult = DllCall("Kernel32.dll", "int", "ReadProcessMemory", "int", $hvProcess, "int", $ivAddress, "ptr", DllStructGetPtr($stvData), "int", DllStructGetSize($stvData), "ptr", DllStructGetPtr($stvRead))
    Return(SetError(Not $avResult[0], DllStructGetData($stvRead, "Read"), DllStructGetData($stvData, 1)))
EndFunc
something is wrong, $playerhp returns 0 and $PlayerhpAddress returns value

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

i found remedy, script from another forum, thanks to syron198 which made it. its more simple than i though, it uses nomadmemory UDF tho

Func _FindNewAddress($Pointer, $Offset)
    Return '0x' & Hex(_MemoryRead($Pointer,$DllInfo1) + $Offset, 8)

EndFunc

where the $pointer is a base address, $dllinfo1 = _MemoryOpen($ProcessID) and $offset is of course an offset. since its not a loop it does't use array of offsets but its easy to add i guess.

since i don't have so much time right now i've made it like this

$ah_handle = _MemoryOpen($ProcessID)
    
    $first = _FindNewAddress($GamePointer, $INNofs)
    $first2 = _FindNewAddress($first, $INNofs2)
   
    $Value = _MemoryWrite($first2, $ah_handle, 1)
   
    _MemoryClose($ah_handle)

and now everything works just fine :)

Edited by zakoz

Share this post


Link to post
Share on other sites

i found remedy, script from another forum, thanks to syron198 which made it. its more simple than i though, it uses nomadmemory UDF tho

Func _FindNewAddress($Pointer, $Offset)
    Return '0x' & Hex(_MemoryRead($Pointer,$DllInfo1) + $Offset, 8)

EndFunc

where the $pointer is a base address, $dllinfo1 = _MemoryOpen($ProcessID) and $offset is of course an offset. since its not a loop it does't use array of offsets but its easy to add i guess.

since i don't have so much time right now i've made it like this

$ah_handle = _MemoryOpen($ProcessID)
    
    $first = _FindNewAddress($GamePointer, $INNofs)
    $first2 = _FindNewAddress($first, $INNofs2)
   
    $Value = _MemoryWrite($first2, $ah_handle, 1)
   
    _MemoryClose($ah_handle)

and now everything works just fine :)

That's exactly what my _ReadProcessPointers function is doing...

If it's giving you a value, then you where using it wrong(the last offset is perhaps the offset to the DMA address, not an offset to a pointer).

If you want, you could try this and see if it works expectedly:

#include <WinAPI.au3>; Required for _WinAPI_OpenProcess
#include <Constants.au3>; Required for $PROCESS_ALL_ACCESS

Dim $iProcess = WinGetProcess("[CLASS:Knight OnLine Client]"); Should maybe use ProcessExists to get the ProcessID instead, as the .exe name is probably a little more reliable
If Not ProcessExists($iProcess) Then Exit(MsgBox(0, "Error", "Please launch the game first")); Make sure it's running before starting the script(you could wait for it to start up if you wanted however)

Dim $hProcess = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, False, $iProcess, False); Get the required handle to the process with access rights to be able to read/write, etc. from the process

Dim $HealthBasePointer = 0x008189a0
Dim $HealthBasePointerOffset = 0xCC

$PlayerHPAddress = _ReadProcessPointers($hProcess, $HealthBasePointer, $HealthBasePointerOffset)+0xA0; Read from the pointer+offset, then add the last offset which should point to the correct address
$PlayerHP = _ReadProcessMemory($hProcess, $PlayerHPAddress, "dword")

MsgBox(0, "HP", $PlayerHP)

Func _ReadProcessPointers(ByRef $hvProcess, $ivBaseAddress, $avOffsets)
    If Not IsArray($avOffsets) Then Return _ReadProcessMemory($hvProcess, $ivBaseAddress+$avOffsets, "ptr")
    $ivBaseAddress = _ReadProcessMemory($hvProcess, $ivBaseAddress, "ptr")
    
    For $i = 0 To UBound($avOffsets)-1
        $ivBaseAddress = _ReadProcessMemory($hvProcess, $ivBaseAddress+$avOffsets[$i], "ptr")
    Next
    Return $ivBaseAddress
EndFunc

Func _WriteProcessMemory(ByRef $hvProcess, $ivAddress, $bvData, $svDataType = "byte")
    Local $stvWritten = DllStructCreate("int Written")
    Local $stvData = DllStructCreate($svDataType)
    DllStructSetData($stvData, 1, $bvData)
    Local $avResult = DllCall("Kernel32.dll", "int", "WriteProcessMemory", "int", $hvProcess, "int", $ivAddress, "ptr", DllStructGetPtr($stvData), "int", DllStructGetSize($stvData), "int", DllStructGetPtr($stvWritten))
    Return(SetError($avResult[0], 0, DllStructGetData($stvWritten, "Written")))
EndFunc

Func _ReadProcessMemory(ByRef $hvProcess, $ivAddress, $svDataType = "byte")
    Local $stvRead = DllStructCreate("int Read")
    Local $stvData = DllStructCreate($svDataType)
    Local $avResult = DllCall("Kernel32.dll", "int", "ReadProcessMemory", "int", $hvProcess, "int", $ivAddress, "ptr", DllStructGetPtr($stvData), "int", DllStructGetSize($stvData), "ptr", DllStructGetPtr($stvRead))
    Return(SetError(Not $avResult[0], DllStructGetData($stvRead, "Read"), DllStructGetData($stvData, 1)))
EndFunc

This is a snippet out of a bot I've made, which uses my function to get the pointer address that points to the position of my character in the game:

Dim $aPlayerPosAddr[4] = [0x0481922c, 0x88, 0x8c, 0x90]; First element is the address of my pointer, the rest are offsets to the values

Func _GetPlayerPosition()
    Local $avRet[3]
    Local $ivBaseAddress = _ReadProcessPointers($hProcess, $aPlayerPosAddr[0], 0); Gets the address the pointer is pointing to(0 as offset as i want the address not the 'value' i'm looking for)
    
    $avRet[0] = _ReadProcessMemory($hProcess, $ivBaseAddress+$aPlayerPosAddr[1], "float"); Read from that pointer+first offset(which points to the X position in the world)
    $avRet[1] = _ReadProcessMemory($hProcess, $ivBaseAddress+$aPlayerPosAddr[2], "float"); Read from that pointer+second offset(which points to the Y position in the world)
    $avRet[2] = _ReadProcessMemory($hProcess, $ivBaseAddress+$aPlayerPosAddr[3], "float"); Read from that pointer+third offset(which points to the Z position in the world)
    Return $avRet
EndFunc

Share this post


Link to post
Share on other sites

#18 ·  Posted (edited)

That's exactly what my _ReadProcessPointers function is doing...

If it's giving you a value, then you where using it wrong(the last offset is perhaps the offset to the DMA address, not an offset to a pointer).

If you want, you could try this and see if it works expectedly:

#include <WinAPI.au3>; Required for _WinAPI_OpenProcess
#include <Constants.au3>; Required for $PROCESS_ALL_ACCESS

Dim $iProcess = WinGetProcess("[CLASS:Knight OnLine Client]"); Should maybe use ProcessExists to get the ProcessID instead, as the .exe name is probably a little more reliable
If Not ProcessExists($iProcess) Then Exit(MsgBox(0, "Error", "Please launch the game first")); Make sure it's running before starting the script(you could wait for it to start up if you wanted however)

Dim $hProcess = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, False, $iProcess, False); Get the required handle to the process with access rights to be able to read/write, etc. from the process

Dim $HealthBasePointer = 0x008189a0
Dim $HealthBasePointerOffset = 0xCC

$PlayerHPAddress = _ReadProcessPointers($hProcess, $HealthBasePointer, $HealthBasePointerOffset)+0xA0; Read from the pointer+offset, then add the last offset which should point to the correct address
$PlayerHP = _ReadProcessMemory($hProcess, $PlayerHPAddress, "dword")

MsgBox(0, "HP", $PlayerHP)

Func _ReadProcessPointers(ByRef $hvProcess, $ivBaseAddress, $avOffsets)
    If Not IsArray($avOffsets) Then Return _ReadProcessMemory($hvProcess, $ivBaseAddress+$avOffsets, "ptr")
    $ivBaseAddress = _ReadProcessMemory($hvProcess, $ivBaseAddress, "ptr")
    
    For $i = 0 To UBound($avOffsets)-1
        $ivBaseAddress = _ReadProcessMemory($hvProcess, $ivBaseAddress+$avOffsets[$i], "ptr")
    Next
    Return $ivBaseAddress
EndFunc

Func _WriteProcessMemory(ByRef $hvProcess, $ivAddress, $bvData, $svDataType = "byte")
    Local $stvWritten = DllStructCreate("int Written")
    Local $stvData = DllStructCreate($svDataType)
    DllStructSetData($stvData, 1, $bvData)
    Local $avResult = DllCall("Kernel32.dll", "int", "WriteProcessMemory", "int", $hvProcess, "int", $ivAddress, "ptr", DllStructGetPtr($stvData), "int", DllStructGetSize($stvData), "int", DllStructGetPtr($stvWritten))
    Return(SetError($avResult[0], 0, DllStructGetData($stvWritten, "Written")))
EndFunc

Func _ReadProcessMemory(ByRef $hvProcess, $ivAddress, $svDataType = "byte")
    Local $stvRead = DllStructCreate("int Read")
    Local $stvData = DllStructCreate($svDataType)
    Local $avResult = DllCall("Kernel32.dll", "int", "ReadProcessMemory", "int", $hvProcess, "int", $ivAddress, "ptr", DllStructGetPtr($stvData), "int", DllStructGetSize($stvData), "ptr", DllStructGetPtr($stvRead))
    Return(SetError(Not $avResult[0], DllStructGetData($stvRead, "Read"), DllStructGetData($stvData, 1)))
EndFunc

this is what i get from ur script Posted Image

and this if i change the msg box variable to $PlayerHPAddress

Posted Image

so, definitely there is something wrong with this script. try for yourself with your pointers/offsets.

anyway i've got new questions

can i send data to inputbox? (i know its an INPUT box but i couldn't find any other area to show a data, except tooltips and msg)

another thing - GUICtrlSetState(-1, $GUI_HIDE) and $GUI_SHOW seems to be bugged, if inputbox is hided since start, this function would show inputbox only once, if i check and uncheck and then check checkbox again, inputbox will stay invisible.

Case $msg = $merch

If BitAnd(GUICtrlRead($merch),$GUI_CHECKED) Then

$Input1 = GUICtrlSetState($input1, $GUI_SHOW)

endif

If BitAnd(GUICtrlRead($merch),$GUI_UNCHECKED) Then

$Input1 = GUICtrlSetState($input1, $GUI_HIDE)

endif

; the $merch is a checkbox and $input1 is a inputbox

also have u got any idea if i could manipulate (i.e. send hotkeyset to a script) from fullscreen game window? Edited by zakoz

Share this post


Link to post
Share on other sites

this is what i get from ur script Posted Image

and this if i change the msg box variable to $PlayerHPAddress

Posted Image

so, definitely there is something wrong with this script. try for yourself with your pointers/offsets.

anyway i've got new questions

can i send data to inputbox? (i know its an INPUT box but i couldn't find any other area to show a data, except tooltips and msg)

another thing - GUICtrlSetState(-1, $GUI_HIDE) and $GUI_SHOW seems to be bugged, if inputbox is hided since start, this function would show inputbox only once, if i check and uncheck and then check checkbox again, inputbox will stay invisible.

also have u got any idea if i could manipulate (i.e. send hotkeyset to a script) from fullscreen game window?

Hey man,

Sorry I just now got your PM. I've been to busy in IRL to pop on here much.

If you still need help with something specific please PM the script and where it errors out=) Not sure what's fixed after 2 pages of posts.

Just skimming the thread,

Get the latest NomadMemory

Get the _memorypointerread/write

Get my baseaddress UDF.

Make sure you're reading the proper data type.

The return values of some functions are array's, make sure you aren't forgetting [0]...

Szh

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0