Что нового

[Автоматизация] Скрипт, Работа с памятью или "Вопросы дилетанта"

Вечер добрый. Требуется написать простой скрипт для игры, но я даже не знаю с чего начинать, т.к не особо разбираюсь в программировании(если это вообще программирование). Просьба пнуть в нужном направлении.
-----------------
ТЗ: Имеется игра, из памяти которой нужно извлечь всего одну переменную и работать с ним. Это переменная - высота. Нужно в пределах 2-40м "колебаться" путем нажатий на кнопки W и S.
-----------------
Интересует конкретно работа с памятью. Искал инфу на этом и других форумах, и как обычно бывает, что-то понятно а что-то не совсем.
В общем как я понял мне придется работать с внешними библиотеками NomadMemory и WinAPI (описание функций на английском, а я им не владею). Вопросы следующие:
1) Нельзя ли обойтись без подключения библиотек? Или есть ли библиотека работы с памятью с описанием на русском?
2) Везде где я искал инфу адреса указаны в виде 8-значного 16ричного числа, а адрес переменной который я нашел через ArtMoney состоит из 12 цифр (что-то вроде 00000002A8C1). Это нормально? Или я нашел не то что нужно?
3) Какие препятствия могут возникнуть при попытке чтения памяти? Может ли игра или ОС как то запретить чтение?
------------------
 
Автор
L
То ли форум мертвый, то ли я задал вопрос некорректно, не понятно. Нет смысла ждать ответа?
 
Автор
L
sngr сказал(а):
Второй день уже копаюсь на форуме. Почитал и этот топик. В общем набросал что то эдакое
Код:
#RequireAdmin
#include <NomadMemory.au3>

$adress = 0x00000014B624

$PID = ProcessExists('aces.exe')
$hOpen = _MemoryOpen($PID)
$value = _MemoryRead($adress, $hOpen, 'float')

MsgBox(4096, "Значение", $value)

Sleep (1000)

_MemoryClose($hOpen)


ArtMoney регистрирует изменение значения, а _MemoryRead возвращает 0. Проверил значение @error, тоже 0.
Код:
;==================================================================================
; Function:			_MemoryRead($iv_Address, $ah_Handle[, $sv_Type])
; Description:		Reads the value located in the memory address specified.
; Parameter(s):		$iv_Address - The memory address you want to read from. It must
;								  be in hex format (0x00000000).
;					$ah_Handle - An array containing the Dll handle and the handle
;								 of the open process as returned by _MemoryOpen().
;					$sv_Type - (optional) The "Type" of value you intend to read.
;								This is set to 'dword'(32bit(4byte) signed integer)
;								by default.  See the help file for DllStructCreate
;								for all types.  An example: If you want to read a
;								word that is 15 characters in length, you would use
;								'char[16]' since a 'char' is 8 bits (1 byte) in size.
; Return Value(s):	On Success - Returns the value located at the specified address.
;					On Failure - Returns 0
;					@Error - 0 = No error.
;							 1 = Invalid $ah_Handle.
;							 2 = $sv_Type was not a string.
;							 3 = $sv_Type is an unknown data type.
;							 4 = Failed to allocate the memory needed for the DllStructure.
;							 5 = Error allocating memory for $sv_Type.
;							 6 = Failed to read from the specified process.
; Author(s):		Nomad
; Note(s):			Values returned are in Decimal format, unless specified as a
;					'char' type, then they are returned in ASCII format.  Also note
;					that size ('char[size]') for all 'char' types should be 1
;					greater than the actual size.
;==================================================================================
Func _MemoryRead($iv_Address, $ah_Handle, $sv_Type = 'dword')
	
	If Not IsArray($ah_Handle) Then
		SetError(1)
        Return 0
	EndIf
	
	Local $v_Buffer = DllStructCreate($sv_Type)
	
	If @Error Then
		SetError(@Error + 1)
		Return 0
	EndIf
	
	DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
	
	If Not @Error Then
		Local $v_Value = DllStructGetData($v_Buffer, 1)
		Return $v_Value
	Else
		SetError(6)
        Return 0
	EndIf
	
EndFunc

Почему _MemoryRead возвращает 0?
 
Автор
L
ЭйчЭйч сказал(а):
Какой значение ты ищешь в ArtMoney? Я верно понимаю, что 8-байт с точкой?
нет, 4 байта с точкой. Вообще не понимаю где ошибка. Проверил на всякий значение @error после каждой строки, и даже изменял ее на другое значение перед вызовом функции, оно обнуляется. Все работает до вызова _MemoryRead, в ней что то не так работает
UPD: Покопался в _MemoryRead. DllStructGetData возвращает 0, т.е ошибка где то здесь. Дальше копать мои скромные познания в этой области не дают. Понятия не имею что такое dll структура.
 
Автор
L
Проблема оказалась в самой NomadMemory.au3. Спустя 3 дня нашел таки похожую ситуацию в топике ниже.
http://autoit-script.ru/index.php?topic=24765.0#msg140675
----------
P.S Надеялся на помощь местных "гуру", а получил от такого же новичка. Понятно почему форум умирает
 
Я правильно понял, что через WinApi всё работает?

OffTopic:
1. Запуск с правами администратора (скрипта).
2. Обрезать твой адрес, убрав ноли после х и до первого значения отличного от ноля (т.е. будет 6 символов)
3. Искать именно параллельно с ArtMoney, так как при перезапуске игры адреса будут уже другие.
4. Запустить из под директивы x64 (по умолчанию запускается от х32)

P.S. Просто "гуру" не работали с памятью, вот и всё. Я видел за 10 лет только одного человека, который на AutoIt в этом шарил и соответствующие скрипты писал, и тот иностранец.
 
Автор
L
ЭйчЭйч сказал(а):
Я правильно понял, что через WinApi всё работает?
Все верно. Напрямую вызывал функции работы с памятью с WinAPI. NomadMemory использует те же функции. Вообще не понял в чем смысл этой библиотеки.
--------
Пробовал и с правами и без, и без первых 4 нулей и с ними, работает одинаково. То же самое и с разрядностью. Ну а адрес переменной как ни странно не меняется с перезапуском игры, в моем случае. Повезло, не нужно возиться с указателями
 
Верх