Jump to content
Szhlopp

Memory UDF

Recommended Posts

Sorry to dig up a old thread. but is their anyway to use this with windows 7?

Wow, this brings back memories. I would imagine this script would require admin rights in Windows 7, are you using #RequireAdmin?

Edited by Yorn

Share this post


Link to post
Share on other sites

I am getting the same problem on windows 7 64bit.

Getting an @error set to 2

any solutions?

quick code i made:

#include <NomadMemory.au3>
#RequireAdmin
SetPrivilege("SeDebugPrivilege", 1) 
$Handle = _MemoryOpen(ProcessExists("firefox.exe"))
If @error Then 
    MsgBox(0,"Error","No handle found")
    Exit
 EndIf
  $Base = _MemoryGetBaseAddress($Handle,0)
  if @error Then
    MsgBox (0,"Error","@Error Returned : " & @error)
 Else
    MsgBox (0,"Success",$Base)
 EndIf
Edited by gononono64

Share this post


Link to post
Share on other sites

Both this module and NomadMemory need to be run under 32-bit mode (you can set this at the top of the script with the line '#AutoIt3Wrapper_UseX64=n').

As far as 64-bit mode - well, you'd need to update both - and actually I'd suggest using CreateToolhelp32Snapshot & Module32First/Next API calls rather than traverse through memory like 'MemoryGetBaseAddress' does.

For an example of what I mean, and for something that works in 64-bit mode, you could take a look at my Processes, Threads & DLL's module (in signature). You'll have to know a bit more about opening/closing processes though.


Share this post


Link to post
Share on other sites

Both this module and NomadMemory need to be run under 32-bit mode (you can set this at the top of the script with the line '#AutoIt3Wrapper_UseX64=n').

i did this to both the codes and i still get 2 as an @error. =S

Edited by gononono64

Share this post


Link to post
Share on other sites

i think you are using an old version of NomadMemory that SetPrivilege doesn't work on Win Vista & 7.

Open NomadMemory.au3 and replace this:

Func SetPrivilege( $privilege, $bEnable )
    Const $MY_TOKEN_ADJUST_PRIVILEGES = 0x0020
    Const $MY_TOKEN_QUERY = 0x0008
    Const $MY_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($MY_TOKEN_ADJUST_PRIVILEGES,$MY_TOKEN_QUERY),"int*",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,$MY_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*",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

Share this post


Link to post
Share on other sites

With the new AutoIt v3.8.8.0 the UDF will always give a error code 2; however, adding a small change to four lines of the original code will make it work in v3.8.8.0

A Int( ) code needs to be added around the DllStructGetData( ) code. Here is the original code --

$vData = Hex(DllStructGetData($v_Buffer, 2))
$vType = Hex(DllStructGetData($v_Buffer, 3))

With the changes done --

$vData = Hex(Int(DllStructGetData($v_Buffer, 2)))
$vType = Hex(Int(DllStructGetData($v_Buffer, 3)))

Just repeat this twice in the function code, in both places the original code is found. I have attached the updated UDF function with the Int code changes added.

Also note adding the Int code around the DllStructGetData code in other places in the NomadMemory.au3 will make those functions work as well in AutoIt v3.8.8.0 . So far I have tested that the _MemoryGetBaseAddress and _MemoryRead functions need the change, most other functions work correctly -- I have to however test the pointer functions.

