Sign in to follow this  
Followers 0
Tec

_MemoryPointerRead understanding

35 posts in this topic

Sorry if this is a stupid question. I still learning und try to understand how does it work.

I make the Tutorial from Cheat Engine 5.5. At step 8 you need to find the Multilevel pointer. See the Screenshot.

I try to read this with autoit and NomadMemory.au3 but i think i dont understand it. The error i think is the offset what i did not understand.

I read all post that i found here but my english and grammar is not perfect and the theme is new for me.

If someone can help me and correct my code so i can see my mistake, that would help a lot.

Posted Image

#include <NomadMemory.au3>
SetPrivilege("SeDebugPrivilege", 1)

$pid = ProcessExists("Tutorial.exe") ;Step 8: Multilevel pointers: (PW=525927)

Global $Offset1[5]
$Offset1[0] = 0 ; Is ALWAYS 0.
$Offset1[1] = Dec("18")
$Offset1[2] = Dec("0")
$Offset1[3] = Dec("14")
$Offset1[4] = Dec("C")

$StaticOffset = Dec("60C20")

$openmem = _MemoryOpen($pid) ; Open the memory
$baseADDR = _MemoryGetBaseAddress($openmem, 1) 
$finalADDR = "0x" & Hex($baseADDR + $StaticOffset) ; Creates the final static address you read from.
    ConsoleWrite (  $finalADDR  & @CRLF) 
$Value = _MemoryPointerRead($finalADDR, $openmem, $Offset1)
_MemoryClose($openmem)
    ConsoleWrite ( "Address = " & $Value[0] & @CRLF & "Value = " & $Value[1] & @CRLF)

Output :

0x00460C20
Address = 0x000060FC
Value = 0

Thanks for help

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

#include <NomadMemory.au3>
SetPrivilege("SeDebugPrivilege", 1)

$pid = ProcessExists("Tutorial.exe") ;Step 8: Multilevel pointers: (PW=525927)

Global $Offset1[5]
$Offset1[0] = 0 ; Is ALWAYS 0.
$Offset1[1] = Dec("c")
$Offset1[2] = Dec("14")
$Offset1[3] = Dec("0")
$Offset1[4] = Dec("18")

$StaticOffset = Dec("60c20")

$openmem = _MemoryOpen($pid) ; Open the memory
$baseADDR = _MemoryGetBaseAddress($openmem, 1)
$finalADDR = "0x" & Hex($baseADDR + $StaticOffset) ; Creates the final static address you read from.
$Value = _MemoryPointerRead($finalADDR, $openmem, $Offset1)
_MemoryClose($openmem)
    ConsoleWrite ( "Address = " & $Value[0] & @CRLF & "Value = " & $Value[1] & @CRLF)

Don't forget that the last row is the top level pointer.

Edited by Authenticity

Share this post


Link to post
Share on other sites

where abouts do u put in the value u want it to turn into? and how would u freeze the value?

#include <NomadMemory.au3>
SetPrivilege("SeDebugPrivilege", 1)

$pid = ProcessExists("Tutorial.exe") ;Step 8: Multilevel pointers: (PW=525927)

Global $Offset1[5]
$Offset1[0] = 0 ; Is ALWAYS 0.
$Offset1[1] = Dec("c")
$Offset1[2] = Dec("14")
$Offset1[3] = Dec("0")
$Offset1[4] = Dec("18")

$StaticOffset = Dec("60c20")

$openmem = _MemoryOpen($pid) ; Open the memory
$baseADDR = _MemoryGetBaseAddress($openmem, 1)
$finalADDR = "0x" & Hex($baseADDR + $StaticOffset) ; Creates the final static address you read from.
$Value = _MemoryPointerRead($finalADDR, $openmem, $Offset1)
_MemoryClose($openmem)
    ConsoleWrite ( "Address = " & $Value[0] & @CRLF & "Value = " & $Value[1] & @CRLF)

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Try VirtualQueryEx VirtualProtectEx API function. I don't know if this is how CE achieve memory freeze but I guess that it's lower-level than that.

Edit: As for your first question, I think you should remove the last element from the array, read the value from the array using _MemoryPointerRead(), you'll get the last address to pointers point to, add the last offset you've removed from the array to the value read from _MemoryPointerRead() adn it should be the last address, not tested.

Edited by Authenticity

Share this post


Link to post
Share on other sites

