Что нового

NomadMemory.au3, при чтении памяти возвращает 0 !

oesoes

xor eax,eax
Сообщения
171
Репутация
9
Привет. Начинаю вникать потихоньку в геймхак+автоит. Игра - Rift. Пытаюсь считать показатель маны. Откидывая лирические отступления выкладываю скрипт:

Код:
#RequireAdmin
#include <NomadMemory.au3>

const $sTitle = "RIFT"
const $dAddress = 0x72cd4738
const $aManaOffset[2] = [0,568]

dim $dPid = 0x0
dim $hMem = 0x0

Func sLog($s)
	ConsoleWrite($s & @CRLF)
EndFunc

if WinExists($sTitle) Then
	$dPid = WinGetProcess($sTitle)
	$hMem = _MemoryOpen($dPid)
	sLog($hMem[0] & "-" & $hMem[1])
	if $hMem[0] Then
		sLog("Дескриптор памяти: " & $hMem[1])
		$CurrentMana = _MemoryPointerRead($dAddress,$hMem,$aManaOffset)
		sLog("Адрес: " & $CurrentMana[0])
		sLog("Значение: " & $CurrentMana[1])
		_MemoryClose($hMem);
	EndIf
EndIf


Адрес и смещение нашел правильно, так как если смотреть в Olly, то значение там по этому адресу имеется, но оно мне упорно дает ноль и все тут, хоть ты тресни. Указатель нашел через CE, как подсказали вот тут:

http://www.youtube.com/watch?feature=player_embedded&v=oI8Q2w9l0Gc

Может быть неправильно нашел - не спорю, так как если игру-пациента перезапускать (выкл\вкл), то адрес не меняется, но вот после перезагрузки компа, данные уже проецируются в другие области памяти. #OFF: Кстати, если есть толковое объяснение, как все-таки _правильно_ искать указатель на данные или просто кто-то может быстренько и четко раскидать - буду рад услышать, а то может быть правда, что-то делаю не так. Схватываю быстро, так что не задержу ) Но факт остается фактом: в отладчике значение в памяти присутствует, но автоит его упорно не видит.

Долго гуглил... Наткнулся на то, что буржуй испытывал такие же проблемы, но после того как откатился на предыдущую версию, все якоб заработало. По моему бред какой-то. Я только утром читал и писал в память и все работало, а теперь как в воду кануло. Помогите, мужики!
 

filautdinov

Знающий
Сообщения
96
Репутация
9
Возможно что в игре стоит защита от чтения, изменения памяти, либо недостаточно прав для этого. Столкнулся с подобной проблемой через СЕ или аналоги значения меняются а вот через Autoit нет. Хотя если беру обычный калькулятор то в нем значения меняются а в игре нет. Нашел способ с использованием сторонней dll для чтения, изменения памяти, но пока не могу разобраться с dllcall для ее использования.
 
Автор
oesoes

oesoes

xor eax,eax
Сообщения
171
Репутация
9
Ну не, оно бы тогда и CE блокировало и ольку и Иду, да и утром я уже делал наброски и читал из памяти... Хотя... СЕ отладчиком не мог подцепиться системным сначала, ругался там, что прав нет на отладку, но это успокаивается активацией виейч-отладчика в самом CE. Что интересно: отладчик-то по дефалту системный юзается...
 

winstan

Эксплотатор)
Сообщения
406
Репутация
79
:smile:я сомниваюсь в правельности параметров для вызова функции _MemoryPointerRead()
filautdinov
Защита от чтения бред, еслибы трабла была в ней то и от CE игрубы тоже защитили
 
Автор
oesoes

oesoes

xor eax,eax
Сообщения
171
Репутация
9
А вот и прикол, действительно! Загуглил ещё разок, и действительно, модуль НомадМемори некорректно работает в новых версиях АвтоИта! На версии 3.3.6.1 все прекрасно запустилось и работает без сучка и задоринки! Сейчас соберу в разных версиях и посмотрю под идой, в чем беда на оба экземпляра-отпишу. Мистика, да и только.

