Jump to content

Help with _Memory


Recommended Posts

Then simply go through his code yourself. That is usually the best way to understand something, reverse engineering. Take the code apart mentally and figure out what each bit does then you'll understand its usage.

I have read through his code many times, before even posting on this forum.

I still seem to be at a standstill though. Always returns 0

Link to comment
Share on other sites

  • Replies 43
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Have you tried treating the result as an array? It may be one so simply try something like

MsgBox(64,"Test",$array[1])
where $array is the name of your variable.

Link to comment
Share on other sites

I have read through his code many times, before even posting on this forum.

I still seem to be at a standstill though. Always returns 0

Here's the copy of Nomad's Memory that I am trying to work with, also tried W0uters _Mem with same results.

#include-once
#region _Memory
;==================================================================================
; AutoIt Version:   3.1.127 (beta)
; Language:         English
; Platform:         All Windows
; Author:           Nomad
; Requirements:     These functions will only work with beta.
;==================================================================================
; Credits:  wOuter - These functions are based on his original _Mem() functions.
;           But they are easier to comprehend and more reliable.  These
;           functions are in no way a direct copy of his functions.  His
;           functions only provided a foundation from which these evolved.
;==================================================================================
;
; Functions:
;
;==================================================================================
; Function:         _MemoryOpen($iv_Pid[, $iv_DesiredAccess[, $iv_InheritHandle]])
; Description:      Opens a process and enables all possible access rights to the
;                   process.  The Process ID of the process is used to specify which
;                   process to open.  You must call this function before calling
;                   _MemoryClose(), _MemoryRead(), or _MemoryWrite().
; Parameter(s):     $iv_Pid - The Process ID of the program you want to open.
;                   $iv_DesiredAccess - (optional) Set to 0x1F0FFF by default, which
;                                       enables all possible access rights to the
;                                       process specified by the Process ID.
;                   $iv_InheritHandle - (optional) If this value is TRUE, all processes
;                                       created by this process will inherit the access
;                                       handle.  Set to 1 (TRUE) by default.  Set to 0
;                                       if you want it FALSE.
; Requirement(s):   None.
; Return Value(s):  On Success - Returns an array containing the Dll handle and an
;                                open handle to the specified process.
;                   On Failure - Returns 0
;                   @Error - 0 = No error.
;                            1 = Invalid $iv_Pid.
;                            2 = Failed to open Kernel32.dll.
;                            3 = Failed to open the specified process.
; Author(s):        Nomad
; Note(s):
;==================================================================================
Func _MemoryOpen($iv_Pid, $iv_DesiredAccess = 0x1F0FFF, $iv_InheritHandle = 1)
    
    If Not ProcessExists($iv_Pid) Then
        SetError(1)
        Return 0
    EndIf
    
    Local $ah_Handle[2] = [DllOpen('kernel32.dll')]
    
    If @Error Then
        SetError(2)
        Return 0
    EndIf
    
    Local $av_OpenProcess = DllCall($ah_Handle[0], 'int', 'OpenProcess', 'int', $iv_DesiredAccess, 'int', $iv_InheritHandle, 'int', $iv_Pid)
    
    If @Error Then
        DllClose($ah_Handle[0])
        SetError(3)
        Return 0
    EndIf
    
    $ah_Handle[1] = $av_OpenProcess[0]
    
    Return $ah_Handle
    
EndFunc

;==================================================================================
; Function:         _MemoryRead($iv_Address, $ah_Handle[, $sv_Type])
; Description:      Reads the value located in the memory address specified.
; Parameter(s):     $iv_Address - The memory address you want to read from. 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().
;                   $sv_Type - (optional) The "Type" of value you intend to read.
;                               This is set to 'dword'(32bit(4byte) signed integer)
;                               by default.  See the help file for DllStructCreate
;                               for all types.  An example: If you want to read a
;                               word that is 15 characters in length, you would use
;                               'char[16]' since a 'char' is 8 bits (1 byte) in size.
; Return Value(s):  On Success - Returns the value located at the specified address.
;                   On Failure - Returns 0
;                   @Error - 0 = No error.
;                            1 = Invalid $ah_Handle.
;                            2 = $sv_Type was not a string.
;                            3 = $sv_Type is an unknown data type.
;                            4 = Failed to allocate the memory needed for the DllStructure.
;                            5 = Error allocating memory for $sv_Type.
;                            6 = Failed to read from the specified process.
; Author(s):        Nomad
; Note(s):          Values returned are in Decimal format, unless specified as a
;                   'char' type, then they are returned in ASCII format.  Also note
;                   that size ('char[size]') for all 'char' types should be 1
;                   greater than the actual size.
;==================================================================================
Func _MemoryRead($iv_Address, $ah_Handle, $sv_Type = 'dword')
    
    If Not IsArray($ah_Handle) Then
        SetError(1)
        Return 0
    EndIf
    
    Local $v_Buffer = DllStructCreate($sv_Type)
    
    If @Error Then
        SetError(@Error + 1)
        Return 0
    EndIf
    
    DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
    
    If Not @Error Then
        Local $v_Value = DllStructGetData($v_Buffer, 1)
        Return $v_Value
    Else
        SetError(6)
        Return 0
    EndIf
    