i dont understand how 2 do that can u please show me how u mean?

Share this post


Link to post
Share on other sites

i dont understand how 2 do that can u please show me how u mean?

You were close man. Just had the offsets in the wrong order=)

BTW... It's been a while since I manually added pointers. Why was it adding the 'new pointer' at the top of my list? Was quite annoying because I had to shift the addresses down each time.

#include <NomadMemory.au3>
SetPrivilege("SeDebugPrivilege", 1)

$pid = ProcessExists("Tutorial.exe") ;Step 8: Multilevel pointers: (PW=525927)

Global $Offset1[5]
$Offset1[0] = 0 ; Is ALWAYS 0.
$Offset1[1] = Dec("C") ; Stattic ADDR offset
$Offset1[2] = Dec("14")
$Offset1[3] = Dec("0")
$Offset1[4] = Dec("18")

$StaticOffset = Dec("60C20")

$openmem = _MemoryOpen($pid) ; Open the memory
$baseADDR = _MemoryGetBaseAddress($openmem, 1) 
$finalADDR = "0x" & Hex($baseADDR + $StaticOffset) ; Creates the final static address you read from.
ConsoleWrite (  $finalADDR  & @CRLF) 
$Value = _MemoryPointerRead($finalADDR, $openmem, $Offset1)
_MemoryClose($openmem)
ConsoleWrite ( "Address = " & $Value[0] & @CRLF & "Value = " & $Value[1] & @CRLF)

Share this post


Link to post
Share on other sites

i dont understand how 2 do that can u please show me how u mean?

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Maybe you got the the version that the _MemoryReadPointer() is defined incorrectly. Search the example forum, you'll find the one that works. Funny challenge >_<

#include <MemoryConstants.au3>
#include <NomadMemory.au3>
SetPrivilege("SeDebugPrivilege", 1)
HotKeySet('{ESC}', '_TerminateLoop')

$pid = ProcessExists("Tutorial.exe") ;Step 8: Multilevel pointers: (PW=525927)

Global $fLoop = True
Global $Offset1[5]
$Offset1[0] = 0 ; Is ALWAYS 0.
$Offset1[1] = Dec("c")
$Offset1[2] = Dec("14")
$Offset1[3] = Dec("0")
$Offset1[4] = Dec("18")

$StaticOffset = Dec("60c20")

$openmem = _MemoryOpen($pid) ; Open the memory
$baseADDR = _MemoryGetBaseAddress($openmem, 1)
$finalADDR = "0x" & Hex($baseADDR + $StaticOffset) ; Creates the final static address you read from.

$Value = _MemoryPointerRead($finalADDR, $openmem, $Offset1)
ConsoleWrite ( "Address = " & $Value[0] & @CRLF & "Value = " & $Value[1] & @CRLF)

; Click change pointer and press Esc before 3 seconds passes away. :)
While $fLoop
    Sleep(10)
WEnd

$Value = _MemoryPointerRead($finalADDR, $openmem, $Offset1)
ConsoleWrite ( "Address = " & $Value[0] & @CRLF & "Value = " & $Value[1] & @CRLF)
_MemoryWrite($Value[0], $openmem, 5000)
_MemoryClose($openmem)


Func _TerminateLoop()
    $fLoop = False
EndFunc

Edit: Meh, can't seem to find it, try this one:

