gil900

[SOLVED]Problem with changing & accessing variable in C++ process from Autoit

1 post in this topic

#1 ·  Posted (edited)

Hello,
I am traying to access and change this n variable in C++ code:

// C_Application.cpp : Defines the entry point for the console application.
//


#include "stdafx.h"
#include "windows.h"
#include <iostream>

using namespace std;
int main()
{
	// Declare the varibles
	int n = 1; int n_old = 1;

	cout << "n=" << n << ", n pointer=" << &n << endl;
	cout << "Waiting for n to change..." << endl;


	while (1)
	{
		Sleep(100);
		if (n != n_old)
		{
			cout << "n changed to: " << n << endl;
			n_old = n;
		}
	}
    return 0;
}

 

This code prints the value of n and it's memory address. The code designed that if n was changed then it will "say" it.

 

Now, after I runned this code and I got the memory address of int n; and the pid of the c++ process, I go to this code:

#include <Array.au3>
#include <NomadMemory.au3>


#Region Test3: change value in C++ process
; Define the C++ address (pid and pointer for the n varible)
Local $iCPid = 3792 ; <---------------- Write here the correct pid of the c++ code
Local $pCPointer = 0x004EFAFC ; <------------- Write here the correct memory address for the n variable in the c++ code
Local $CPointer_DataType = 'int' ; <------------- the variable datatype


; Open the Pointer for the n varibale in the C++ process
$haMem = _MemoryOpen($iCPid,$pCPointer)
If @error Then Exit ConsoleWrite('Error in _MemoryOpen' &' (L:'&@ScriptLineNumber&')'&@CRLF)


; Write new value into n in the C++ process (using the pointer for n)
ConsoleWrite('Start writing new values into n varible in the C++ process...'&' (L:'&@ScriptLineNumber&')'&@CRLF)
Local $n_new
For $n_new = 2 To 100
    _MemoryWrite($pCPointer, $haMem,$n_new,$CPointer_DataType)
    If Not @error Then
        ConsoleWrite('Succeeded to write the value '&$n_new&' into n' &' (L:'&@ScriptLineNumber&')'&@CRLF)
    Else
        ConsoleWrite('Failed to write the value '&$n_new&' into n' &' (L:'&@ScriptLineNumber&')'&@CRLF)
    EndIf

    ConsoleWrite(@TAB&'Reading the value on n using the memory address: the value is: '& _
    _MemoryRead($pCPointer, $haMem,$CPointer_DataType)&' (L:'&@ScriptLineNumber&')'&@CRLF)
    ; This should return the new value that is $n_new

    Sleep(1000)
Next

_MemoryClose($haMem)
#EndRegion

 

Then I write the correct values in lines 7-8 (in line 9 there is no change unless you change the datatype of n in the c++ code) and run the script while the C++ code running.


What I expected to see is:
1) in the C++ concole window I will see that n is changing. Not happening

2) In Autoit I will see that in line 28 it will prints the correct value which is $n_new. Not happening. It print always 0

 

What I did wrong?

 

Thanks.

 

Update 1:

Spoiler

 

I tried to replace the target c++ code to this  alternative autoit code:

#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>


#Region Test

; Create alternative concole gui
Global $ConsoleGUI,$ConsoleGUI_Edit
CreateAlternativeConcoleGUI()



; Allocate memory (and create the memory address) for the given data structure
Local $tSTRUCT1 = DllStructCreate("int n")
; Set the value 1 to n
DllStructSetData($tSTRUCT1,1,1)

; Get the memory address("Pointer") for the allocated space into varible
Local $Pointer = DllStructGetPtr($tSTRUCT1,1)




; Print the data
ConsoleWrite2('n='&DllStructGetData($tSTRUCT1,1)&@LF)
ConsoleWrite2('The pid is: '&@AutoItPID &@LF)
ConsoleWrite2('The pointer for [int n] is: '&$Pointer&@LF)


ConsoleWrite2('Waiting for n to change...' &@LF)



Local $n_old = 1
While Sleep(100)
    If DllStructGetData($tSTRUCT1,1) <> $n_old Then
        ConsoleWrite2('n changed to: '&DllStructGetData($tSTRUCT1,1)&@LF)
        $n_old = DllStructGetData($tSTRUCT1,1)
    EndIf
WEnd

#EndRegion




#Region Low-Level
Func CreateAlternativeConcoleGUI()
    ; Exit on exit key
    HotKeySet('{ESC}','Exit1')
    ; Create the console GUI
    $ConsoleGUI = GUICreate('Alternative Concole', 690, 298)
    $ConsoleGUI_Edit = GUICtrlCreateEdit("", 0, 0, 689, 297)
    GUICtrlSetColor(-1, 0xFFFFFF)
    GUICtrlSetBkColor($ConsoleGUI_Edit, 0x000000)
    WinSetOnTop($ConsoleGUI,'',1)
    GUISetState(@SW_SHOW)
EndFunc

Func ConsoleWrite2($sText)
    ControlSend($ConsoleGUI,'',$ConsoleGUI_Edit,$sText)
