Jump to content

Get the actual true pointer for an Autoit native variable (Updated)


Recommended Posts

Posted (edited)

I just found ultra manipulative and very tricky way to get the pointer for Autoit native variable.
This is not getting pointer of Struc variable type (created with DllStructCreate() ). this is way how to get pointer for native Autoit variable so you can able to change & read Autoit native variable from outside in very directly way (even from c++ if you want)

 This is exactly the answer to threads like this:

 

 

 

CODE OUTPUT:

Quote

Declaring the $variable...
Looking for the true pointer of $variable
The pointer for $variable (Autoit native variable) is: 0x0074BB30

Reading the $variable using Autoit native ---> $variable is equal to: -1234562457
Reading the $variable using _MemoryRead ---> $variable is equal to: -1234562457

Changing the $variable to 5697 with _MemoryWrite(*) -> Reading the $variable using Autoit native -> $variable is equal to: 5697


CODE:

#include 'NomadMemory.au3'

; Code how to get the pointer for NORMAL AUTOIT variable (native variable)

Global Const $iIdentifyingMark = -1234562457

$hMem = _MemoryOpen(@AutoItPID) ; Open the memory of this Autoit
If @error Then Exit ConsoleWrite(@ScriptLineNumber & @CRLF) ; Error opening the memory

ConsoleWrite('Declaring the $variable...' & @CRLF)
$variable = DllStructCreate('int') ; Create variable as struct to get its pointer
$variable_pointer = DllStructGetPtr($variable) ; Get the pointer for the struct variable
$variable = $iIdentifyingMark ; Change the variable "back" to normal autoit variable