;=================================================================================================
; Function:   _MemoryPointerRead ($iv_Address, $ah_Handle, $av_Offset[, $sv_Type])
; Description:    Reads a chain of pointers and returns an array containing the destination
;               address and the data at the address.
; Parameter(s):  $iv_Address - The static memory address you want to start at. It must be 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.  Each pointer must have an
;                         offset.  If there is no offset for a pointer, enter 0 for that
;                         array dimension.
;               $sv_Type - (optional) The "Type" of data you intend to read at the destination
;                         address.  This is set to 'dword'(32bit(4byte) signed integer) by
;                         default.  See the help file for DllStructCreate for all types.
; Requirement(s):   The $ah_Handle returned from _MemoryOpen.
; Return Value(s):  On Success - Returns an array containing the destination address and the value
;                         located at the address.
;               On Failure - Returns 0
;               @Error - 0 = No error.
;                      1 = $av_Offset is not an array.
;                      2 = Invalid $ah_Handle.
;                      3 = $sv_Type is not a string.
;                      4 = $sv_Type is an unknown data type.
;                      5 = Failed to allocate the memory needed for the DllStructure.
;                      6 = Error allocating memory for $sv_Type.
;                      7 = Failed to read from the specified process.
; Author(s):        Nomad
; Note(s):      Values returned are in Decimal format, unless a 'char' type is selected.
;               Set $av_Offset like this:
;               $av_Offset[0] = NULL (not used)
;               $av_Offset[1] = Offset for pointer 1 (all offsets must be in Decimal)
;               $av_Offset[2] = Offset for pointer 2
;               etc...
;               (The number of array dimensions determines the number of pointers)
;=================================================================================================
Func _MemoryPointerRead($iv_Address, $ah_Handle, $av_Offset, $sv_Type = 'dword')
   
    If IsArray($av_Offset) Then
        If IsArray($ah_Handle) Then
            Local $iv_PointerCount = UBound($av_Offset) - 1
        Else
            SetError(2)
            Return 0
        EndIf
    Else
        SetError(1)
        Return 0
    EndIf
   
    Local $iv_Data[2], $i
    Local $v_Buffer = DllStructCreate('dword')
   
    For $i = 0 To $iv_PointerCount
       
        If $i = $iv_PointerCount Then
            $v_Buffer = DllStructCreate($sv_Type)
            If @error Then
                SetError(@error + 2)
                Return 0
            EndIf
           
            $iv_Address = '0x' & Hex($iv_Data[1] + $av_Offset[$i])
            DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
            If @error Then
                SetError(7)
                Return 0
            EndIf
           
            $iv_Data[1] = DllStructGetData($v_Buffer, 1)
           
        ElseIf $i = 0 Then
            DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
            If @error Then
                SetError(7)
                Return 0
            EndIf
           
            $iv_Data[1] = DllStructGetData($v_Buffer, 1)
           
        Else
            $iv_Address = '0x' & Hex($iv_Data[1] + $av_Offset[$i])
            DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
            If @error Then
                SetError(7)
                Return 0
            EndIf
           
            $iv_Data[1] = DllStructGetData($v_Buffer, 1)
           
        EndIf
       
    Next
   
    $iv_Data[0] = $iv_Address
   
    Return $iv_Data

EndFunc   ;==>_MemoryPointerRead
Edited by Authenticity

Share this post


Link to post
Share on other sites

when trying to run that i keep getting error line 19

$baseADDR = _MemoryGetBaseAddress($openmem,1)

$baseADDR = ^ Error

Error: Unknown function name.

can some 1 please help me?

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Update your NomadMemory with the following function, it should be on the Example forum but I can't find it:

;===================================================================================================

; Function........:  _MemoryGetBaseAddress($ah_Handle, $iHD)
;
; Description.....:  Reads the 'Allocation Base' from the open process.
;
; Parameter(s)....:  $ah_Handle - An array containing the Dll handle and the handle of the open
;                               process as returned by _MemoryOpen().
;                    $iHD - Return type:
;                       |0 = Hex (Default)
;                       |1 = Dec
;
; Requirement(s)..:  A valid process ID.
;
; Return Value(s).:  On Success - Returns the 'allocation Base' address and sets @Error to 0.
;                    On Failure - Returns 0 and sets @Error to:
;                  |1 = Invalid $ah_Handle.
;                  |2 = Failed to find correct allocation address.
;                  |3 = Failed to read from the specified process.
;
; Author(s).......:  Nomad. Szhlopp.
; URL.............:  http://www.autoitscript.com/forum/index.php?showtopic=78834
; Note(s).........:  Go to Www.CheatEngine.org for the latest version of CheatEngine.
;===================================================================================================

Func _MemoryGetBaseAddress($ah_Handle, $iHexDec = 0)
   
    Local $iv_Address = 0x00100000
    Local $v_Buffer = DllStructCreate('dword;dword;dword;dword;dword;dword;dword')
    Local $vData
    Local $vType
   
    If Not IsArray($ah_Handle) Then
        SetError(1)
        Return 0
    EndIf
   

    DllCall($ah_Handle[0], 'int', 'VirtualQueryEx', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer))
   
    If Not @Error Then
       
        $vData = Hex(DllStructGetData($v_Buffer, 2))
        $vType = Hex(DllStructGetData($v_Buffer, 3))
       
        While $vType <> "00000080"
            DllCall($ah_Handle[0], 'int', 'VirtualQueryEx', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer))
            $vData = Hex(DllStructGetData($v_Buffer, 2))
            $vType = Hex(DllStructGetData($v_Buffer, 3))
            If Hex($iv_Address) = "01000000" Then ExitLoop
            $iv_Address += 65536
           
        WEnd

        If $vType = "00000080" Then
            SetError(0)
            If $iHexDec = 1 Then
                Return Dec($vData)
            Else
                Return $vData
            EndIf
           
        Else
            SetError(2)
            Return 0
        EndIf
       
    Else
        SetError(3)
        Return 0
    EndIf
   