EndFunc

Func Exit1()
    Exit
EndFunc
#EndRegion

 

And perform exactly the same test but this time with the Autoit code instead of the c++ code.
I got exactly the same result.

 

 

Update 2:

Spoiler

 

During this test [Autoit A --write-in--> Autoit A]

#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <NomadMemory.au3>


#Region Test

; Create alternative concole gui
Global $ConsoleGUI,$ConsoleGUI_Edit
CreateAlternativeConcoleGUI()



; Allocate memory (and create the memory address) for the given data structure
$tSTRUCT1 = DllStructCreate("int n")
; Set the value 1 to n
DllStructSetData($tSTRUCT1,1,1)

; Get the memory address("Pointer") for the allocated space into varible
$Pointer = DllStructGetPtr($tSTRUCT1,1)




; Print the data
ConsoleWrite2('n='&DllStructGetData($tSTRUCT1,1)&@LF)
ConsoleWrite2('The pid is: '&@AutoItPID &@LF)
ConsoleWrite2('The pointer for [int n] is: '&$Pointer&@LF)


ConsoleWrite2('Waiting for n to change...' &@LF)

; Change the n from inside (some test)
AdlibRegister('Change_n_from_inside',1000) ; <----------------------------------- SUB TEST (If that does not work then there is no chance that it will work from outside)

Local $n_old = 1
While Sleep(100)
    If DllStructGetData($tSTRUCT1,1) <> $n_old Then
        ConsoleWrite2('n changed to: '&DllStructGetData($tSTRUCT1,1)&@LF)
        $n_old = DllStructGetData($tSTRUCT1,1)
    EndIf
WEnd

#EndRegion


Func Change_n_from_inside()
    Local Static $n_new = 2,$haMem = -1
    If $haMem = -1 Then
        $haMem = _MemoryOpen(@AutoItPID)
        If @error Then Exit ConsoleWrite('Error in _MemoryOpen' &' (L:'&@ScriptLineNumber&')'&@CRLF)
    EndIf
    _MemoryWrite($Pointer, $haMem,$n_new,'int')
    $n_new += 1
EndFunc


#Region Low-Level
Func CreateAlternativeConcoleGUI()
    ; Exit on exit key
    HotKeySet('{ESC}','Exit1')
    ; Create the console GUI
    $ConsoleGUI = GUICreate('Alternative Concole', 690, 298)
    $ConsoleGUI_Edit = GUICtrlCreateEdit("", 0, 0, 689, 297)
    GUICtrlSetColor(-1, 0xFFFFFF)
    GUICtrlSetBkColor($ConsoleGUI_Edit, 0x000000)
    WinSetOnTop($ConsoleGUI,'',1)
    GUISetState(@SW_SHOW)
EndFunc

Func ConsoleWrite2($sText)
    ControlSend($ConsoleGUI,'',$ConsoleGUI_Edit,$sText)
EndFunc

Func Exit1()
    Exit
EndFunc
#EndRegion

 

I found the bug. to make it work I needed to change line:

$haMem = _MemoryOpen(@AutoItPID,$Pointer)

To:

$haMem = _MemoryOpen(@AutoItPID)

 

Now I try to repeat the test with the patch applied.. I'll update later if it will works

 

 

 

 

Update 3:
Repeate the original test when the target exe (where int n is stored) is Autoit exe - [Autoit A --write-in--> Autoit B] Test passed (Working!)

 

Update 4:
Repeate the original test when the target exe (where int n is stored) is C++ exe - [Autoit --write-in--> C++] Test passed (Working!)

working.thumb.png.3d7bf621b1e3e3919aeea0

 

Problem solved

 

Update 5:

And now I worte c++ code that will change the n varible in Autoit: [C++ --write-in--> Autoit] Test passed (Working!)

56be71f4ca2a7_Work2.thumb.png.f5961b7438

 

C++ code:
 

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

using namespace std;

int main()
{

    // Define the address of n stored in Autoit EXE (pid and pointer for the n varible)
    DWORD ExProcessPid = 7184; // The target process PID of Autoit
    int TargetVariablePointer = 0x00F28F38; // The memory address for the n variable stored in Autoit (Pointer in 0x0 format is (LPVOID)Pointer)
    int n_new = 2; // The new value to set to the n varibale 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 n inside Autoit
    cout << "Start writing new values into n varible in the Autoit process..." << endl;

    bool bWriteMem;int iReadFromMem_OutValue;bool bReadFromMem;
    for (n_new; n_new <= 100; n_new++)
    {
        // Write the new value
        bWriteMem = WriteProcessMemory(hProcess,(LPVOID)TargetVariablePointer,&n_new,sizeof(n_new),NULL);
        if (bWriteMem)
        {
            cout << "Succeeded to write the value " << n_new << " into n." << endl;
        }
        else
        {
            cout << "Failed to write the value " << n_new << " into n." << 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;


}

 

Unfortunately I could not make it simpler in C.
There is no way to do it simple in C ..
But maybe I'm wrong .. I'm new in C ++

Edited by gil900
2 people like this

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