;===================================================================================================
; 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(Int(DllStructGetData($v_Buffer, 2)))
        $vType = Hex(Int(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(Int(DllStructGetData($v_Buffer, 2)))
            $vType = Hex(Int(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

Share this post


Link to post
Share on other sites

Heya,

I took the liberty to extract the right functions from Ascend4nt's exelent function-compilation and made a simple example-script to get the base address from a process:

#include <WinAPI.au3>
Global $_COMMON_KERNEL32DLL=DllOpen("kernel32.dll")


$Process = 'notepad.exe'

If Not ProcessExists($Process) then
  MsgBox(0, "", $Process&" is not running")
  Exit
EndIf


$PID = ProcessExists($Process)
$OpenProcess = _ProcessOpen($PID,0x400)
$pTemp=_ProcessGetModuleBaseAddress($PID ,$OpenProcess)
$aTemp=_ProcessMemoryVirtualQuery($OpenProcess,$pTemp)

;$aTemp[1] contains the base address
MsgBox(0, "", "The base address for the process "&$Process&" is "&$aTemp[1])




Func _ProcessOpen($vProcessID,$iAccess,$bInheritHandle=False)
Local $aRet
; Special 'Open THIS process' ID?  [returns pseudo-handle from Windows]
If $vProcessID=-1 Then
  $aRet=DllCall($_COMMON_KERNEL32DLL,"handle","GetCurrentProcess")
  If @error Then Return SetError(2,@error,0)
  Return $aRet[0]  ; usually the constant '-1', but we're keeping it future-OS compatible this way
ElseIf Not __PFEnforcePID($vProcessID) Then
  Return SetError(16,0,0)  ; Process does not exist or was invalid
EndIf
$aRet=DllCall($_COMMON_KERNEL32DLL,"handle","OpenProcess","dword",$iAccess,"bool",$bInheritHandle,"dword",$vProcessID)
If @error Then Return SetError(2,@error,0)
If Not $aRet[0] Then Return SetError(3,@error,0)
Return SetExtended($vProcessID,$aRet[0]) ; Return Process ID in @extended in case a process name was passed
EndFunc

Func _ProcessGetModuleBaseAddress($vProcessID,$sModuleName,$bList32bitMods=False,$bGetWow64Instance=False)
Local $i=0,$aModList
If Not $bList32bitMods Then $i=4 ; flag 4 = stop at 1st match (only if 32-bit modules aren't being listed)
$aModList=_ProcessListModules($vProcessID,$sModuleName,$i,$bList32bitMods)
If @error Then Return SetError(@error,@extended,-1)
If $aModList[0][0]=0 Then Return SetError(-1,0,-1)
; If a Wow64 Process (and $bList32bitMods=True), its possible more than one module name will match
If $aModList[0][0]>1 Then
  If $bList32bitMods And $bGetWow64Instance Then Return SetExtended($aModList[2][4],$aModList[2][3])
  SetError(-16) ; notify caller that >1 match was found, but returning 1st instance since $bGetWow64Instance=False
EndIf
Return SetError(@error,$aModList[1][4],$aModList[1][3]) ; SetExtended() actually clears @error, so we must use SetError()
EndFunc
Func _ProcessMemoryVirtualQuery($hProcess,$pAddress,$iInfo=-1)
If Not IsPtr($hProcess) Or Ptr($pAddress)=0 Or $iInfo>6 Then Return SetError(1,0,-1)
; MEMORY_BASIC_INFORMATION structure:  BaseAddress, AllocationBase, AllocationProtect, RegionSize, State, Protect, Type
Local $aRet,$stMemInfo=DllStructCreate("ptr;ptr;dword;ulong_ptr;dword;dword;dword"),$iStrSz=DllStructGetSize($stMemInfo)
$aRet=DllCall($_COMMON_KERNEL32DLL,"ulong_ptr","VirtualQueryEx","handle",$hProcess,"ptr",$pAddress,"ptr",DllStructGetPtr($stMemInfo),"ulong_ptr",$iStrSz)
If @error Then Return SetError(2,@error,-1)
If Not $aRet[0] Then Return SetError(3,@error,-1)
If $aRet[0]<>$iStrSz Then ConsoleWriteError("Size (in bytes) mismatch in VirtualQueryEx: Struct: "&$iStrSz&", Transferred: "&$aRet[0]&@LF)
; Return ALL?
If $iInfo<0 Then
  Dim $aMemInfo[7]
  For $i=0 To 6
   $aMemInfo[$i]=DllStructGetData($stMemInfo,$i+1)
  Next
  Return $aMemInfo
EndIf
Return DllStructGetData($stMemInfo,$iInfo+1)
EndFunc

Func _ProcessListModules($vProcessID,$sTitleFilter=0,$iTitleMatchMode=0,$bList32bitMods=False)
If Not __PFEnforcePID($vProcessID) Then Return SetError(1,0,"")
Local $hTlHlp,$aRet,$sTitle,$bMatchMade=1,$iTotal=0,$bMatch1=0,$iArrSz=40,$iNeg=0
If $sTitleFilter="" Then $sTitleFilter=0
If BitAND($iTitleMatchMode,8) Then
  $iNeg=-1
; 'Stop at first match' flag set?
ElseIf BitAND($iTitleMatchMode,4) And IsString($sTitleFilter) Then
  $iArrSz=1
  $bMatch1=1
EndIf
$iTitleMatchMode=BitAND($iTitleMatchMode,3)
Dim $aModules[$iArrSz+1][6]
; MAX_MODULE_NAME32 = 255  (+1 = 256), MAX_PATH = 260
; ModuleEntry32: Size, Module ID, Process ID, Global Usage Count, Process Usage Count, Base Address, Module Size, Module Handle, Module Name, Module Path
Local $stModEntry=DllStructCreate("dword;dword;dword;dword;dword;ptr;dword;handle;wchar[256];wchar[260]"),$pMEPointer=DllStructGetPtr($stModEntry)
DllStructSetData($stModEntry,1,DllStructGetSize($stModEntry))
If $bList32bitMods Then
  ; TH32CS_SNAPMODULE32 0x00000010  +  ; TH32CS_SNAPMODULE  0x00000008
  $hTlHlp=__PFCreateToolHelp32Snapshot($vProcessID,0x18)
Else
  ; TH32CS_SNAPMODULE  0x00000008
  $hTlHlp=__PFCreateToolHelp32Snapshot($vProcessID,8)
EndIf
If @error Then Return SetError(@error,@extended,"")
; Get first module
$aRet=DllCall($_COMMON_KERNEL32DLL,"bool","Module32FirstW","handle",$hTlHlp,"ptr",$pMEPointer)
While 1
  If @error Then
   Local $iErr=@error
   __PFCloseHandle($hTlHlp)
   Return SetError(2,$iErr,"")
  EndIf
  ; False returned? Likely no more modules found [LastError should equal ERROR_NO_MORE_FILES (18)]
  If Not $aRet[0] Then ExitLoop
  $sTitle=DllStructGetData($stModEntry,9)    ; file name
  If IsString($sTitleFilter) Then
   Switch $iTitleMatchMode
    Case 0
     If $sTitleFilter<>$sTitle Then $bMatchMade=0
    Case 1
     If StringInStr($sTitle,$sTitleFilter)=0 Then $bMatchMade=0
    Case Else
     If Not StringRegExp($sTitle,$sTitleFilter) Then $bMatchMade=0
   EndSwitch
   $bMatchMade+=$iNeg ; toggles match/no-match if 0x8 set
  EndIf
  If $bMatchMade Then
   $iTotal+=1
   If $iTotal>$iArrSz Then
    $iArrSz+=10
    ReDim $aModules[$iArrSz+1][6]
   EndIf
   $aModules[$iTotal][0]=$sTitle
   $aModules[$iTotal][1]=DllStructGetData($stModEntry,10) ; full path
   $aModules[$iTotal][2]=DllStructGetData($stModEntry,8) ; module handle/address (normally same as Base Address)
   $aModules[$iTotal][3]=DllStructGetData($stModEntry,6) ; module base address
   $aModules[$iTotal][4]=DllStructGetData($stModEntry,7) ; module size
   $aModules[$iTotal][5]=DllStructGetData($stModEntry,5) ; process usage count (same as Global usage count)
   ; Process ID is same as on entry, Module ID always = 1, Global Usage Count = Process Usage Count
   If $bMatch1 Then ExitLoop
  EndIf
  $bMatchMade=1
  ; Next module
  $aRet=DllCall($_COMMON_KERNEL32DLL,"bool","Module32NextW","handle",$hTlHlp,"ptr",$pMEPointer)
WEnd
__PFCloseHandle($hTlHlp)
ReDim $aModules[$iTotal+1][6]
$aModules[0][0]=$iTotal
Return $aModules
EndFunc

Func __PFCreateToolHelp32Snapshot($iProcessID,$iFlags)
; Parameter checking not done!! (INTERNAL only!)
Local $aRet
; Enter a loop in the case of a Module snapshot returning -1 and LastError=ERROR_BAD_LENGTH.  We'll try a max of 10 times
For $i=1 To 10
  $aRet=DllCall($_COMMON_KERNEL32DLL,"handle","CreateToolhelp32Snapshot","dword",$iFlags,"dword",$iProcessID)
  If @error Then Return SetError(2,@error,-1)
  ; INVALID_HANDLE_VALUE (-1) ?
  If $aRet[0]=-1 Then
   ; Heap (0x1) or Module (0x8 or 0x18) Snapshot?  MSDN recommends retrying the API call if LastError=ERROR_BAD_LENGTH (24)
   If BitAND($iFlags,0x19) And _WinAPI_GetLastError()=24 Then ContinueLoop
   ; Else - other error, invalid handle
   Return SetError(3,0,-1)
  EndIf
  Sleep(0) ; delay the next attempt
Next
If $aRet[0]=-1 Then Return SetError(4,0,-1)
Return $aRet[0]
EndFunc
Func __PFCloseHandle(ByRef $hHandle)
If Not IsPtr($hHandle) Or $hHandle=0 Then Return SetError(1,0,False)
Local $aRet=DllCall($_COMMON_KERNEL32DLL,"bool","CloseHandle","handle",$hHandle)
If @error Then Return SetError(2,@error,False)
If Not $aRet[0] Then Return SetError(3,@error,False)
; non-zero value for return means success
$hHandle=0 ; invalidate handle
Return True
EndFunc
Func __PFEnforcePID(ByRef $vPID)
If IsInt($vPID) Then Return True
$vPID=ProcessExists($vPID)
If $vPID Then Return True
Return SetError(1,0,False)
EndFunc

Cheers

Edited by faldo

Share this post


Link to post
Share on other sites

i have no knowledge about this things. will it be possible with this, to read the autoit-process and possibly to identify its content?

what i want is something, to detect closures, routines, witch eat ram, memory, not freed variables.

a kind of debugger for bad writen code.

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

×
×
  • Create New...