EndFunc   ;==>_MemoryGetBaseAddress

Edit: Sorry, used the wrong function.

Edited by Authenticity

Share this post


Link to post
Share on other sites

i updated it with what u said but now i get another error on line 3

SetPrivilege("SeDebugPrivilege", 1)

unknown function name

Share this post


Link to post
Share on other sites

I've attached the full NomadMemory.au3 that I have, the NomadMemory.au3's topic in the example forum is not linked and the content is garbage near the end.

NomadMemory.au3

Share this post


Link to post
Share on other sites

ok thanks but now since i updated that another error >_< line 23

ConsoleWrite ( "Address = " & $Value[0] & @CRLF & "Value = " & $Value[1] & @CRLF)

ConsoleWrite ( "Address = " & $Value^ERROR

Error: Subscript used with non-Array variable

what dose that mean?

Share this post


Link to post
Share on other sites

Can use post the script source? Make sure you check whether the function succeeded and that the return type is indeed an array type, and that the element you're requesting is fitting within the array boundaries, using IsArray() and UBound() functions.

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

i was just trying to open this code that we have posted was trying to get it to work with the cheat engine tut

there no point trying to get it to work with a game if i cant even get it to work with the tut program

#include <MemoryConstants.au3>
#include <NomadMemory.au3>
SetPrivilege("SeDebugPrivilege", 1)
HotKeySet('{ESC}', '_TerminateLoop')

$pid = ProcessExists("Tutorial.exe") ;Step 8: Multilevel pointers: (PW=525927)

Global $fLoop = True
Global $Offset1[5]
$Offset1[0] = 0 ; Is ALWAYS 0.
$Offset1[1] = Dec("c")
$Offset1[2] = Dec("14")
$Offset1[3] = Dec("0")
$Offset1[4] = Dec("18")

$StaticOffset = Dec("60c20")

$openmem = _MemoryOpen($pid) ; Open the memory
$baseADDR = _MemoryGetBaseAddress($openmem, 1)
$finalADDR = "0x" & Hex($baseADDR + $StaticOffset) ; Creates the final static address you read from.

$Value = _MemoryPointerRead($finalADDR, $openmem, $Offset1)
ConsoleWrite ( "Address = " & $Value[0] & @CRLF & "Value = " & $Value[1] & @CRLF)

; Click change pointer and press Esc before 3 seconds passes away. :)
While $fLoop
    Sleep(10)
WEnd

$Value = _MemoryPointerRead($finalADDR, $openmem, $Offset1)
ConsoleWrite ( "Address = " & $Value[0] & @CRLF & "Value = " & $Value[1] & @CRLF)
_MemoryWrite($Value[0], $openmem, 5000)
_MemoryClose($openmem)


Func _TerminateLoop()
    $fLoop = False
EndFunc
Edited by hot202

Share this post


Link to post
Share on other sites

Works for me, if somehow your tutorial executable's image name is not Tutorial.exe you should change the line that gets it's process ID. Just execute the Tutorial.exe file, go to Tutorial 8 using the code posted in the source, run the script, click Change Pointer, hit Escapce and after 3 seconds the Next button should be enabled.

Share this post


Link to post
Share on other sites

Posted Image

that is what i get as soon as i run the script.

Share this post


Link to post
Share on other sites

Can you run this simple script and post the number you see in the dialog box?

#RequireAdmin
$pid = ProcessExists("Tutorial.exe") ;Step 8: Multilevel pointers: (PW=525927)
MsgBox(0x40, 'Process Identifier', $pid)

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

yeah just did that i got a 0 what dose that mean im not admin or something? i should be admin

wait am i ment to run that with the tut open?

with the tut open i get 2768

Edited by hot202

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