EndFunc

;==================================================================================
; Function:         _MemoryWrite($iv_Address, $ah_Handle, $v_Data[, $sv_Type])
; Description:      Writes data to the specified memory address.
; Parameter(s):     $iv_Address - The memory address which you want to write to.
;                                 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().
;                   $v_Data - The data to be written.
;                   $sv_Type - (optional) The "Type" of value you intend to write.
;                               This is set to 'dword'(32bit(4byte) signed integer)
;                               by default.  See the help file for DllStructCreate
;                               for all types.  An example: If you want to write a
;                               word that is 15 characters in length, you would use
;                               'char[16]' since a 'char' is 8 bits (1 byte) in size.
; Return Value(s):  On Success - Returns 1
;                   On Failure - Returns 0
;                   @Error - 0 = No error.
;                            1 = Invalid $ah_Handle.
;                            2 = $sv_Type was not a string.
;                            3 = $sv_Type is an unknown data type.
;                            4 = Failed to allocate the memory needed for the DllStructure.
;                            5 = Error allocating memory for $sv_Type.
;                            6 = $v_Data is not in the proper format to be used with the
;                                "Type" selected for $sv_Type, or it is out of range.
;                            7 = Failed to write to the specified process.
; Author(s):        Nomad
; Note(s):          Values sent must be in Decimal format, unless specified as a
;                   'char' type, then they must be in ASCII format.  Also note
;                   that size ('char[size]') for all 'char' types should be 1
;                   greater than the actual size.
;==================================================================================
Func _MemoryWrite($iv_Address, $ah_Handle, $v_Data, $sv_Type = 'dword')
    
    If Not IsArray($ah_Handle) Then
        SetError(1)
        Return 0
    EndIf
    
    Local $v_Buffer = DllStructCreate($sv_Type)
    
    If @Error Then
        SetError(@Error + 1)
        Return 0
    Else
        DllStructSetData($v_Buffer, 1, $v_Data)
        If @Error Then
            SetError(6)
            Return 0
        EndIf
    EndIf
    
    DllCall($ah_Handle[0], 'int', 'WriteProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
    
    If Not @Error Then
        Return 1
    Else
        SetError(7)
        Return 0
    EndIf
    
EndFunc

;==================================================================================
; Function:         _MemoryClose($ah_Handle)
; Description:      Closes the process handle opened by using _MemoryOpen().
; Parameter(s):     $ah_Handle - An array containing the Dll handle and the handle
;                                of the open process as returned by _MemoryOpen().
; Return Value(s):  On Success - Returns 1
;                   On Failure - Returns 0
;                   @Error - 0 = No error.
;                            1 = Invalid $ah_Handle.
;                            2 = Unable to close the process handle.
; Author(s):        Nomad
; Note(s):
;==================================================================================
Func _MemoryClose($ah_Handle)
    
    If Not IsArray($ah_Handle) Then
        SetError(1)
        Return 0
    EndIf
    
    DllCall($ah_Handle[0], 'int', 'CloseHandle', 'int', $ah_Handle[1])
    If Not @Error Then
        DllClose($ah_Handle[0])
        Return 1
    Else
        DllClose($ah_Handle[0])
        SetError(2)
        Return 0
    EndIf
    
EndFunc

;==================================================================================
; Function:         SetPrivilege( $privilege, $bEnable )
; Description:      Enables (or disables) the $privilege on the current process
;                   (Probably) requires administrator privileges to run
;
; Author(s):        Larry (from autoitscript.com's Forum)
; Notes(s):
; http://www.autoitscript.com/forum/index.php?s=&showtopic=31248&view=findpost&p=223999
;==================================================================================

Func SetPrivilege( $privilege, $bEnable )
    Const $TOKEN_ADJUST_PRIVILEGES = 0x0020
    Const $TOKEN_QUERY = 0x0008
    Const $SE_PRIVILEGE_ENABLED = 0x0002
    Local $hToken, $SP_auxret, $SP_ret, $hCurrProcess, $nTokens, $nTokenIndex, $priv
    $nTokens = 1
    $LUID = DLLStructCreate("dword;int")
    If IsArray($privilege) Then    $nTokens = UBound($privilege)
    $TOKEN_PRIVILEGES = DLLStructCreate("dword;dword[" & (3 * $nTokens) & "]")
    $NEWTOKEN_PRIVILEGES = DLLStructCreate("dword;dword[" & (3 * $nTokens) & "]")
    $hCurrProcess = DLLCall("kernel32.dll","hwnd","GetCurrentProcess")
    $SP_auxret = DLLCall("advapi32.dll","int","OpenProcessToken","hwnd",$hCurrProcess[0],   _
            "int",BitOR($TOKEN_ADJUST_PRIVILEGES,$TOKEN_QUERY),"int_ptr",0)
    If $SP_auxret[0] Then
        $hToken = $SP_auxret[3]
        DLLStructSetData($TOKEN_PRIVILEGES,1,1)
        $nTokenIndex = 1
        While $nTokenIndex <= $nTokens
            If IsArray($privilege) Then
                $priv = $privilege[$nTokenIndex-1]
            Else
                $priv = $privilege
            EndIf
            $ret = DLLCall("advapi32.dll","int","LookupPrivilegeValue","str","","str",$priv,   _
                    "ptr",DLLStructGetPtr($LUID))
            If $ret[0] Then
                If $bEnable Then
                    DLLStructSetData($TOKEN_PRIVILEGES,2,$SE_PRIVILEGE_ENABLED,(3 * $nTokenIndex))
                Else
                    DLLStructSetData($TOKEN_PRIVILEGES,2,0,(3 * $nTokenIndex))
                EndIf
                DLLStructSetData($TOKEN_PRIVILEGES,2,DllStructGetData($LUID,1),(3 * ($nTokenIndex-1)) + 1)
                DLLStructSetData($TOKEN_PRIVILEGES,2,DllStructGetData($LUID,2),(3 * ($nTokenIndex-1)) + 2)
                DLLStructSetData($LUID,1,0)
                DLLStructSetData($LUID,2,0)
            EndIf
            $nTokenIndex += 1
        WEnd
        $ret = DLLCall("advapi32.dll","int","AdjustTokenPrivileges","hwnd",$hToken,"int",0,   _
                "ptr",DllStructGetPtr($TOKEN_PRIVILEGES),"int",DllStructGetSize($NEWTOKEN_PRIVILEGES),   _
                "ptr",DllStructGetPtr($NEWTOKEN_PRIVILEGES),"int_ptr",0)
        $f = DLLCall("kernel32.dll","int","GetLastError")
    EndIf
    $NEWTOKEN_PRIVILEGES=0
    $TOKEN_PRIVILEGES=0
    $LUID=0
    If $SP_auxret[0] = 0 Then Return 0
    $SP_auxret = DLLCall("kernel32.dll","int","CloseHandle","hwnd",$hToken)
    If Not $ret[0] And Not $SP_auxret[0] Then Return 0
    return $ret[0]
EndFunc   ;==>SetPrivilege

#endregion
Link to comment
Share on other sites

  • Moderators

I have read through his code many times, before even posting on this forum.

I still seem to be at a standstill though. Always returns 0

Suggestions:

I'd suggest you provide the link to the .au3 file you are using. Not everyone is familiar with the functions you are using, and people like me won't go out of their way to find it.

Issues I see with your code:

There's no Return statement in your function. It will always return nothing until you tell it to return something. (Yes I see your msgbox... this is more an FYI just in case).

Your @error statement, I'd suggest using a switch statement for that:

Switch @error
    Case 0
        $error_ = "etc"
EndSwitch

About bumping:

http://www.autoitscript.com/forum/index.ph...st&p=529666

http://www.autoitscript.com/forum/index.ph...st&p=485422

http://www.autoitscript.com/forum/index.ph...st&p=443303

http://www.autoitscript.com/forum/index.ph...st&p=450311

http://www.autoitscript.com/forum/index.ph...st&p=451665

http://www.autoitscript.com/forum/index.ph...st&p=491638

http://www.autoitscript.com/forum/index.ph...st&p=517041

http://www.autoitscript.com/forum/index.ph...st&p=544854

http://www.autoitscript.com/forum/index.ph...st&p=558562

Now you'll see the moderator(s) issues with it.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

...

; Return Value(s): On Success - Returns an array

...

It does return an array. You need to get the PID of the process (easy enough with the built-in autoit functions) and then simply call the _MemoryOpen function. Are you simply calling it like
_MemoryOpen($PID)
or are you using a variable like
$mem = _MemoryOpen($PID)
?
Link to comment
Share on other sites

It does return an array. You need to get the PID of the process (easy enough with the built-in autoit functions) and then simply call the _MemoryOpen function. Are you simply calling it like

_MemoryOpen($PID)
or are you using a variable like
$mem = _MemoryOpen($PID)
?

Yes i tried calling the variables as static and arrays, but when i used an array like [1] or [0] or [2] after the variable it gave me an error like

$OpenProcess[1]

$OpenProcess ^ERROR

Link to comment
Share on other sites

  • Moderators

Yes i tried calling the variables as static and arrays, but when i used an array like [1] or [0] or [2] after the variable it gave me an error like

$OpenProcess[1]

$OpenProcess ^ERROR

That's not the issue... you are sending the array as memory read requires.

"'Char[16]'" Why the single quotes?

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

That's not the issue... you are sending the array as memory read requires.

"'Char[16]'" Why the single quotes?

I tried with an without single quotes because i thought maybe it needed those, the Nomad used them in the example, so i was not sure if they are required or not. Either way though, it doesn't change anything, the result is still returned 0

which according to Nomad's comments mean there is some error while reading the memory?

I tried reading the memory of other processes too, and still failed with a 0.

I can find the address with CheatEngine, maybe i am using the wrong address,

do I need a pointer, or offset? Maybe you can explain a lil about those if you know?

Thanks ;)

Link to comment
Share on other sites

CE is fairly good but try MHS. It's based on the same principals and the creator is friends with the author of CE but it has a lot more features and seems to be able to read memory in a more "in-depth" way.

Link to comment
Share on other sites

its an issue with SetDebugPriviledge, no one here admits it, but its true.

I myself have had the same problem, the result is always 0, what people forget is, when you use PermEdit to grant your program priviledge, the result is correct.

Therefore SetDebugPriviledge does not work, and no one here is willing to accept this.

Link to comment
Share on other sites

  • Moderators

its an issue with SetDebugPriviledge, no one here admits it, but its true.

I myself have had the same problem, the result is always 0, what people forget is, when you use PermEdit to grant your program priviledge, the result is correct.

Therefore SetDebugPriviledge does not work, and no one here is willing to accept this.

That's a very bold statement. If you are talking about how that function (UDF SetPrivilege()) is written, well... I have no idea if it was written correctly. But I use this in other languages, and it does in fact work.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Well all i know is this. Ive tested it with 2 different types of processes

Notepad.exe

and a game process (its name isnt important)

Game.exe

When using my autoit script with notepad, and with or without using SetPrivilege the return value is correct.

When using my script with Game.exe and with or without using SetPrivilege the return value is always zero

By looking at msdn and how SetPrivilege works, i can conclude that the result "0" is actually the result of not having permission over the process.

A way to fix this, should be by setting your permissions using SetDebugPrivilege, however with Game.exe like i say it does not work.

Maybe some contributing factors are things like the game process "hooking" certain api's used such as WriteProcessMemory and ReadProcessMemory, however, if this was the case, then using an external program like "permedit" to grant my script permission to read/write processes would not work, however it does.

So from all this, i can only conclude the problem lies with the UDF for SetPrivilege() and the section for this function in NomadMemory.au3 is faulty.

Edited by SXGuy
Link to comment
Share on other sites

  • Moderators

Well all i know is this. Ive tested it with 2 different types of processes

Notepad.exe

and a game process (its name isnt important)

Game.exe

When using my autoit script with notepad, and with or without using SetPrivilege the return value is correct.

When using my script with Game.exe and with or without using SetPrivilege the return value is always zero

By looking at msdn and how SetPrivilege works, i can conclude that the result "0" is actually the result of not having permission over the process.

A way to fix this, should be by setting your permissions using SetDebugPrivilege, however with Game.exe like i say it does not work.

Maybe some contributing factors are things like the game process "hooking" certain api's used such as WriteProcessMemory and ReadProcessMemory, however, if this was the case, then using an external program like "permedit" to grant my script permission to read/write processes would not work, however it does.

So from all this, i can only conclude the problem lies with the UDF for SetPrivilege() and the section for this function in NomadMemory.au3 is faulty.

Your conclusion is kind of silly. There is no fault. There are ways of blocking processes with any debug privilege of reading your processes memory. I'd almost wager that this process is using some kind of game guard.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Moderators

Well all i know is this. Ive tested it with 2 different types of processes

Notepad.exe

and a game process (its name isnt important)

Game.exe

When using my autoit script with notepad, and with or without using SetPrivilege the return value is correct.

When using my script with Game.exe and with or without using SetPrivilege the return value is always zero

By looking at msdn and how SetPrivilege works, i can conclude that the result "0" is actually the result of not having permission over the process.

A way to fix this, should be by setting your permissions using SetDebugPrivilege, however with Game.exe like i say it does not work.

Maybe some contributing factors are things like the game process "hooking" certain api's used such as WriteProcessMemory and ReadProcessMemory, however, if this was the case, then using an external program like "permedit" to grant my script permission to read/write processes would not work, however it does.

So from all this, i can only conclude the problem lies with the UDF for SetPrivilege() and the section for this function in NomadMemory.au3 is faulty.

engine found an issue with token_privileges structure. He has a work around if you want to try that: http://www.autoitscript.com/forum/index.php?showtopic=78488

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Your right, of course there is a game gaurd which blocks privileges, but my point was, if this was soley the case, then permedit would not fix this, but it does.

EDIT: id like to point out however, i have bypassed the game gaurd, so thats not really the issue.

But i will say one thing, i dont know how different perm edit is, compared to standard SetPrivilege, so maybe the tool itsself re-writes some hooks which are needed, like WPM/RPM etc. In that case, then id agree with you.

SmOke_N : Thank you, i will try that ;)

