Jump to content
Sign in to follow this  
toto22

Reading memory "double"

Recommended Posts

I'm trying to get a "double" value from memory . However my code gives me error.

 

Opt("WinTitleMatchMode", 4)
    Global $ProcessID = WinGetProcess("TI Pro")

    If $ProcessID = -1 Then
        MsgBox(4096, "ERROR", "Failed to detect process.")
        Exit
    EndIf

    Local $DllInformation = _MemoryOpen($ProcessID)
    If @Error Then
        MsgBox(4096, "ERROR", "Failed to open memory.")
        Exit
    EndIf

  Local $dAddress = 0x1FECD474
  Local $tNbSteps = DllStructCreate("double", $dAddress)
  Local $value = DllStructSetData($tNbSteps, 1, (_MemoryRead($dAddress, $DllInformation)))

     MsgBox($MB_SYSTEMMODAL, $value)
Edited by toto22

Share this post


Link to post
Share on other sites

@toto22 how about explaining what you are trying to automate? Why do you need to pull it out of memory? What is the app? Is the info displayed in a field, on a webpage, etc.? The more information you can provide, the better we can assist.


"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Share this post


Link to post
Share on other sites

Hey guys, thank you for your replies. I'm trying to get information form trade-ideas software to help me place trades faster. I tried extracting information using windows UI, but I was unsuccessful. My code below works for 4 bit values. Any ideas on how to modify it to get it working for "double" values?

#include <nomadMemory.au3>

Opt("WinTitleMatchMode", 4)
    Global $ProcessID = WinGetProcess("TI Pro")

    If $ProcessID = -1 Then
        MsgBox(4096, "ERROR", "Failed to detect process.")
        Exit
    EndIf

    Local $DllInformation = _MemoryOpen($ProcessID)
    If @Error Then
        MsgBox(4096, "ERROR", "Failed to open memory.")
        Exit
    EndIf

    $Value = Number(_MemoryRead(0x1FECD474, $DllInformation),2)
    If @Error Then
        MsgBox(4096, "ERROR", "Failed to read memory.")
        Exit
    EndIf


    _MemoryClose($DllInformation)
    If @Error Then
        MsgBox(4096, "ERROR", "Failed to close memory.")
        Exit
    EndIf

 

 

Edited by toto22

Share this post


Link to post
Share on other sites

Maybe try to read 2 bytes separatelly and then combine these two values in AutoIt:

$Value1 = Number(_MemoryRead(0x1FECD474, $DllInformation),1)
$Value2 = Number(_MemoryRead(0x1FECD475, $DllInformation),1)

or try this:

$Value = Number(_MemoryRead(0x1FECD474, $DllInformation),3)

 

Edited by Zedna

Share this post


Link to post
Share on other sites

I don't think Number(###, 3) will work in this case, as it will still treat the integer value at that memory location as a number, rather than an IEEE754 encoded value. The Dec function does do this conversion though, if you give it a string value.

$xMem = 0x40151CAC083126E9

$sMemHex = String(Hex($xMem, 16))
$nNum = Dec($sMemHex, 3)

MsgBox(0, $xMem, $nNum)

In this case, the expected answer is 5.278. 

For completeness, to go the other way you can just use the Hex function on a double value. 

Share this post


Link to post
Share on other sites

Thank you guys. 

Zedna - Mat is right, #3 does return tread integer, and I'm not sure on how to combine 4 bit values in order to get a double.

Mat - somethig like this? "$Value = Dec(Hex(_MemoryRead(0x1FECD474, $DllInformation),8),3)"

Share this post


Link to post
Share on other sites

