Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

What is the fastest/less resources script of these?



  • Please log in to reply
2 replies to this topic
SnowFlake_FlowSnake
  • Members
  • 845 posts
  • Last active: Jan 24 2016 05:24 PM
  • Joined: 08 Oct 2012

Hey :)

 

so i have 2 scripts that does the same things but i want to know witch one of these are the fastest one/with one uses the less resources/CPU power.

 

script 1:

/*

Memory Tester

*/

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

#SingleInstance force

ProcessName := " wow.exe"
hwnd := MemoryOpenFromName(ProcessName)

Adress = 0x0D6E9DD0

Gui, +AlwaysOnTop
Gui, Add, Text,,Adress:
Gui, Add, Text,,Value:
Gui, Add, Edit, ReadOnly ym,%Adress%
Gui, Add, Edit, ReadOnly w30 vGUI_Adress,--
Gui, Show, x0 y0 ,Memory Tester 4 byte
return

x::
Loop
{
GuiControl,, GUI_Adress, % Adress2 := MemoryReadPointer(hwnd,Adress, "int")
}
return

MemoryOpenFromName(Name)
{
    Process, Exist, %Name%
    Return DllCall("OpenProcess", "Uint", 0x1F0FFF, "int", 0, "int", PID := ErrorLevel)
}

MemoryReadPointer(hwnd, base, datatype="int", length=4, offsets=0, offset_1=0, offset_2=0, offset_3=0, offset_4=0, offset_5=0, offset_6=0, offset_7=0, offset_8=0, offset_9=0)
{
	B_FormatInteger := A_FormatInteger 
	Loop, %offsets%
	{
		baseresult := MemoryRead(hwnd,base)
		Offset := Offset_%A_Index%
		SetFormat, integer, h
		base := baseresult + Offset
		SetFormat, integer, d
	}
	SetFormat, Integer, %B_FormatInteger%
	return MemoryRead(hwnd,base,datatyp,length)
}

MemoryRead(hwnd, address, datatype="int", length=4, offset=0)
{
	VarSetCapacity(readvalue,length, 0)
	DllCall("ReadProcessMemory","Uint",hwnd,"Uint",address+offset,"Str",readvalue,"Uint",length,"Uint *",0)
	finalvalue := NumGet(readvalue,0,datatype)
	return finalvalue
}

Script 2:

/*

Memory Tester

*/

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

#SingleInstance force

Gui, +AlwaysOnTop
Gui, Add, Text,,Adress:
Gui, Add, Text,,Value:
Gui, Add, Edit, ReadOnly ym,0x0A5D14C4
Gui, Add, Edit, ReadOnly w30 vGUI_Adress,--
Gui, Show, x0 y0 ,Memory Tester 4 byte
return

x::
Loop
{
GuiControl,, GUI_Adress, % Adress2 := ReadMemory(0x0A5D14C4,"AssaultCube")
}
return

ReadMemory(MADDRESS,PROGRAM)
{
winget, pid, PID, %PROGRAM%

VarSetCapacity(MVALUE,4,0)
ProcessHandle := DllCall("OpenProcess", "Int", 24, "Char", 0, "UInt", pid, "UInt")
DllCall("ReadProcessMemory","UInt",ProcessHandle,"UInt",MADDRESS,"Str",MVALUE,"UInt",4,"UInt *",0)

Loop 4
result += *(&MVALUE + A_Index-1) << 8*(A_Index-1)
return, result 
}
return

  • Download link of my scripts on Autohotkey.com 2/10/2015 [DOWNLAND]
  • Contact Info:  https://github.com/floowsnaake //  FloowSnaake(A)gmail.com
  • IF you need Help send me a PM,Email or Post on Github

  • Quote by tank  Posted 29 September 2015 - 06:14 PM

  • "Eventually i will find a way to convert the DB back to PHPBB3. but i dont have the bandwidth right now. No one that has tried has had success. It is the Only way i can keep this open is if i could successfully convert it."

RHCP
  • Members
  • 1228 posts
  • Last active: Apr 08 2017 06:17 PM
  • Joined: 29 May 2006
✓  Best Answer

Both have drawbacks.

 

The first script opens a single process  handle and keeps it open, which is efficient, as a handle only needs to be opened once unless the program closes or restarts. However, it unnecessarily calls setformat slow. The AHK manual states that this will significantly impact script performance (disables binary caching) even if the command is never executed i.e. the command is present somewhere in the script.

 

It also calls memoryReadPointer() even though the address is not a pointer. MemoryRead() could be called directly instead. If you really wanted to get picky, there is no need to call varsetCapcity() and numget(), the DLLCall() can handle the conversion.  There's no need to initialise the variable to 0 in varsetcapacity(), as the RPM call will overwrite these bytes anyway....but that's hardly a big deal.

 

The second script calls winget, pid and openProcess on every memory read, which is highly inefficient when performing many time sensitive reads. It also neglects to close the process handles, resulting in a handle leak.  It uses a loop and bit operations to convert the result, this is slower than using numget().

 

This will be faster than either of those. The memoryRead() supports pointers too.

/*

Memory Tester

*/

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

#SingleInstance force

ProcessName := "wow.exe"
hProcess := MemoryOpenFromName(ProcessName)

Address = 0x0D6E9DD0