>> :smile:я сомниваюсь в правельности параметров для вызова функции _MemoryPointerRead()
Все так, как написано в самом NomadMemory. Ничего лишнего.
 

filautdinov

Знающий
Сообщения
96
Репутация
9
winstan сказал(а):
:smile:я сомниваюсь в правельности параметров для вызова функции _MemoryPointerRead()
filautdinov
Защита от чтения бред, еслибы трабла была в ней то и от CE игрубы тоже защитили
В том то и дело что когда использую СЕ то все норм и меняется и читается но при использовании NomadMemory получаю 0. Попробую старую версию Autoit как предлагает oesoes может быть так и есть что дело в новой версии.
 

Dellroc

Осваивающий
Сообщения
151
Репутация
31
Попробуй вот эту версию библиотеки
 

Вложения

  • NoMadMemory.au3
    21.7 КБ · Просмотры: 20

filautdinov

Знающий
Сообщения
96
Репутация
9
Попробывал версию 3.3.6.1 то же самое в СЕ значения меняются а так нет:
Код:
_Memorywrite(0x6a7902, _Memoryopen(ProcessExists("test.exe")), "0xf4g8s7", 'byte[3]')
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
oesoes
Пользуйся.

Код:
#include-once
#Region _FMemory64
;==================================================================================
; AutoIt Version:	3.3.8.1
; UDF Version:		2.02
; Language:			English
; Platform:			All Windows
; Author:			Firex
;==================================================================================
; Credits:	NoMad - These function are based on his original NoMadMemory_UDF.

Global $FMem_hMem = -1
Global $FMem_hDll = -1
Global $FMem_aDef[1] = [ 0 ]
Global $FMem_tPointer = DllStructCreate( "int" ), _
	$FMem_pPointer = DllStructGetPtr( $FMem_tPointer ), _
	$FMem_iPointer = DllStructGetSize( $FMem_tPointer )

;==================================================================================
Func _FMem_Open( $iPid, $iDesiredAccess = 0x1F0FFF, $iInheritHandle = 1 )
	If Not ProcessExists($iPid) Then _
        Return SetError( 1, 0, 0 )

	$FMem_hDll = DllOpen('kernel32.dll')
	If @Error Then _
        Return SetError( 2, 0, 0 )

	Local $aOpenProcess = DllCall( $FMem_hDll, "handle", "OpenProcess", "dword", $iDesiredAccess, "bool", $iInheritHandle, "dword", $iPid )
	If @Error Then
        DllClose( $FMem_hDll )
        Return SetError( 3 + @Error, 0 )
    EndIf
	$FMem_hMem = $aOpenProcess[0]
	Return True
EndFunc

Func _FMem_Read( $iAddress, $pStruct, $iSize ) ;Return Bool && pStruct
	Local $aRet = DllCall( $FMem_hDll,"bool","ReadProcessMemory","handle",$FMem_hMem,"ptr",$iAddress,"ptr",$pStruct,"ulong_ptr",$iSize,"ulong_ptr*",0 )
	If Not @Error And $aRet[0] Then _
		Return True

	Return SetError( 1 + @Error, 0, 0 )
EndFunc

Func _FMem_Read2( $iAddress, $sStruct, $iRet = 1 ) ;Return tBuffer[1] || tBuffer
	Local $aRet, $tBuffer = DllStructCreate( $sStruct ), _
		$pBuffer = DllStructGetPtr( $tBuffer ), _
		$iSize = DllStructGetSize( $tBuffer )
	; ---
	$aRet = DllCall( $FMem_hDll,"bool","ReadProcessMemory","handle",$FMem_hMem,"ptr",$iAddress,"ptr",$pBuffer,"ulong_ptr",$iSize,"ulong_ptr*",0 )
	If Not @Error And $aRet[0] Then
		If $iRet Then _
			Return DllStructGetData( $tBuffer, 1 )

		Return $tBuffer
	EndIf
	Return SetError( 1 + @Error, 0, 0 )
