Memory search not working ingame Topic is solved

Ask gaming related questions (AHK v1.1 and older)
Mightykiller
Posts: 57
Joined: 09 Oct 2017, 13:34

Memory search not working ingame

01 Jan 2018, 19:37

I am trying this script to detect a string in a game, but it doesn't detect anything i tried this script with many appications and it works fine but in games it doesn't work, am i missing something ?

Code: Select all

#Include <classMemory>
#SingleInstance Force
if (_ClassMemory.__Class != "_ClassMemory")
{
    msgbox class memory not correctly installed. 
    ExitApp
}



TargetProcess := new _ClassMemory("ahk_exe war3.exe", "", hProcessCopy)
myAOBstringpattern := "test2"
ConvertBase(InputBase, OutputBase, number)
{
	static u := A_IsUnicode ? "_wcstoui64" : "_strtoui64"
	static v := A_IsUnicode ? "_i64tow"    : "_i64toa"
	VarSetCapacity(s, 65, 0)
	value := DllCall("msvcrt.dll\" u, "Str", number, "UInt", 0, "UInt", InputBase, "CDECL Int64")
	DllCall("msvcrt.dll\" v, "Int64", value, "Str", s, "UInt", OutputBase, "CDECL")
	return s
}

Loop
{
	myAOBscan := TargetProcess.stringToPattern(myAOBstringpattern, "UTF-16")    
	myAOBaddressdec := TargetProcess.processPatternScan(,, myAOBscan*)
	if (myAOBaddressdec > 0) ;AOB found, stop scanning and convert it from decimal to hexadecimal
	{
		myAOBaddresshex := "0x" ConvertBase(10, 16, myAOBaddressdec)		
        SendInput, {raw}working
		SendInput {enter}
	}
	else ;AOB not found, continue scanning
	{
		Sleep,500

    }

}
Last edited by Mightykiller on 06 Jan 2018, 19:01, edited 1 time in total.
Mightykiller
Posts: 57
Joined: 09 Oct 2017, 13:34

Re: Memory search not working ingame

06 Jan 2018, 19:00

Any one would love to reply?
RHCP
Posts: 202
Joined: 30 Sep 2013, 10:59

Re: Memory search not working ingame

06 Jan 2018, 23:19

What game is it? An old version of warcraft 3?

Try using UTF-8 encoding.

Code: Select all

myAOBscan := TargetProcess.stringToPattern(myAOBstringpattern, "UTF-8")
Also, ensure you are successfully opening a handle to the program. This will provide an error if it fails.

Code: Select all

            
            TargetProcess := new _ClassMemory("ahk_exe war3.exe", "", hProcessCopy)
            if !isObject(TargetProcess) 
            {
                msgbox failed to open a handle
                if (hProcessCopy = 0)
                    msgbox The program isn't running (not found) or you passed an incorrect program identifier parameter. 
                else if (hProcessCopy = "")
                    msgbox OpenProcess failed. If the target process has admin rights, then the script also needs to be ran as admin. Consult A_LastError for more information.
                ExitApp
            }
Mightykiller
Posts: 57
Joined: 09 Oct 2017, 13:34

Re: Memory search not working ingame

25 Jan 2018, 16:46

Hi,
Yeah it seems that it doesn't detect war3.exe i don't know why i tried everything process ID title etc nothing works, i tried using the script with other programs and it works fine.
So why does it not work with warcraft3?

errors:
Failed to open a handle
The program isn't running (not found) or you passed an incorrect program identifier parameters.

Screenshot_2.png
Screenshot_2.png (25.15 KiB) Viewed 2289 times

Code: Select all

#Include <classMemory>
#SingleInstance Force

IF NOT A_IsAdmin
{
   Run *RunAs "%A_ScriptFullPath%"
   ExitApp
}



if (_ClassMemory.__Class != "_ClassMemory")
{
    msgbox class memory not correctly installed. 
    ExitApp
}


SetTitleMatchMode 2
TargetProcess := new _ClassMemory("ahk_exe war3.exe", "", hProcessCopy)
            if !isObject(TargetProcess) 
            {
                msgbox failed to open a handle
                if (hProcessCopy = 0)
                    msgbox The program isn't running (not found) or you passed an incorrect program identifier parameter. 
                else if (hProcessCopy = "")
                    msgbox OpenProcess failed. If the target process has admin rights, then the script also needs to be ran as admin. Consult A_LastError for more information.
                ExitApp
            }
myAOBstringpattern := "test2222"
myAOBaddresshex := Format("0x{:x}", myAOBaddressdec)
ConvertBase(InputBase, OutputBase, number)
{
	static u := A_IsUnicode ? "_wcstoui64" : "_strtoui64"
	static v := A_IsUnicode ? "_i64tow"    : "_i64toa"
	VarSetCapacity(s, 65, 0)
	value := DllCall("msvcrt.dll\" u, "Str", number, "UInt", 0, "UInt", InputBase, "CDECL Int64")
	DllCall("msvcrt.dll\" v, "Int64", value, "Str", s, "UInt", OutputBase, "CDECL")
	return s
}

Loop
{

    StringLeft, thedetectedstring, myAOBstringpattern, 4  ; Stores the string "This" in OutputVar.
    StringRight, thedetectedstring, myAOBstringpattern, 4  ; Stores the string "test." in OutputVar.
	myAOBscan := TargetProcess.stringToPattern(myAOBstringpattern, "UTF-8")    
	myAOBaddressdec := TargetProcess.processPatternScan(,, myAOBscan*)
	if (myAOBaddressdec > 0) ;AOB found, stop scanning and convert it from decimal to hexadecimal
	{
		
        msgbox, %myAOBaddressdec%
        
	}
	else ;AOB not found, continue scanning
	{
		Sleep,500

    }

}
Mightykiller
Posts: 57
Joined: 09 Oct 2017, 13:34

Re: Memory search not working ingame

27 Jan 2018, 15:12

Reply please RHCP
RHCP
Posts: 202
Joined: 30 Sep 2013, 10:59

Re: Memory search not working ingame

27 Jan 2018, 19:16

I actually still have warcraft 3 TFT (fully updated) installed on this computer - win10 64, AHK 32 bit. It works perfectly fine here, so im not sure.

When the game is running, is war3.exe listed as the running executable in the task manager?

From the info provided it would seem that this function is failing - returning 0.

Code: Select all

findPID(program, windowMatchMode := "3")
    {
        ; If user passes an AHK_PID, don't bother searching. There are some very rare cases where searching windows for PIDs 
        ; wont work - console apps
        if RegExMatch(program, "Ai)\s*AHK_PID\s+(0x[[:xdigit:]]+|\d+)", pid)
            return pid1
        if windowMatchMode
        {
            ; This is a string and will not contain the 0x prefix
            mode := A_TitleMatchMode
            ; remove hex prefix as SetTitleMatchMode will throw a run time error. This will occur if integer mode is set to hex and user passed an int (unquoted)
            StringReplace, windowMatchMode, windowMatchMode, 0x 
            SetTitleMatchMode, %windowMatchMode%
        }
        WinGet, pid, pid, %program%
        if windowMatchMode
            SetTitleMatchMode, %mode%    ; In case executed in autoexec
        return pid ? pid : 0 ; PID is null on fail, return 0
    }

Perhaps you could try different window identifiers, and windowMatchMode settings (though neither should be required....) e.g.

Code: Select all

#Include <classMemory>
#SingleInstance Force

IF NOT A_IsAdmin
{
   Run *RunAs "%A_ScriptFullPath%"
   ExitApp
}


; If the msgbox contains a number other than 0, then it worked.
msgbox % _ClassMemory.findPID("ahk_exe War3.exe")
msgbox % _ClassMemory.findPID("ahk_exe war3.exe")

msgbox % _ClassMemory.findPID("ahk_exe War3.exe", "2")
msgbox % _ClassMemory.findPID("ahk_exe war3.exe", "2")

msgbox % _ClassMemory.findPID("Warcraft", "2")

ExitApp

Finally, can you post the code you used to retrieve and test using the PID as the ID?

Cheers.
Mightykiller
Posts: 57
Joined: 09 Oct 2017, 13:34

Re: Memory search not working ingame

29 Jan 2018, 18:33

Code: Select all

msgbox % _ClassMemory.findPID("Warcraft", "2")0  ;shows me the PID  "8276" the others show 0
still cant get it to work :'(
war3.png
war3.png (1.93 KiB) Viewed 2730 times

Code: Select all

#Include <classMemory>
#SingleInstance Force
DetectHiddenWindows, On

IF NOT A_IsAdmin
{
   Run *RunAs "%A_ScriptFullPath%"
   ExitApp
}



if (_ClassMemory.__Class != "_ClassMemory")
{
    msgbox class memory not correctly installed. 
    ExitApp
}

;msgbox % _ClassMemory.findPID("Warcraft", "2")

TargetProcess := new _ClassMemory("ahk_pid 8276", "", hProcessCopy)
            if !isObject(TargetProcess) 
            {
                msgbox failed to open a handle
                if (hProcessCopy = 0)
                    msgbox The program isn't running (not found) or you passed an incorrect program identifier parameter. 
                else if (hProcessCopy = "")
                    msgbox OpenProcess failed. If the target process has admin rights, then the script also needs to be ran as admin. Consult A_LastError for more information.
                ExitApp
            }
            
            
            
            
            
myAOBstringpattern := "test"
myAOBaddresshex := Format("0x{:x}", myAOBaddressdec)
ConvertBase(InputBase, OutputBase, number)
{
	static u := A_IsUnicode ? "_wcstoui64" : "_strtoui64"
	static v := A_IsUnicode ? "_i64tow"    : "_i64toa"
	VarSetCapacity(s, 65, 0)
	value := DllCall("msvcrt.dll\" u, "Str", number, "UInt", 0, "UInt", InputBase, "CDECL Int64")
	DllCall("msvcrt.dll\" v, "Int64", value, "Str", s, "UInt", OutputBase, "CDECL")
	return s
}

Loop
{

    StringLeft, thedetectedstring, myAOBstringpattern, 4  ; Stores the string "This" in OutputVar.
    StringRight, thedetectedstring, myAOBstringpattern, 4  ; Stores the string "test." in OutputVar.
	myAOBscan := TargetProcess.stringToPattern(myAOBstringpattern, "UTF-8")    
	myAOBaddressdec := TargetProcess.processPatternScan(,, myAOBscan*)
	if (myAOBaddressdec > 0) ;AOB found, stop scanning and convert it from decimal to hexadecimal
	{
		
        msgbox, %myAOBaddressdec%
        
	}
	else ;AOB not found, continue scanning
	{
		Sleep,500

    }

}
RHCP
Posts: 202
Joined: 30 Sep 2013, 10:59

Re: Memory search not working ingame

29 Jan 2018, 21:54

When specifying the PID as the ID, if the error message presented is
OpenProcess failed. If the target process has admin rights, then the script also needs to be ran as admin. Consult A_LastError for more information.
(Instead of 'the program isn't running / not found)

Then you could try calling _ClassMemory.setSeDebugPrivilege(), e.g.

Code: Select all

#Include <classMemory>
#SingleInstance Force
DetectHiddenWindows, On

IF NOT A_IsAdmin
{
   Run *RunAs "%A_ScriptFullPath%"
   ExitApp
}


_ClassMemory.setSeDebugPrivilege()


msgbox % _ClassMemory.findPID("Warcraft", "2") ; make sure the PID matches PID listed in task manager

TargetProcess := new _ClassMemory("Warcraft", "2", hProcessCopy)

if !isObject(TargetProcess) 
{
    if (hProcessCopy = 0)
        msgbox The program isn't running (not found) or you passed an incorrect program identifier parameter. 
    else if (hProcessCopy = "")
        msgbox OpenProcess failed. If the target process has admin rights, then the script also needs to be ran as admin. Consult A_LastError for more information.
    ExitApp
}

msgbox success
When specifying the PID as the ID (as in your last example), the only thing which could fail is the call to OpenProcess().... so you might have to look at ErrorLevel to debug it.

Cheers.
RHCP
Posts: 202
Joined: 30 Sep 2013, 10:59

Re: Memory search not working ingame  Topic is solved

23 Feb 2018, 01:35

In response to your PM, for some reason with your 'special' version of warcraft the 'winget, pid,PID, ahk_exe war3.exe' command (which is used internally in the class) fails, but 'winget, pid,PID, Warcraft III' works fine.
You need to either use the wintitle 'Warcraft III' or use the 'ahk_pid xxxx'.
You must also run the script as admin AND enable setSeDebugPrivilege().

The code below works with your warcraft version.

Code: Select all

#SingleInstance Force
#Include <classMemory>

if !A_IsAdmin 
{
        Run *RunAs "%A_ScriptFullPath%"
        exitapp 
}


if (_ClassMemory.__Class != "_ClassMemory")
{
    msgbox class memory not correctly installed. 
    ExitApp
}


_ClassMemory.setSeDebugPrivilege() ; Required

; get the pid using an alternate method.
for process in ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process where Name='war3.exe'")
{
    pid := process.ProcessId 
}


TargetProcess := new _ClassMemory("ahk_pid " pid,, hProcessCopy)
;TargetProcess := new _ClassMemory("Warcraft III",, hProcessCopy) ; This also works fine.

if !isObject(TargetProcess) 
{
    if (hProcessCopy = 0)
        msgbox The program isn't running (not found) or you passed an incorrect program identifier parameter. 
    else if (hProcessCopy = "")
        msgbox OpenProcess failed. If the target process has admin rights, then the script also needs to be ran as admin. _ClassMemory.setSeDebugPrivilege() may also be required. Consult A_LastError for more information.
    ExitApp
}


myAOBstringpattern := "test2"

Loop
{
    myAOBscan := TargetProcess.stringToPattern(myAOBstringpattern, "UTF-8")    
    myAOBaddressdec := TargetProcess.processPatternScan(,, myAOBscan*)
    if (myAOBaddressdec > 0) ;AOB found, stop scanning and convert it from decimal to hexadecimal
    {
        myAOBaddresshex := "0x" ConvertBase(10, 16, myAOBaddressdec)        
        msgbox found at %myAOBaddresshex%
    }
    else ;AOB not found, continue scanning
    {
        Sleep, 500
    }

}


ConvertBase(InputBase, OutputBase, number)
{
    static u := A_IsUnicode ? "_wcstoui64" : "_strtoui64"
    static v := A_IsUnicode ? "_i64tow"    : "_i64toa"
    VarSetCapacity(s, 65, 0)
    value := DllCall("msvcrt.dll\" u, "Str", number, "UInt", 0, "UInt", InputBase, "CDECL Int64")
    DllCall("msvcrt.dll\" v, "Int64", value, "Str", s, "UInt", OutputBase, "CDECL")
    return s
}

Edit:

I had another play around with this tonight and realised something pretty obvious...
providing you call _ClassMemory.setSeDebugPrivilege(), using AHK_exe war3.exe works fine.
e.g.

Code: Select all

#SingleInstance Force
#Include <classMemory>

if !A_IsAdmin 
{
        Run *RunAs "%A_ScriptFullPath%"
        exitapp 
}


if (_ClassMemory.__Class != "_ClassMemory")
{
    msgbox class memory not correctly installed. 
    ExitApp
}


_ClassMemory.setSeDebugPrivilege() ; Required - must be first thing called


TargetProcess := new _ClassMemory("ahk_exe war3.exe",, hProcessCopy)


if !isObject(TargetProcess) 
{
    if (hProcessCopy = 0)
        msgbox The program isn't running (not found) or you passed an incorrect program identifier parameter. 
    else if (hProcessCopy = "")
        msgbox OpenProcess failed. If the target process has admin rights, then the script also needs to be ran as admin. _ClassMemory.setSeDebugPrivilege() may also be required. Consult A_LastError for more information.
    ExitApp
}


myAOBstringpattern := "test2"

Loop
{
    myAOBscan := TargetProcess.stringToPattern(myAOBstringpattern, "UTF-8")    
    myAOBaddressdec := TargetProcess.processPatternScan(,, myAOBscan*)
    if (myAOBaddressdec > 0) ;AOB found, stop scanning and convert it from decimal to hexadecimal
    {
        myAOBaddresshex := "0x" ConvertBase(10, 16, myAOBaddressdec)        
        msgbox found at %myAOBaddresshex%
    }
    else ;AOB not found, continue scanning
    {
        Sleep, 500
    }

}


ConvertBase(InputBase, OutputBase, number)
{
    static u := A_IsUnicode ? "_wcstoui64" : "_strtoui64"
    static v := A_IsUnicode ? "_i64tow"    : "_i64toa"
    VarSetCapacity(s, 65, 0)
    value := DllCall("msvcrt.dll\" u, "Str", number, "UInt", 0, "UInt", InputBase, "CDECL Int64")
    DllCall("msvcrt.dll\" v, "Int64", value, "Str", s, "UInt", OutputBase, "CDECL")
    return s
}
Mightykiller
Posts: 57
Joined: 09 Oct 2017, 13:34

Re: Memory search not working ingame

24 Feb 2018, 19:39

Yeah now it works thanks mate.

Return to “Gaming Help (v1)”

Who is online

Users browsing this forum: No registered users and 56 guests