Edited by SXGuy
Link to comment
Share on other sites

Rick,

I was easily able to get the memory functions to work. My suggestion is, your memory address is wrong.

Take a look: Memory

Even the "static" memory addresses change when you log-off your computer. So everytime you boot up, you gotta get it again. ;)

Get this example to work. And when you do that you should be easily able to make your game work=)

GL

Link to comment
Share on other sites

If your "static" address changes when you log off, then its not static, its dynamic.

And even if its dynamic, there would be a static way of finding it again.

Help me here? According to every help file and tutorial I can find... When it hits a green address it's called "Static".

That address changed on me twice when I logged off my computer. How do I take it a step farther and get the real 'Static' address?

This would be really useful information=D

Thanks,

Link to comment
Share on other sites

ok, bare in mind, im more expierenced with CheatEngine than i am autoit, so i can try to explain how the pointers are found using that, but someone else more skilled in autoit maybe needed to convert my explanation to code.

Usually when you have a dynamic address with cheat engine search results, if you add it to your ct, and then change the address, you will generaly have processname.exe+offset.

In the ct list this is shown as an address, however its dynamic, the only static thing is the offset no doubt.

Therefore with finding dynamic addresses using autoit, you would need to locate the base address of the client once its process has been loaded, and then add the offset to it, and return the new address.