EndFunc

Func _FMem_ReadArray( $iAddress, $iCount, $sElemTag, $iElemSize ) ;Return aArr(iCount) || FMem_aDef(1)
	If Not $iCount Then _
		Return SetError( 1, 0, $FMem_aDef )

	Local $Idx, $tElem, $tBuffer, $pBuffer, $iSize, $aRet, $aArr[$iCount]
	; ---
	$iSize = $iElemSize * $iCount
	$tBuffer = DllStructCreate( "byte[" & $iSize & "]" )
	$pBuffer = DllStructGetPtr( $tBuffer )

	$aRet = DllCall( $FMem_hDll,"bool","ReadProcessMemory","handle",$FMem_hMem,"ptr",$iAddress,"ptr",$pBuffer,"ulong_ptr",$iSize,"ulong_ptr*",0 )
	If Not @Error And $aRet[0] Then
		For $Idx = 0 To $iCount - 1 Step 1
			$tElem = DllStructCreate( $sElemTag, $pBuffer + ( $Idx * $iElemSize ) )
			$aArr[$Idx] = DllStructGetData( $tElem, 1 )
		Next
		; *
		Return $aArr
	EndIf
	Return SetError( 1 + @Error, 0, $FMem_aDef )
EndFunc

Func _FMem_ReadPointer( $iAddress ) ;Return FMem_tPointer[1]
	Local $aRet = DllCall( $FMem_hDll,"bool","ReadProcessMemory","handle",$FMem_hMem,"ptr",$iAddress,"ptr",$FMem_pPointer,"ulong_ptr",$FMem_iPointer,"ulong_ptr*",0 )
	If Not @Error And $aRet[0] Then _
		Return DllStructGetData( $FMem_tPointer, 1 )

	Return SetError( 1 + @Error, 0, 0 )
EndFunc

Func _FMem_ReadPointer2( $iAddress, $iOfs1, $iOfs2 = -1, $iOfs3 = -1, $iOfs4 = -1, $iOfs5 = -1, $iOfs6 = -1 )
	Local $aOfs[6] = [$iOfs1, $iOfs2, $iOfs3, $iOfs4, $iOfs5, $iOfs6 ], $Idx
	; ---
	For $Idx = 0 To @NumParams - 2 Step 1
		$iAddress = _FMem_ReadPointer( $iAddress ) + $aOfs[$Idx]
	Next
	Return _FMem_ReadPointer( $iAddress )
EndFunc

Func _FMem_Close()
	If $FMem_hDll = -1 Or $FMem_hMem = -1 Then _
        Return SetError(1,0,0)

	DllCall($FMem_hDll, 'int', 'CloseHandle', 'int', $FMem_hMem)
	DllClose($FMem_hDll)

	$FMem_hDll = -1
	$FMem_hMem = -1
	; ----
	Return 1
EndFunc
#EndRegion _FMemory64


Выглядеть основная часть будет примерно так:
Код:
$iPid = WinGetProcess( $sTitle )
If _FMem_Open( $iPid ) Then
		sLog( "Дескриптор памяти: " & $FMem_hMem )
	; *
	$CurrentMana = _FMem_ReadPointer2( 0x72cd4738, 0, 568 )
	sLog( "$CurrentMana=" & $CurrentMana )

	_FMem_Close()
Else
	sLog( "Error=" & @Error )
EndIf


Библиотека писалась под скоростное чтение для личных нужд.
 

filautdinov

Знающий
Сообщения
96
Репутация
9
Dellroc сказал(а):
Попробуй вот эту версию библиотеки
Тож самое не меняется только в игре если допустим взять тот же блокнот то его значения меняются в игре нет.
 