Gui, +AlwaysOnTop
Gui, Add, Text,,Address:
Gui, Add, Text,,Value:
Gui, Add, Edit, ReadOnly ym,%Address%
Gui, Add, Edit, ReadOnly w30 vGUI_Address,--
Gui, Show, x0 y0 ,Memory Tester 4 byte
return

x::
Loop
{
  GuiControl,, GUI_Address, % Address2 := memoryRead(hProcess, Address, "Int")
}
return

MemoryOpenFromName(Name)
{
    Process, Exist, %Name%
    Return DllCall("OpenProcess", "Uint", 0x1F0FFF, "int", 0, "UInt", PID := ErrorLevel, "Ptr")
}

; Function:          pointer32(base, finalType := "UInt", offsets*)
;                   This will read integer values of both pointers (in 32 bit programs) and non-pointers (i.e. a single memory address).
; Parameters:
;   hProcess -      Process handle
;   address  -      The base address of the pointer or the memory address for a non-pointer.
;   finalType -     The type of integer stored at the final address.
;                   Valid types are UChar, Char, UShort, Short, UInt, Int, Float, Int64 and Double. 
;                   Note: Types must not contain spaces i.e. " UInt" or "UInt " will not work. 
;                   When an invalid type is passed the method returns NULL and sets ErrorLevel to -2
;   offsets* -     A variadic list of offsets used to calculate the pointers final address.
; Return Values: (The same as the read() method)
;       integer -   Indicates success.
;       Null    -   Indicates failure. Check A_LastError for more information.
;       Note:       Since the returned integer value may be 0, to check for success/failure compare the result
;                   against null i.e. if (result = "") then an error has occurred.
; examples:
; Read a pointer with offsets 0x20 and 0x15C which points to a UChar. 
;    value := pointer32(hProcess, pointerBase, "UChar", 0x20, 0x15C)
; or
;    arrayPointerOffsets := [0x20, 0x15C]
;    value := pointer32(hProcess, pointerBase, "UChar", arrayPointerOffsets*)


pointer32(hProcess, address, finalType := "UInt", offsets*)
{ 
    For index, offset in offsets
        address := memoryRead(hProcess, address) + offset 
    Return memoryRead(hProcess, address, finalType)
}

; Method:   read(address, type := "UInt", aOffsets*)
;           Reads various integer type values. Supports pointers in 32 bit applications.
; Parameters:
;       address -   The memory address of the value or if using the offset parameter, 
;                   the base address of the pointer.
;       type    -   The integer type. 
;                   Valid types are UChar, Char, UShort, Short, UInt, Int, Float, Int64 and Double. 
;                   Note: Types must not contain spaces i.e. " UInt" or "UInt " will not work. 
;                   When an invalid type is passed the method throws an error.
;       offsets* - A variadic list of offsets. When using offsets the address parameter should equal the base address of the pointer.
;                   The address (bass address) and offsets should point to the memory address which holds the integer.  
; Return Values:
;       integer -   Indicates success.
;       Null    -   Indicates failure. Check A_LastError for more information.
;       Note:       Since the returned integer value may be 0, to check for success/failure compare the result
;                   against null i.e. if (result = "") then an error has occurred.
;                   When reading doubles, adjusting "SetFormat, float, totalWidth.DecimalPlaces"
;                   may be required depending on your requirements.
; Examples:
;   Read a UInt at address 0x0016CB60
;       value := memoryRead(hProcess, 0x0016CB60)
;   Read a pointer with offsets 0x20 and 0x15C which points to a UChar. 
;       memoryRead(hProcess, pointerBase, "UChar", 0x20, 0x15C)
;   Or
;       arrayPointerOffsets := [0x20, 0x15C]
;       memoryRead(hProcess, pointerBase, "UChar", arrayPointerOffsets*)


memoryRead(hProcess, address, dataType := "UInt", offsets*)
{
    static aTypeSize := {   "UChar":    1,  "Char":     1
                        ,   "UShort":   2,  "Short":    2
                        ,   "UInt":     4,  "Int":      4
                        ,   "UFloat":   4,  "Float":    4 ; No such thing as a UFloat, but AHK treats it as a float so it 'works'
                        ,   "Int64":    8,  "Double":   8}

    if !aTypeSize.HasKey(dataType)
        throw, "MemoryRead()`n" dataType "`nIs an invalid data type!"
    if DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", offsets.MaxIndex() ? offsets.Remove() + pointer32(hProcess, address, "UInt", offsets*) : address, dataType "*", result, "Ptr", aTypeSize[dataType], "Ptr", 0)
        return result
    return ; return null/blank on error
}




SnowFlake_FlowSnake
  • Members
  • 845 posts
  • Last active: Jan 24 2016 05:24 PM
  • Joined: 08 Oct 2012

wow thank you so much RHCP this is really helpful  :D


  • Download link of my scripts on Autohotkey.com 2/10/2015 [DOWNLAND]
  • Contact Info:  https://github.com/floowsnaake //  FloowSnaake(A)gmail.com
  • IF you need Help send me a PM,Email or Post on Github

  • Quote by tank  Posted 29 September 2015 - 06:14 PM

  • "Eventually i will find a way to convert the DB back to PHPBB3. but i dont have the bandwidth right now. No one that has tried has had success. It is the Only way i can keep this open is if i could successfully convert it."