Jump to content

Reading memory "double"


toto22
 Share

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

One obvious error is that the MsgBox function requires at least 3 parameters.

MsgBox ( flag, "title", "text" [, timeout = 0 [, hwnd]] )

 

Link to comment
Share on other sites

What version of AutoIt are you using?  I don't see a _MemoryOpen function in 3.3.14.2.

 

Link to comment
Share on other sites

  • Moderators

@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!

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

Link to comment
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)"

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

Link to comment
Share on other sites

  • 2 weeks later...

@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). 

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

 

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

×
×
  • Create New...