If _MemoryRead is returning 4 byte values (which I think it does, but I haven't used it in a long time) then to combine you should use BitShift and BitOr. For example:

BitOr(BitShift(_MemoryRead(...), 32), _MemoryRead(...))

So this shifts the more significant dword up and combines it with the lower dword. 

You'll have to do some reading on endianness to work out what addresses each would be. 

Once you have that value, then you can convert it to floating point using the method above.

Share this post


Link to post
Share on other sites

@toto22, There's a mistake in my previous post. The bit operations only work on 32 bit integers in AutoIt (no idea why). The below code shows a method using concatenation to build the hex string instead:

; Simulate the program
$t = DllStructCreate("DOUBLE")
DllStructSetData($t, 1, 123.456)
$p = DllStructGetPtr($t)


MsgBox(0, "Address", $p)


; This is what _MemoryRead($p) does the equivalent of
$tRead = DllStructCreate("DWORD", $p)
$hi = DllStructGetData($tRead, 1)

; This is what _MemoryRead($p+4) does the equivalent of
$tRead = DllStructCreate("DWORD", $p+4)
$lo = DllStructGetData($tRead, 1)

; Combine back into an 8byte integer:
$full = Hex($lo,8) & Hex($hi,8)

MsgBox(0, "Read from memory", "Two dwords:" & @CRLF & Hex($hi,8) & @CRLF & Hex($lo,8) & @CRLF & $full)

; Conversion to double:
$sMemHex = String($full)
$nNum = Dec($sMemHex, 3)

MsgBox(0, $full, $nNum)

I don't have NomadMemory installed, so instead I've shown the equivalent using structs (this method only works within one process). 

Share this post


Link to post
Share on other sites

@toto22

This code should works

Local $iPid = WinGetProcess("TI Pro")
Local $iAddress = 0x1FECD474

If $iPid = -1 Then
    ConsoleWrite("+++ Failed to get process PID. Open good process or change parameter in WinGetProcess func." & @CRLF)
    Exit
EndIf

Local $hHandle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1F0FFF, 'int', 1, 'int', $iPid)

If @error Then
    ConsoleWrite("+++ Failed to open process memory for FULL_ACCESS. Error is " & @error & @CRLF)
    Exit
EndIf

Local $tagStruct = "struct;double var1;endstruct"

Local $sStruct = DllStructCreate($tagStruct)

If @error Then
    ConsoleWrite("+++ Failed to create $sStruct. Error is " & @error & @CRLF)
    Exit
EndIf

DllCall("kernel32.dll", 'int', 'ReadProcessMemory', 'int', $hHandle[0], 'int', $iAddress, 'ptr', DllStructGetPtr($sStruct), 'int', DllStructGetSize($sStruct), 'int', '')

If @error Then
    ConsoleWrite("+++ Failed to Read Process Memory. Error is " & @error & @CRLF)
    Exit
EndIf

Local $vRet = DllStructGetData($sStruct, "var1")

If @error Then
    ConsoleWrite("+++ Failed to Get data from $sStruct. Error is " & @error & @CRLF)
    Exit
EndIf