Автор
oesoes

oesoes

xor eax,eax
Сообщения
171
Репутация
9
filautdinov сказал(а):
Попробывал версию 3.3.6.1 то же самое в СЕ значения меняются а так нет:
Код:
_Memorywrite(0x6a7902, _Memoryopen(ProcessExists("test.exe")), "0xf4g8s7", 'byte[3]')

Адрес должен передаваться в функцию как число, а не как строка и массив смещений тоже. К тому же, смещения в массиве должны быть в десятичной форме записи, как указывается в NomadMemory.

Кстати, AuotIt не дает отлаживать скрипты в отладчиках и пишет, что, мол, если вы являетесь антивирусным аналитиком, то милости просим, пишите нам на адрес. Политика, черт бы ее побрал.

#UPD:
Долго думал, тыкался с версиями, операционками, разрядностями. Так вот, судя по всему, хреново работает только функция _MemoryPointerRead() на x64 версии пинды. На x86 все прекрасно (когда я говорил, что заработало, то сидел на ноуте с XP, а потом опять прыгнул за свой комп, ну и опять ничего не работает). Так вот, когда я переписал код с использованием простого _MemoryRead(), то все благополучно запустилось и отработало. Версия пакета AutoIT оказалась ни при чем.

Заметил так же, что разновидностей библиотек NomadMemory в сети кочует как собак нерезаных и вот, что ещё хочется сказать. Функция _MemoryGetBaseAddress, которая встречается в версиях одноименного модуля НЕ РАБОТАЕТ - она всегда отдает ноль (я про x64. на x86 наверное работает, я уже запутался). Есть по крайней мере две рабочие функции (которые я встретил откапывая стопицот Номадов на форумах, а то может быть и гораздо больше) и эти функции имеют имена: _ProcessGetModuleBase() и _MemoryModuleGetBaseAddress(). У них разные алгоритмы, но выполняют они одну и ту же функцию. На всякий случай продублирую их тут:

Код:
Func _ProcessGetModuleBase($ivPID, $svModuleName) 
    $ivPID = ProcessExists($ivPID)
    If Not $ivPID Then Return(SetError(1, 0, 0)); Process does not exist

    Local $TH32CS_SNAPMODULE = 0x00000008
    Local $sMODULEENTRY32Struct = "dword Size;" & _
                            "dword 32ModuleID;" & _
                            "dword 32ProcessID;" & _
                            "dword GlblcntUsage;" & _
                            "dword ProccntUsage;" & _
                            "ptr modBaseAddr;" & _
                            "dword modBaseSize;" & _
                            "hwnd hModule;" & _
                            "char Module[255];" & _
                            "char ExePath[260]"

    Local $hvSnapShot = DllCall("Kernel32.dll", "hwnd", "CreateToolhelp32Snapshot", "dword", $TH32CS_SNAPMODULE, "dword", $ivPID)
    If Not $hvSnapShot[0] Then Return(SetError(2, 0, 0)); Could not create snapshot?

    Local $stMODULEENTRY32 = DllStructCreate($sMODULEENTRY32Struct)
    DllStructSetData($stMODULEENTRY32, "Size", DllStructGetSize($stMODULEENTRY32))

    Local $ivState = DllCall("Kernel32.dll", "int", "Module32First", "hwnd", $hvSnapShot[0], "long_ptr", DllStructGetPtr($stMODULEENTRY32))
    If Not $ivState[0] Then Return(SetError(3, _WinAPI_CloseHandle($hvSnapShot[0]), 0)); Could not enumerate first module in list?
    Local $ivRet = 0
    Local $svModule

    Do
        $ivRet = DllStructGetData($stMODULEENTRY32, "modBaseAddr")
        $svModule = DllStructGetData($stMODULEENTRY32, "Module")
        If $svModule = $svModuleName Then ExitLoop
        $ivState = DllCall("Kernel32.dll", "int", "Module32Next", "hwnd", $hvSnapShot[0], "long_ptr", DllStructGetPtr($stMODULEENTRY32))
        Sleep(1)
    Until Not $ivState[0]

    _WinAPI_CloseHandle($hvSnapShot[0])

    Return $ivRet