ConsoleWrite('Looking for the true pointer of $variable' & @CRLF)
; Look for the pointer for the normal autoit variable with the help of $variable_pointer
Local $data_from_memread, $variable_updated_pointer_found
For $variable_updated_pointer = Int(Number($variable_pointer)*0.999) To Int(Number($variable_pointer)*1.001)
    $data_from_memread = _MemoryRead($variable_updated_pointer, $hMem,'int')
    ; Check if the value of the pointer is equal to $variable. If so then there is high chance that we found it
    If $data_from_memread <> $variable Then ContinueLoop
    ; If this area executed then $variable must be equal to $data_from_memread
    ; next: Check if the founded pointer is correct one
    $variable = 1 ; Set the $variable to be 1
    $data_from_memread = _MemoryRead($variable_updated_pointer, $hMem,'int') ; Now read the the $variable through the pointer
    If $data_from_memread = $variable Then ; Check again if the value we got using this pointer is equal to $variable
        ; YES!! we found it! this is the correct pointer
        $variable_updated_pointer_found = 1
        $variable = $iIdentifyingMark
        ExitLoop ; Exit now to continue to the magic
    Else
        ; if not then this is the worng one :( so we try again and reset...
        $variable = $iIdentifyingMark
    EndIf
Next


If Not $variable_updated_pointer_found Then Exit ConsoleWrite("Sorry, I didn't found the pointer :(" & @CRLF)
; If this area executed then this is very good news. Because you're going to see here magic
$variable_updated_pointer = Ptr($variable_updated_pointer)
ConsoleWrite('The pointer for $variable (Autoit native variable) is: '& $variable_updated_pointer & @CRLF & @CRLF)


ConsoleWrite('Reading the $variable using Autoit native ---> ')
ConsoleWrite('$variable is equal to: '&$variable & @CRLF)

ConsoleWrite('Reading the $variable using _MemoryRead ---> ')
ConsoleWrite('$variable is equal to: '&_MemoryRead($variable_updated_pointer, $hMem, 'int') & @CRLF&@CRLF)



$iNewValue = Random(1,10000,1)
ConsoleWrite('Changing the $variable to '&$iNewValue&' with _MemoryWrite(*) -> ')
_MemoryWrite($variable_updated_pointer, $hMem, $iNewValue, 'int')
ConsoleWrite('Reading the $variable using Autoit native -> $variable is equal to: '&$variable & @CRLF )

 

I still didn't made function for this but I will create one later

 

UPDATE 1:
After making a few basic tests, this  technique of getting the pointer seems to be very unstable.
As a result, I abandoned this direction.


The unstable is increasing when there is more and more data in the script
and it does not even matter if data was used (for example local variable inside function that not been declared yet)
The fact the the data is exists - increases the  instability of this  method.

But, what can help to increase stability of this method is to make to change line:
 

For $variable_updated_pointer = Int(Number($variable_pointer)*0.999) To Int(Number($variable_pointer)*1.001)

to something like this:
 

For $variable_updated_pointer = Int(Number($variable_pointer)*0.9) To Int(Number($variable_pointer)*1.1)

 

But this solution is bad because it makes the process to be much more slow (takes about 30 seconds to finish).


This is the function that I started to write and stopped because of the instability of this method:
 

#include 'NomadMemory.au3'

#Region GetVariablePointer - variabls declarations:

#EndRegion

; Code how to get the pointer for NORMAL AUTOIT variable (native variable)

Global $Variable = 123
$ptr = GetVariablePointer($Variable)
ConsoleWrite($ptr & @CRLF)



#Region GetVariablePointer
Func GetVariablePointer(ByRef $Variable,$Autoit_hMem = 0)
    If Not IsArray($Autoit_hMem) Then
        Local $hMem = _MemoryOpen(@AutoItPID) ; Open the memory of this Autoit
        If @error Then Return SetError(@ScriptLineNumber) ; Error opening the memory
    Else
        Local $hMem = $Autoit_hMem
    EndIf

    Local Const $UniqueValue = -1234562457
    Local $SavedValue = $Variable,$VariablePtr,$PtrFound
    $Variable = DllStructCreate('int') ; Create variable as struct to get its pointer
    $VariablePtr = DllStructGetPtr($Variable) ; Get the pointer for the struct variable
    $Variable = $UniqueValue ; Change the variable "back" to normal autoit variable

    For $NewPtr = Int(Number($VariablePtr)*0.9) To Int(Number($VariablePtr)*1.1)

        ; Check if the value of the pointer is equal to $variable. If so then there is high chance that we found it
        If _MemoryRead($NewPtr, $hMem,'int') <> $Variable Then ContinueLoop
        ; If this area executed then $variable must be equal to $data_from_memread
        ; next: Check if the founded pointer is correct one
        $Variable = 1 ; Set the $variable to be 1
        If _MemoryRead($NewPtr, $hMem,'int') = $Variable Then ; Check again if the value we got using this pointer is equal to $variable
            ; YES!! we found it! this is the correct pointer
            $PtrFound = 1
            ExitLoop ; Exit now to continue to the magic
        Else
            ; if not then this is the worng one :( so we try again and reset...
            $Variable = $UniqueValue
        EndIf
    Next
    $Variable = $SavedValue
    If IsArray($Autoit_hMem) Then _MemoryClose($Autoit_hMem)
    If $PtrFound Then Return Ptr($NewPtr)
    Return SetError(@ScriptLineNumber,0,0) ; Failed to find the pointer
EndFunc

#EndRegion




#Region Internal Use for GetVariablePointer

; Thenks to https://www.autoitscript.com/forum/topic/113824-windows-data-types/
Func _MSDNDataType($sType) ; Idea by wolf9228, code by guinness.
    Local $aType[157][2] = [[156, 2],['ATOM', 'WORD'],['BOOL', 'BOOL'],['BOOLEAN', 'BOOLEAN'],['BYTE', 'BYTE'],['CHAR', 'str'], _
            ['COLORREF', 'DWORD'],['CONST', 'const'],['DWORD', 'DWORD'],['DWORDLONG', 'ULONG'],['DWORD_PTR', 'DWORD_PTR'], _
            ['DWORD32', 'UINT'],['DWORD64', 'INT64'],['FLOAT', 'FLOAT'],['HACCEL', 'HANDLE'],['HALF_PTR', 'ptr'], _
            ['HANDLE', 'HANDLE'],['HBITMAP', 'HANDLE'],['HBRUSH', 'HANDLE'],['HCONV', 'HANDLE'],['HCONVLIST', 'HANDLE'], _
            ['HCURSOR', 'HANDLE'],['HDC', 'HANDLE'],['HDDEDATA', 'HANDLE'],['HDESK', 'HANDLE'],['HDROP', 'HANDLE'], _
            ['HDWP', 'HANDLE'],['HENHMETAFILE', 'HANDLE'],['HFILE', 'int'],['HFONT', 'HANDLE'],['HGIDOBJ', 'HANDLE'], _
            ['HGLOBAL', 'HANDLE'],['HHOOK', 'HANDLE'],['HICON', 'HANDLE'],['HINSTANCE', 'HANDLE'],['HKEY', 'HANDLE'], _
            ['HKL', 'HANDLE'],['HLOCAL', 'HANDLE'],['HMENU', 'HANDLE'],['HMETAFILE', 'HANDLE'],['HMODULE', 'HANDLE'], _
            ['HMONITOR', 'HANDLE'],['HPALETTE', 'HANDLE'],['HPEN', 'HANDLE'],['HRESULT', 'LONG'],['HRGN', 'HANDLE'], _
            ['HRSRC', 'HANDLE'],['HSZ', 'HANDLE'],['HWINSTA', 'HANDLE'],['HWND', 'HWND'],['INT_PTR', 'INT_PTR'], _
            ['INT32', 'int'],['INT64', 'INT64'],['LANGID', 'WORD'],['LCID', 'DWORD'],['LGRPID', 'DWORD'], _
            ['LONG', 'LONG'],['LONGLONG', 'INT64'],['LONG_PTR', 'LONG_PTR'],['LONG32', 'int'],['LONG64', 'INT64'], _
            ['LPARAM', 'LPARAM'],['LPBOOL', 'int*'],['LPBYTE', 'int*'],['LPCOLORREF', 'DWORD*'],['LPCSTR', 'str'], _
            ['LPCTSTR', 'str'],['LPCWSTR', 'wstr'],['LPDWORD', 'DWORD*'],['LPHANDLE', 'HANDLE*'],['LPINT', 'int*'], _
            ['LPLONG', 'long*'],['LPSTR', 'str'],['LPTSTR', 'str'],['LPVOID', 'ptr'],['LPWORD', 'WORD*'], _
            ['LPWSTR', 'wstr'],['LRESULT', 'LRESULT'],['PBOOL', 'BOOL*'],['PBOOLEAN', 'BOOLEAN*'],['PBYTE', 'BYTE*'], _
            ['PCHAR', 'str'],['PCSTR', 'str'],['PCTSTR', 'str'],['PCWSTR', 'wstr'],['PDWORD', 'DWORD*'], _
            ['PDWORDLONG', 'UINT64'],['PDWORD_PTR', 'DWORD_PTR*'],['PDWORD32', 'UINT*'],['PDWORD64', 'INT64*'],['PFLOAT', 'FLOAT*'], _
            ['PHALF_PTR', 'ptr'],['PHANDLE', 'HANDLE*'],['PHKEY', 'HANDLE*'],['PINT', 'int*'],['PINT_PTR', 'INT_PTR*'], _
            ['PINT32', 'int*'],['PINT64', 'INT64*'],['PLCID', 'DWORD*'],['PLONG', 'LONG*'],['PLONGLONG', 'INT64*'], _
            ['PLONG_PTR', 'LONG_PTR*'],['PLONG32', 'long*'],['PLONG64', 'INT64*'],['POINTER_32', 'ptr'],['POINTER_64', 'ptr'], _
            ['POINTER_SIGNED', 'ptr'],['POINTER_UNSIGNED', 'ULONG_PTR'],['PSHORT', 'SHORT*'],['PSIZE_T', 'ULONG_PTR*'],['PSSIZE_T', 'LONG_PTR*'], _
            ['PSTR', 'str'],['PTBYTE', 'BYTE*'],['PTCHAR', 'wstr'],['PTSTR', 'wstr'],['PUCHAR', 'BYTE*'], _
            ['PUHALF_PTR', 'ptr*'],['PUINT', 'UINT*'],['PUINT_PTR', 'UINT_PTR*'],['PUINT32', 'UINT*'],['PUINT64', 'UINT64*'], _
            ['PULONG', 'ULONG*'],['PULONGLONG', 'UINT64*'],['PULONG_PTR', 'ULONG_PTR*'],['PULONG32', 'ULONG*'],['PULONG64', 'UINT64*'], _
            ['PUSHORT', 'USHORT*'],['PVOID', 'ptr'],['PWCHAR', 'wstr'],['PWORD', 'WORD*'],['PWSTR', 'wstr'], _
            ['SC_HANDLE', 'HANDLE'],['SC_LOCK', 'ptr'],['SERVICE_STATUS_HANDLE', 'HANDLE'],['SHORT', 'SHORT'],['SIZE_T', 'ULONG_PTR'], _
            ['SSIZE_T', 'LONG_PTR'],['TBYTE', 'wstr'],['TCHAR', 'wstr'],['UCHAR', 'BYTE'],['UHALF_PTR', 'ptr'], _
            ['UINT', 'UINT'],['UINT_PTR', 'UINT_PTR'],['UINT32', 'UINT'],['UINT64', 'UINT64'],['ULONG', 'ULONG'], _
            ['ULONGLONG', 'UINT64'],['ULONG_PTR', 'ULONG_PTR'],['ULONG32', 'ULONG'],['ULONG64', 'UINT64'],['UNICODE_STRING', 'ptr'], _
            ['USHORT', 'USHORT'],['USN', 'INT64'],['VOID', 'none'],['WCHAR', 'wstr'],['WORD', 'WORD'], _
            ['WPARAM', 'WPARAM']]

    If StringStripWS($sType, 8) <> '' Then
        For $i = 1 To $aType[0][0]
            If $sType = $aType[$i][0] Then
                Return $aType[$i][1]
            EndIf
        Next
    EndIf
    Return SetError(1, 0, '')
EndFunc   ;==>_MSDNDataType

#EndRegion

 

Maybe someone else can solve it and continue from where I stopped. (I expect that if someone manages to solve it - then he will share it)

Edited by Guest
Posted (edited)

This example shows that it is possible change and read native variable completely directly from c++ exe (just to show you why it is good...):
Screenshot_5.thumb.png.dc9423d6c8116063f

 

The codes I used for this:
 

#include <NomadMemory.au3>

#AutoIt3Wrapper_Run_AU3Check=n

HotKeySet('{ESC}','Exit1')

Global $var,$var_old
ConsoleWrite('Looking for the pointer for $var ...' &@CRLF)
$var_pointer = GetVariablePointer($var,0.01)
If Not $var_pointer Then Exit
ConsoleWrite('PID: '&@AutoItPID&@CRLF)
ConsoleWrite('Pointer for $var: '&$var_pointer&@CRLF)

ConsoleWrite('Waiting for $var to change from outside... '&@CRLF)
While Sleep(100)
    If $var <> $var_old Then
        ConsoleWrite('$var changed to: '&$var&@CRLF)
        $var_old = $var
    EndIf
WEnd





Func GetVariablePointer(ByRef $Variable,$iScanRange = 0.1,$Autoit_hMem = 0)
    If Not IsArray($Autoit_hMem) Then
        Local $hMem = _MemoryOpen(@AutoItPID) ; Open the memory of this Autoit
        If @error Then Return SetError(@ScriptLineNumber) ; Error opening the memory
    Else
        Local $hMem = $Autoit_hMem
    EndIf

    Local Const $UniqueValue = -1234562457
    Local $SavedValue = $Variable,$VariablePtr,$PtrFound
    $Variable = DllStructCreate('int') ; Create variable as struct to get its pointer
    $VariablePtr = Number(DllStructGetPtr($Variable)) ; Get the pointer for the struct variable
    $Variable = $UniqueValue ; Change the variable "back" to normal autoit variable

    For $NewPtr = Int($VariablePtr*(1-$iScanRange)) To Int($VariablePtr*(1+$iScanRange))

        ; Check if the value of the pointer is equal to $variable. If so then there is high chance that we found it
        If _MemoryRead($NewPtr, $hMem,'int') <> $Variable Then ContinueLoop
        ; If this area executed then $variable must be equal to $data_from_memread
        ; next: Check if the founded pointer is correct one
        $Variable = 1 ; Set the $variable to be 1
        If _MemoryRead($NewPtr, $hMem,'int') = $Variable Then ; Check again if the value we got using this pointer is equal to $variable
            ; YES!! we found it! this is the correct pointer
            $PtrFound = 1
            ExitLoop ; Exit now to continue to the magic
        Else
            ; if not then this is the worng one :( so we try again and reset...
            $Variable = $UniqueValue
        EndIf
    Next
    $Variable = 0
    If IsArray($Autoit_hMem) Then _MemoryClose($Autoit_hMem)
    If $PtrFound Then Return Ptr($NewPtr)
    Return SetError(@ScriptLineNumber,0,0) ; Failed to find the pointer
EndFunc

Func Exit1()
    Exit
EndFunc

 

#include <iostream>
//#include <string>
#include <windows.h>

using namespace std;

int main()
{

    // Define the address of $var stored in Autoit EXE (pid and pointer for the varible)
    DWORD ExProcessPid = --> Write here the pid <-- ; // The target process PID of Autoit
    int TargetVariablePointer = --> Write here the pointer <-- ; // The memory address for the $var stored in Autoit (Pointer in 0x0 format is (LPVOID)Pointer)
    int var_new = 2; // The new value to set to the $var in Autoit

    // Open the Autoit process
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, ExProcessPid);
    if (!hProcess) {cout << "Error in OpenProcess" << endl; return -1;} // If Error then return -1



    // Change the value of $var inside Autoit
    cout << "Start writing new values into $var in the Autoit process..." << endl;

    bool bWriteMem;int iReadFromMem_OutValue;bool bReadFromMem;
    for (var_new; var_new <= 100; var_new++)
    {
        // Write the new value
        bWriteMem = WriteProcessMemory(hProcess,(LPVOID)TargetVariablePointer,&var_new,sizeof(var_new),NULL);
        if (bWriteMem)
        {
            cout << "Succeeded to write the value " << var_new << " into $var." << endl;
        }
        else
        {
            cout << "Failed to write the value " << var_new << " into $var." << endl;
        }

        // Read the value to see if it was changed
        cout << '\t' << "Reading the value on n using the memory address -> ";
        bReadFromMem = ReadProcessMemory(hProcess,(LPVOID)TargetVariablePointer,&iReadFromMem_OutValue,sizeof(iReadFromMem_OutValue),NULL);
        if (bReadFromMem)
        {
            cout << "the value is: " << iReadFromMem_OutValue << endl;
        }
        else
        {
             cout << "Failed to read the value." << endl;
        }

        Sleep(1000); // Sleep every 1 second

    }

    CloseHandle(hProcess);
    cout << "Done" << endl;
    return 1;


}

 

Edited by Guest

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...