ConsoleWrite("++ Successfully read memory at addr 0x" & Hex($iAddress) & " value is " & $vRet & @CRLF)

 

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  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By SteveJM
      When I use DllStructCreate() to reserve a chunk of memory I would like to know if I can rely on that memory being initialized to zero. Experience suggests that it is, but I have been searching to try and find a definitive statement anywhere that this is the case. I apologise if I have missed somewhere. Part of the reason for this question is so that my next search (after my personal memory has dimmed) should yield a link to this post, hopefully with an answer.
      A number of DLLs I use have structs where a few parts have to be explicitly set and other parts are reserved with the instruction that they must be set to zero. Because DllStructCreate() appears to zero-initialise the memory, I tend to forget to do it explicitly and everything seems to work. I am wondering whether I have been lucky and am storing up trouble for myself. It seems likely that the OS has been asked for zeroed memory, but without a promise in the documentation for DllStructCreate(),  perhaps that could change? Perhaps the developers wish to reserve the right to change their minds?
    • By Chimp
      After watching this movie (https://www.youtube.com/watch?v=cPiDHXtM0VA) I wanted to try the test to see how much i could compete with that chimpanzee so i created this script.
      well, actually passing that test is a lot harder than it sounds. With the difficulty set to seven numbers and a display time of one second, I can only remember 2 or 3 numbers ... (what a disappointment)
      I can only do better if I reduce the slider to 5 numbers and increase the storage time to 2 seconds (the easyest level), a very poor performance. That chimpanzee is great.
      The script offers you a sequence of 10 random quizzes. At the end it gives you the percentage of your "level". The chimpanzee resolves on average 8 out of 10 (80%), so you can compare your performance to that of the chimpanzee.
      How to play:
      Run the script. At the beginning there are 2 sliders at the bottom of the screen where you can set the difficulty level by varying the memorization time and the amount of numbers to memorize as you like. After setting the difficulty, click the circle on the bottom left to get started. after the first move the sliders are no longer displayed until the next game, (the game lasts 10 attempts, there is a progress bar at the bottom of the screen to see where you are) between one test and the other of the ten, click on the circle to move on to the next test have fun.
      #include <GUIConstants.au3> #include <MsgBoxConstants.au3> #include <Array.au3> #include <WinAPIMisc.au3> ; HotKeySet("{ESC}", "_EndOfGame") Global $iNumbersToGuess = 7, $iExpositionTime = 1000, $iMatches = 10, $iMatchesWon Global $aNumbers[10] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] Global $aButtons[10], $aControls[5] Global $iWinWidth = @DesktopWidth / 2, $iWinHeight = @DesktopHeight / 2, $iButtonXSide = Int($iWinWidth / UBound($aNumbers)), $iButtonYSide = Int($iWinHeight / UBound($aNumbers)), $sWinTitle = "Beat the Chimp" Global $aX[Int($iWinWidth / $iButtonXSide)], $aY[Int($iWinHeight / $iButtonYSide)], $iNdx = 0, $aPoints[3], $score, $GUIGetMsg, $iDockHeight = 50, $iProgrssHeight = 5 For $i = 0 To (Int($iWinWidth / $iButtonXSide) - 1) * $iButtonXSide Step $iButtonXSide $aX[$iNdx] = $i $iNdx += 1 Next $iNdx = 0 For $i = 0 To (Int($iWinHeight / $iButtonYSide) - 1) * $iButtonYSide Step $iButtonYSide $aY[$iNdx] = $i $iNdx += 1 Next Global Const $iDockLeftBorder = 200, $iForeColor = 0xFFFFFF, $iBackColor = 0x000000 Global $hGUI = GUICreate($sWinTitle, $iWinWidth, $iWinHeight + $iDockHeight + $iProgrssHeight, @DesktopWidth / 4, @DesktopHeight / 5) GUISetBkColor($iBackColor, $hGUI) ; the circle to continue playing $aControls[0] = GUICtrlCreateLabel(ChrW(0x25EF), 0, $iWinHeight + 1, 100, $iDockHeight, 0x01) ; GUICtrlSetTip(-1, "Click the circle," & @CRLF & "then click the squares" & @CRLF & "in numeric order.") GUICtrlSetFont(-1, 24, 900) GUICtrlSetColor(-1, $iForeColor) GUICtrlSetBkColor(-1, $iBackColor) ; slider for the amount of numbers to guess $aControls[2] = GUICtrlCreateSlider($iDockLeftBorder, $iWinHeight, $iWinWidth - $iDockLeftBorder, Int($iDockHeight / 2)) GUICtrlSetLimit(-1, 10, 5) ; 5 steps 5 (easy) to 10 (hard) GUICtrlSetData(-1, $iNumbersToGuess) ; label for the amount of quizzes $aControls[1] = GUICtrlCreateLabel("Numbers : " & GUICtrlRead($aControls[2]), 100, $iWinHeight + 1, 100) GUICtrlSetColor(-1, $iForeColor) ; slider for the exposition time $aControls[4] = GUICtrlCreateSlider($iDockLeftBorder, $iWinHeight + (Int($iDockHeight / 2)), $iWinWidth - $iDockLeftBorder, $iDockHeight / 2) GUICtrlSetLimit(-1, 8, 1) ; 8 steps (0f 250ms each) GUICtrlSetData(-1, $iExpositionTime / 250) ; label for the exposition time $aControls[3] = GUICtrlCreateLabel("ms to show : " & GUICtrlRead($aControls[4]) * 250, 100, $iWinHeight + 1 + (Int($iDockHeight / 2)), 100) GUICtrlSetColor(-1, $iForeColor) ; progress bar of the match Global $idProgressbar = GUICtrlCreateProgress(0, $iWinHeight + $iDockHeight, $iWinWidth, $iProgrssHeight) ; Create buttons For $i = 0 To 9 $aButtons[$i] = GUICtrlCreateLabel($i + 1, $iWinWidth + 5, $iWinHeight + $iDockHeight + $iProgrssHeight + 5, $iButtonXSide, $iButtonYSide, 0x01) GUICtrlSetFont($aButtons[$i], 24) GUICtrlSetColor($aButtons[$i], $iForeColor) GUICtrlSetBkColor($aButtons[$i], $iBackColor) Next GUISetState(@SW_SHOW) ; --- Main loop --- Do ; New game $iMatchesWon = 0 GUICtrlSetData($idProgressbar, 0) For $iRound = 1 To $iMatches ; the game lasts $iMatches rounds $iNdx = 0 ; reset pointer (index to the next correct answer) _HideControls(__get_IDs_by_indexes($aButtons, $aNumbers)) ; remove the numbers from the screen ; show the dock and wait (only in the first round are also shown the sliders) _ShowControls($iRound = 1 ? $aControls : $aControls[0]) ; display the dock's control(s) While 1 Switch GUIGetMsg() Case $aControls[0] ; The circle (play a new quiz) ExitLoop Case $aControls[2] ; slider to choose how many numbers to guess $iNumbersToGuess = GUICtrlRead($aControls[2]) GUICtrlSetData($aControls[1], "Numbers : " & $iNumbersToGuess) Case $aControls[4] ; slider to choose how long (milliseconds) to show the numbers $iExpositionTime = GUICtrlRead($aControls[4]) * 250 ; 8 steps of 250 milliseconds each GUICtrlSetData($aControls[3], "ms to show : " & $iExpositionTime) Case $GUI_EVENT_CLOSE _EndOfGame() EndSwitch WEnd _HideControls($aControls) ; hide the dock Sleep(750) ; wait a bit $aQuiz = _GenerateQuiz($iNumbersToGuess) ; generate random elements to guess _SpreadControls(__get_IDs_by_indexes($aButtons, $aQuiz)) ; scatter the numbers on the GUI _ShowControls(__get_IDs_by_indexes($aButtons, $aQuiz)) ; display the numbers Sleep($iExpositionTime) ; leave numbers visible for a short time _MaskControls(__get_IDs_by_indexes($aButtons, $aQuiz)) ; mask the numbers GUICtrlSetData($idProgressbar, Round($iRound / $iMatches * 100)) ; _ShowControls(__get_IDs_by_indexes($aButtons, $aQuiz)) ; <------------- keep numbers visible FOR DEBUG PURPOSE ONLY! While 1 ; wait for a move $GUIGetMsg = GUIGetMsg() If $GUIGetMsg = $GUI_EVENT_CLOSE Then _EndOfGame() ; scan all quiz buttons to check if one was pressed For $i = 0 To UBound($aQuiz) - 1 ; $aButtons) - 1 If $GUIGetMsg = $aButtons[$aQuiz[$i] - 1] Then If $i = $iNdx Then ; -------------------------- ; actions for a right move ; -------------------------- ; hide the guessed number _HideControls($aButtons[$aQuiz[$i] - 1]) ; --------------------------------- ; check if this round is complete ; --------------------------------- If $iNdx = (UBound($aQuiz) - 1) Then _WinAPI_PlaySound("SystemExclamation", Null, BitOR($SND_ALIAS, $SND_ASYNC)) $iMatchesWon += 1 ExitLoop 2 EndIf ; play a short ok sound ; _WinAPI_PlaySound("FaxBeep", Null, BitOR($SND_ALIAS, $SND_ASYNC)) ; "SystemAsterisk" $iNdx += 1 ; set index to next correct answer Else ; -------------------------- ; actions for a wrong move ; -------------------------- ; show all the right sequence _ShowControls(__get_IDs_by_indexes($aButtons, $aQuiz)) _WinAPI_PlaySound("DeviceFail", Null, BitOR($SND_ALIAS, $SND_ASYNC)) ; give a little time to the user to control it Sleep(1500) ; go to next step ExitLoop 2 EndIf EndIf Next WEnd ; loop till end of match $score = Round($iMatchesWon / $iMatches * 100, 2) ; percentage Select Case $score < 80 $sResult = "The chimp beat you!" Case $score > 80 $sResult = "You beat the chimp!" Case $score = 80 $sResult = "You tied the chimp." EndSelect Next ; next round ; game over? Until MsgBox($MB_YESNO + $MB_ICONINFORMATION + $MB_TASKMODAL + $MB_SETFOREGROUND, _ "Game over", _ "You got " & $score & "% correct." & @CRLF & _ "Ayumu averages 80% correct." & @CRLF & $sResult & @CRLF & @CRLF & _ "do you want to try again?") <> 6 Func _SpreadControls($aTemp) ; place the required numbers scattered on the GUI SRandom(@YEAR + @MON + @MDAY + @HOUR + @MIN + @SEC) _ArrayShuffle($aX) _ArrayShuffle($aY) ; first, place all buttons out of GUI For $i = 0 To UBound($aButtons) - 1 GUICtrlSetPos($aButtons[$i], $iWinWidth + 5, $iWinHeight + $iDockHeight + $iProgrssHeight + 5) GUICtrlSetState($aButtons[$i], $GUI_DISABLE) Next ; Then place only the numbers of this quiz in visible area For $i = 0 To UBound($aTemp) - 1 GUICtrlSetPos($aTemp[$i], $aX[$i], $aY[$i]) GUICtrlSetState($aTemp[$i], $GUI_ENABLE) Next EndFunc ;==>_SpreadControls Func _GenerateQuiz($iNumElements) ; generate an array of required random numbers SRandom(@YEAR + @MON + @MDAY + @HOUR + @MIN + @SEC) Local $aTemp[$iNumElements] _ArrayShuffle($aNumbers) For $i = 0 To $iNumElements - 1 $aTemp[$i] = $aNumbers[$i] Next _ArraySort($aTemp) Return $aTemp EndFunc ;==>_GenerateQuiz Func _ShowControls($aTemp) ; render controls visible (and enabled) $aTemp = _EnforceArray($aTemp) For $i = 0 To UBound($aTemp) - 1 GUICtrlSetState($aTemp[$i], $GUI_SHOW) GUICtrlSetColor($aTemp[$i], $iForeColor) GUICtrlSetBkColor($aTemp[$i], $iBackColor) Next EndFunc ;==>_ShowControls Func _MaskControls($aTemp) ; mask the controls $aTemp = _EnforceArray($aTemp) For $i = 0 To UBound($aTemp) - 1 GUICtrlSetColor($aTemp[$i], $iForeColor) GUICtrlSetBkColor($aTemp[$i], $iForeColor) Next EndFunc ;==>_MaskControls Func _HideControls($aTemp) ; hide the controls (implies disable) $aTemp = _EnforceArray($aTemp) For $i = 0 To UBound($aTemp) - 1 GUICtrlSetState($aTemp[$i], $GUI_HIDE) ; $GUI_DISABLE) ; GUICtrlSetColor($aButtons[$aTemp[$i] - 1], $iBackColor) ; GUICtrlSetBkColor($aButtons[$aTemp[$i] - 1], $iBackColor) Next EndFunc ;==>_HideControls Func _EnforceArray($vParam) ; if only one value is passed, turn it into an array of only 1 element If Not IsArray($vParam) Then Local $aTemp[1] = [$vParam] Return $aTemp EndIf Return $vParam EndFunc ;==>_EnforceArray Func __get_IDs_by_indexes(ByRef $aCtrls, ByRef $aNdxs) ; returns the handles of the controls pointed to by the indexes Local $aTemp[UBound($aNdxs)] For $i = 0 To UBound($aNdxs) - 1 $aTemp[$i] = $aCtrls[$aNdxs[$i] - 1] Next Return $aTemp EndFunc ;==>__get_IDs_by_indexes Func _EndOfGame() ; _WinAPI_PlaySound ("SystemExit" , Null, $SND_ALIAS) GUIDelete() Exit EndFunc ;==>_EndOfGame P.S. At this link (https://web.archive.org/web/20131006161544/http://games.lumosity.com/chimp.html) there is a Flash version of this game.
    • By ManualIT
      Guys, i need help on creating a script that restarts a program once it starts using more than 1GB of memory.
      No idea how to start on the script, i don't know which functions i should use for process memory reading.
       
      My mind is in total blank at the moment, so i need a kick start
    • By Pricehacker
      Hello!
      Im wondering if it is possible to 'empty' the variable value to save memory, for example i often use variable as a onetime use thing and would prefer to 'forget' it after is is used
      Maybe it is just as easy as to setting $vVar = Null, but i wanted to make sure that this is the case
    • By CarlD
      Is there a reliable way to ensure that data assigned to variables in a script is overwritten or deleted when the script exits? I have scripts that encrypt/decrypt data and would like to ensure, if possible, that the encryption keys and decrypted data do not stay in memory after the script exits. Thanks.
×
×
  • Create New...