EndFunc

Func _MemoryModuleGetBaseAddress($iPID, $sModule)
    If Not ProcessExists($iPID) Then Return SetError(1, 0, 0)

    If Not IsString($sModule) Then Return SetError(2, 0, 0)

    Local   $PSAPI = DllOpen("psapi.dll")

    ;Get Process Handle
    Local   $hProcess
    Local   $PERMISSION = BitOR(0x0002, 0x0400, 0x0008, 0x0010, 0x0020) ; CREATE_THREAD, QUERY_INFORMATION, VM_OPERATION, VM_READ, VM_WRITE

    If $iPID > 0 Then
        Local $hProcess = DllCall("kernel32.dll", "ptr", "OpenProcess", "dword", $PERMISSION, "int", 0, "dword", $iPID)
        If $hProcess[0] Then
            $hProcess = $hProcess[0]
        EndIf
    EndIf

    ;EnumProcessModules
    Local   $Modules = DllStructCreate("ptr[1024]")
    Local   $aCall = DllCall($PSAPI, "int", "EnumProcessModules", "ptr", $hProcess, "ptr", DllStructGetPtr($Modules), "dword", DllStructGetSize($Modules), "dword*", 0)
    If $aCall[4] > 0 Then
        Local   $iModnum = $aCall[4] / 4
        Local   $aTemp
        For $i = 1 To $iModnum
            $aTemp =  DllCall($PSAPI, "dword", "GetModuleBaseNameW", "ptr", $hProcess, "ptr", Ptr(DllStructGetData($Modules, 1, $i)), "wstr", "", "dword", 260)
            If $aTemp[3] = $sModule Then
                DllClose($PSAPI)
                Return Ptr(DllStructGetData($Modules, 1, $i))
            EndIf
        Next
    EndIf

    DllClose($PSAPI)
    Return SetError(-1, 0, 0)

EndFunc

Вот почему так получается? Потому, что нет единого, централизованного склада для разного рода таких библиотек. А то один скачал - допилил, другой скачал - ещё чего-то дописал, так и беснуются разные версии с одним и тем же названием по сети. Вот жил я раньше на Delphi и там сообщество достаточно щепетильно относится к подобного рода проблемам и если что-то подобное случается, то заливают куда-нибудь на житхаб и оттуда форкают кто что хочет. Ну это я так, к слову.

Плохо живется AutoIT-программистам, я так понимаю, без отладчика... Понятно, что политика лицензии не позволяет дизассемблировать скрипты, но а как же иначе? Откуда я знаю, может компилятор данные в байт-коде на рожон x64 переводит и из за ничего не работает? А было бы круто иметь хорошую IDE под это дело с интегрированным отладчиком, брейками, пошаговым выполнением и остальными плюхами...
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Мне кажется что nomad memory был написан как раз в то время, когда в autoit не было собственной библиотеки для работы с памятью и процессами. Поэтому там своя функция для открытия процесса, для чтения адреса, вспомогательные функцие по чтению данных по массиву указателей.

Сегодняшний nomad должен быть оберткой к функциям:
_WinAPI_OpenProcess
_WinAPI_EnumProcessModules
_WinAPI_ReadProcessMemory
_WinAPI_WriteProcessMemory
 
Автор
oesoes

oesoes

xor eax,eax
Сообщения
171
Репутация
9
inververs сказал(а):
Сегодняшний nomad должен быть оберткой к функциям:
_WinAPI_OpenProcess
_WinAPI_EnumProcessModules
_WinAPI_ReadProcessMemory
_WinAPI_WriteProcessMemory

Тогда он станет оберткой оберток. :scratch:
 
Верх