If the address was truely static, then it would remain the same all the time, unless the client updates of course by patching and creating a memory shift.

I cant remember if green or black addresses are static or dynamic, forgive me for that, but like i said, static ones would never change, dynamic do, but can be found statically first by finding the process base address then adding the offset to it.

Example.

01234567 <--- dynamic address

Process.exe+4567 <-- static offset

01230000 <--- dynamic base address

Does that make sense? im trying to explain as best i can lol.

How you find the base address by scanning intially using autoit it i do not know.

Edited by SXGuy
Link to comment
Share on other sites

ok, bare in mind, im more expierenced with CheatEngine than i am autoit, so i can try to explain how the pointers are found using that, but someone else more skilled in autoit maybe needed to convert my explanation to code.

Usually when you have a dynamic address with cheat engine search results, if you add it to your ct, and then change the address, you will generaly have processname.exe+offset.

In the ct list this is shown as an address, however its dynamic, the only static thing is the offset no doubt.

Therefore with finding dynamic addresses using autoit, you would need to locate the base address of the client once its process has been loaded, and then add the offset to it, and return the new address.

If the address was truely static, then it would remain the same all the time, unless the client updates of course by patching and creating a memory shift.

I cant remember if green or black addresses are static or dynamic, forgive me for that, but like i said, static ones would never change, dynamic do, but can be found statically first by finding the process base address then adding the offset to it.

Example.

01234567 <--- dynamic address

Process.exe+4567 <-- static offset

01230000 <--- dynamic base address

Does that make sense? im trying to explain as best i can lol.

How you find the base address by scanning intially using autoit it i do not know.

Okay so your saying...

Find the static adress (Green btw)

Get the process name and value: "00000A18-inkball.exe" (Dumb vista game I was playing with)

Take the static - the A18 in a calculator and then you have your base static?

00869ED8 - A18 (Hex in calc) ??

Or are you saying:

00869ED8 + A18 = Base static

?

Thanks man for your help! I'll get this sooner or later ;)

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...