Jump to content
Sign in to follow this  
jplumb

Yikes! Read/write memory of apps in BlueStacks!?

Recommended Posts

jplumb

Okay, this might be a long-shot, but I've been digging everywhere and had no luck. Maybe I'm not using the right search terms...

I am trying to make an automated script that assists with inventory for work. They use an Android app and, unfortunately (or fortunately, depending on your perspective) I have an iPhone...so I've downloaded BlueStacks on my laptop and do all of my inventory through that, and it works fine.

I recently began trying to use AutoIt to automate some of the process for me, and I wrote a decent pixel scanner to help me out, but I want to take it one step further and use memory reading and writing to make it more efficient. The pixel reader I've made is about 95% accurate, but it would be nice to know my script is 100% accurate...

I have a working knowledge of memory editing on the PC and have written a few in C#, but it doesn't seem to be the same in an app within an emulator within Windows. I've found the correct process to attach to when the app is open in Windows (outside of BlueStacks), and I can successfully locate the memory outside of BlueStacks (just using a general memory search program within Windows). I can see the values change in the memory reader as I change them inside of BlueStacks, so I know I have the right addresses.

However, I've tried both krymemory.au3 and nomadmemory.au3 to try to read those addresses in AutoIt, and I always get "0" for whatever I try to read.

Example:

Local $process = _MemoryOpen("HD-Player.exe")
Local $result = _MemoryRead(0x9E1E0E94, $process)

There are no errors, no nothing. Just get a "0" no matter what address I try to read.

Does anybody know how I can get this to work? Thanks.

Share this post


Link to post
Share on other sites
Bilgus

HEY what is the square root of these three numbers added together?

Hard telling huh? about the same with what I see in your post going to need a minimum amount of code that reproduces your issue 

Before anyone is even going to attempt to address your problem

about all I can say ATM is maybe run as administrator ??

Share this post


Link to post
Share on other sites
jplumb

Okay, let me put a bare-bones...

#RequireAdmin
#include <various includes...>

#include "NomadMemory.au3"

Init()

Func Init()
    Global $iPaperOnHand = 0x9E1E0E94
    Global $process = _MemoryOpen("HD-Player.exe")

    Opt("GUIOnEventMode",1)
    Global $MainWindow = GUICreate("Inventory Handler", 320, 480)
    Global $LogBox = GUICtrlCreateEdit("", 4, 4, 312, 452)
    Global $CountButton = GUICtrlCreateButton("Start", 4, 460, 308, 20)
    
    GUISetOnEvent($GUI_EVENT_CLOSE, "CloseApp")
    GUICtrlSetOnEvent($CountButton, "OnCount")
    GUISetState(@SW_SHOW)
    
    Echo("Initialization Complete.")
EndFunc
    
Func OnCount()
    Local $result = _MemoryRead($iPaperOnHand, $process)
    Echo($result)
EndFunc

Func CloseApp()
    Exit
EndFunc

Func Echo($s)
    $old = GUICtrlRead($LogBox)
    $iEnd = StringLen(GUICtrlRead($LogBox))
    GUICtrlSetData($LogBox, $old & _NowTime() & ": " & $s & @CRLF)
    _GUICtrlEdit_SetSel($LogBox, $iEnd, $iEnd)
    _GUICtrlEdit_Scroll($LogBox, $SB_SCROLLCARET)
EndFunc

Now, I open BlueStacks (it's always open as Administrator), open my app, use my Windows memory scanner to find the value of my "Paper" "on hand" block, adjusting it until I find the right address, then I put that address into my $iPaperOnHand variable.

Run the program, and I get "0" no matter what I try.

Share this post


Link to post
Share on other sites
Bilgus

Ok So before even running it I see 

_MemoryOpen("HD-Player.exe")

Looking in the UDF indicates it requires a PID

at the very least you need something like this 

WinGetProcess ( "title" [, "text"] )

Or if you create the process run returns the PID of the process

Func _MemoryOpen($iv_Pid, $iv_DesiredAccess = 0x1F0FFF, $iv_InheritHandle = 1)
    
    If Not ProcessExists($iv_Pid) Then
        SetError(1)
        Return 0
    EndIf

 

Edited by Bilgus

Share this post


Link to post
Share on other sites
Ascer

@jplumb

Take a look here

Just replace process name to your process and this line

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

To this

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

 

Share this post


Link to post
Share on other sites
jplumb

Still get "0" while attempting all of your solutions. @Bilgus, you're definitely right that I needed the process though and not just the name of the process, I forgot to change that when I switched back over to trying NomadMemory instead of KryMemory (which KryMemory says it requires a string value of the process name, not a pid).

I'll have to take another look at this tomorrow. Thanks for the help guys.

Share this post


Link to post
Share on other sites
Bilgus

One thing to note is that this is using ReadProcessMemory(0 and on MSDN there are a few caveats to using it that you may be running up against

the other thing is that you probably need to use the script as 64Bit

 

Share this post


Link to post
Share on other sites
Ascer

Let's thing...

1. Make sure that you put good Address and Process name in my code created for Toto22

2. Check address value using other program to verify if not 0.

3. Run code...

4. When result is equal 0 just one reason. You try to access proteced process and it's against forum rules then thread will locked.

Share this post


Link to post
Share on other sites
Bilgus

Well thats funny 

Quote

You try to access proteced process and it's against forum rules then thread will locked

I tried Scite with your code and Nomad memory and got a return of 0 as well is that a protected process that will get the thread locked?

Share this post


Link to post
Share on other sites
Ascer

About Scite...

There is not address in program memory

0x1FECD474

You have to type example base address to get value

0x00400000
; ++ Successfully read memory at addr 0x00400000 value is 9460301

Also example given for toto22 was reading for double so you should replace lines..

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

To this

Local $tagStruct = "struct;dword var1;endstruct"
Edited by Ascer

Share this post


Link to post
Share on other sites
Bilgus
#RequireAdmin
;#include <various includes...>

#include <array.au3>
#include "NomadMemory.au3"
Global Const $GUI_EVENT_CLOSE = -0x3
Global $g_sWndName = "- scite"
Global $iPaperOnHand = 0x0
Global $aProcess
Init()
While 1
Wend
Func Init()

    Opt("GUIOnEventMode",1)
    Global $MainWindow = GUICreate("Inventory Handler", 320, 480)
    Global $LogBox = GUICtrlCreateEdit("", 4, 4, 312, 452)
    Global $CountButton = GUICtrlCreateButton("Start", 4, 460, 308, 20)

    GUISetOnEvent($GUI_EVENT_CLOSE, "CloseApp")
    GUICtrlSetOnEvent($CountButton, "OnCount")
    GUISetState(@SW_SHOW)
    Local $hPid = WinGetProcess ( "[REGEXPTITLE:(?i)(.*" & $g_sWndName & ".*)]")
    Local $aWin = _WinGetByPID($hPid, 0)
    _ArrayDisplay($aWin)
    
    $aProcess = _MemoryOpen($hPid)
    If Not $hPid or @error then MsgBox(0,"Error", "Unable to open process" & " some process")

    Echo("Initialization Complete.")

EndFunc

Func OnCount()
    Local $iError = 0
    do
        $iPaperOnHand += 1
        Local $result = _MemoryRead($iPaperOnHand, $aProcess, "BYTE") ;<DWord = 32 bits Word = 16 bits Byte = 8 bits
        $iError = @error
    Until $iError or $result <> 0
    Echo($result & ":Add:" & "0x" & Hex($iPaperOnHand) & ":Err:" & $iError)
EndFunc

Func CloseApp()
    _MemoryClose($aProcess)
    Exit
EndFunc

Func Echo($s)
    $old = GUICtrlRead($LogBox)
    $iEnd = StringLen(GUICtrlRead($LogBox))
    GUICtrlSetData($LogBox, $old & "" & ": " & $s & @CRLF)
    ;Must be in various includes??_GUICtrlEdit_SetSel($LogBox, $iEnd, $iEnd)
    ;Must be in various includes??_GUICtrlEdit_Scroll($LogBox, $SB_SCROLLCARET)
EndFunc

Func _WinGetByPID($iPID, $iArray = 1) ; 0 Will Return 1 Base Array & 1 Will Return The First Window.;SmOke_N
    Local $aError[1] = [0], $aWinList, $sReturn
    If IsString($iPID) Then
        $iPID = ProcessExists($iPID)
    EndIf
    $aWinList = WinList()
    For $A = 1 To $aWinList[0][0]
        If WinGetProcess($aWinList[$A][1]) = $iPID And BitAND(WinGetState($aWinList[$A][1]), 2) Then
            If $iArray Then
                Return $aWinList[$A][1]
            EndIf
            $sReturn &= $aWinList[$A][1] & Chr(1)
        EndIf
    Next
    If $sReturn Then
        Return StringSplit(StringTrimRight($sReturn, 1), Chr(1))
    EndIf
    Return SetError(1, 0, $aError)
EndFunc   ;==>_WinGetByPID

 

My issue ended up being What Pid I was actually grabbing

This should help OP get a bit better 'handle' on what he is doing

Share this post


Link to post
Share on other sites
jplumb

Still no dice.

You know, if for some reason the app developer put things in protected memory, then I guess it's not the end of the world. I've been doing inventory manually for years...I can survive to do it manually longer.

Thanks for the help guys, I really appreciate the time you've given.

Share this post


Link to post
Share on other sites
jplumb

As a workaround, I just rewrote my memory reading program to export the values in an XML file, that updates whenever the values change, and then I just check for changes in that XML file in my AutoIt script!

Works like a charm.

  • Like 1

Share this post


Link to post
Share on other sites
Earthshine

nice. usually there is more than one way to skin a cat

  • Like 1

My resources are limited. You must ask the right questions

 

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  

×