Что нового

[Данные, строки] Как правильно вывести оффсет

kojidun1

Новичок
Сообщения
11
Репутация
0
Добрый день,столкнулся с проблемой вычисления оффсета,вычислил его через CE ,он статичный и после перезапуска определяется правильно,но как только переношу его в скрипт выдает разные значение (ни одно из них не верное ) оффсет 0x002D2288 ,пути вывода которые пробовал:
http://www.autoitscript.com/forum/topic/96164-memorypointerread-understanding/#entry691696
http://autoit-script.ru/index.php/topic,4334.msg31302.html#msg31302
http://autoit-script.ru/index.php/topic,11078.msg73330.html#msg73330
и еще несколько которые уже потерял,прошу помощи хотя бы в наставлении на путь истинный :(
библиотеки NomadMemory.au3 менял результата 0,
Вот код который хотелось бы допилить,скорее всего трабла в самом чтении а не оффсете но я не знаю как ее устранить
Код:
#include <GUIConstants.au3>
#include <nomadmemory.au3>
dim $b[5]=  [0x238,0x34,0x64,0x3f8,0x18]
global $sModule = 'l2.exe'
global $ProcessID =WinGetProcess("II", "")
SetPrivilege("SeDebugPrivilege", 1)
global $DllInformation = _MemoryOpen($ProcessID)
global $baseADDR = _MemoryModuleGetBaseAddress($ProcessID, $sModule)
HotKeySet('{F1}','_CurrentHP')

While 1
    Sleep(100)
WEnd

Func _CurrentHP()
$baseADDR =$baseADDR+0x002D2288
$addr=_MemoryRead($baseADDR, $DllInformation, 'ptr')
$addr = _MemoryRead($addr+$b[0], $DllInformation, 'ptr')
$addr = _MemoryRead($addr+$b[1], $DllInformation, 'ptr')
$addr = _MemoryRead($addr+$b[2], $DllInformation, 'ptr')
$addr = _MemoryRead($addr+$b[3], $DllInformation, 'ptr')
$addr = _MemoryRead($addr+$b[4], $DllInformation, 'dword')
InputBox('',$addr);$ProcessID,$baseADDR)


endFunc
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Попробуйте так:
Код:
Local $_baseADDR =$baseADDR+0x000557F4;Вы тут ошиблись и забыли 0x? или это опечатка
$addr=_MemoryRead($_baseADDR, $DllInformation, 'ptr')
$addr = _MemoryRead($addr+$b[0], $DllInformation, 'ptr')
$addr = _MemoryRead($addr+$b[1], $DllInformation, 'ptr')
$addr = _MemoryRead($addr+$b[2], $DllInformation, 'ptr')
$addr = _MemoryRead($addr+$b[3], $DllInformation, 'ptr')
$addr = _MemoryRead($addr+$b[4], $DllInformation, 'dword')

Странно что вы объявили $baseADDR как глобальную переменную, а затем в функции, каждый раз нажимая F1, прибаляете к ней 000557F4. Как я понимаю, базовый адрес должен определяться один раз, и являться константой для скрипта.
 
Автор
K

kojidun1

Новичок
Сообщения
11
Репутация
0
Изменил код на более актуальный,но всё равно результата не дал ваш способ :(
Есть подозрения что он не правильно определяет где именно считывать (сам процесс ) как это можно проверить/исправить? данные из Autoit window info:
Title: II
Process: l2.exe
UPD: проверил процесс определяет нужный,но так и не выводит оффсет,возвращает всегда 0
 

winstan

Эксплотатор)
Сообщения
406
Репутация
79
1. 'ptr' можно убрать из фукции чтения памяти
2. от имяни администратора запускаешь?
 
Автор
K

kojidun1

Новичок
Сообщения
11
Репутация
0
1.Убрал не помогло
2.Да,от админа
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Ну так, может вам и нужно искать с учетом офсетов относительно базового адреса этой dll?
 
Автор
K

kojidun1

Новичок
Сообщения
11
Репутация
0
Как узнать базовый адрес длл/exe файла? и желательно статей на подобную тему,что бы более не надоедать своими глупыми вопросами,прямо неловко как то
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Уже есть функция готовая _MemoryModuleGetBaseAddress.
Код:
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   ;==>_MemoryModuleGetBaseAddress
И для поисков циклических офсетов тоже есть готовая _MemoryPointerRead
Код:
;=================================================================================================
; Function:			_MemoryPointerRead ($iv_Address, $ah_Handle, $av_Offset[, $sv_Type])
; Description:		Reads a chain of pointers and returns an array containing the destination
;					address and the data at the address.
; Parameter(s):		$iv_Address - The static memory address you want to start at. 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().
;					$av_Offset - An array of offsets for the pointers.  Each pointer must have an
;								 offset.  If there is no offset for a pointer, enter 0 for that
;								 array dimension.
;					$sv_Type - (optional) The "Type" of data you intend to read at the destination
;								 address.  This is set to 'dword'(32bit(4byte) signed integer) by
;								 default.  See the help file for DllStructCreate for all types.
; Requirement(s):	The $ah_Handle returned from _MemoryOpen.
; Return Value(s):	On Success - Returns an array containing the destination address and the value
;								 located at the address.
;					On Failure - Returns 0
;					@Error - 0 = No error.
;							 1 = $av_Offset is not an array.
;							 2 = Invalid $ah_Handle.
;							 3 = $sv_Type is not a string.
;							 4 = $sv_Type is an unknown data type.
;							 5 = Failed to allocate the memory needed for the DllStructure.
;							 6 = Error allocating memory for $sv_Type.
;							 7 = Failed to read from the specified process.
; Author(s):		Nomad
; Note(s):			Values returned are in Decimal format, unless a 'char' type is selected.
;					Set $av_Offset like this:
;					$av_Offset[0] = NULL (not used)
;					$av_Offset[1] = Offset for pointer 1 (all offsets must be in Decimal)
;					$av_Offset[2] = Offset for pointer 2
;					etc...
;					(The number of array dimensions determines the number of pointers)
;=================================================================================================
Func _MemoryPointerRead ($iv_Address, $ah_Handle, $av_Offset, $sv_Type = 'dword')
	
	If IsArray($av_Offset) Then
		If IsArray($ah_Handle) Then
			Local $iv_PointerCount = UBound($av_Offset) - 1
		Else
			SetError(2)
			Return 0
		EndIf
	Else
		SetError(1)
		Return 0
	EndIf
	
	Local $iv_Data[2], $i
	Local $v_Buffer = DllStructCreate('dword')
	
	For $i = 0 to $iv_PointerCount
		
		If $i = $iv_PointerCount Then
			$v_Buffer = DllStructCreate($sv_Type)
			If @Error Then
				SetError(@Error + 2)
				Return 0
			EndIf
			
			$iv_Address = '0x' & hex($iv_Data[1] + $av_Offset[$i])
			DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
			If @Error Then
				SetError(7)
				Return 0
			EndIf
			
			$iv_Data[1] = DllStructGetData($v_Buffer, 1)
			
		ElseIf $i = 0 Then
			DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
			If @Error Then
				SetError(7)
				Return 0
			EndIf
			
			$iv_Data[1] = DllStructGetData($v_Buffer, 1)
			
		Else
			$iv_Address = '0x' & hex($iv_Data[1] + $av_Offset[$i])
			DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
			If @Error Then
				SetError(7)
				Return 0
			EndIf
			
			$iv_Data[1] = DllStructGetData($v_Buffer, 1)
			
		EndIf
		
	Next
	
	$iv_Data[0] = $iv_Address
	
	Return $iv_Data
EndFunc



Добавлено:
Сообщение автоматически объединено:

И разберитесь в порядке чтения оффсетов. Можен нужно начать с последнего в массиве.
 
Автор
K

kojidun1

Новичок
Сообщения
11
Репутация
0
Как правильно узнать адрес дллки? при таком коде возвращает 0 (PID/адрес процесса выдает правильно)
Код:
global $ProcessID =WinGetProcess("II", "")
global $sModule2 = 'system.dll'
global $dllbase = _MemoryModuleGetBaseAddress  ($ProcessID, $sModule2)
 

britanec74

Знающий
Сообщения
22
Репутация
8
Попробуй так:
Код:
#include <GUIConstants.au3>
#include <nomadmemory.au3>
SetPrivilege("SeDebugPrivilege", 1)
global $ProcessID =WinGetProcess("II", "")
global $offset=  StringSplit("18->3f8->64->34->238", "->", 1)
global $sModule = 'NWindow.DLL'
global $Dll = _MemoryOpen($ProcessID)
global $baseADDR = (_MemoryModuleGetBaseAddress($ProcessID, $sModule))+0x002D2288
HotKeySet('{F1}','_CurrentHP')

While 1
    Sleep(100)
WEnd

Func _CurrentHP()
$addr = _MemoryOffsetRead($baseADDR, $Dll, $offset)
InputBox('',$addr);$ProcessID,$baseADDR)
EndFunc

Func _MemoryOffsetRead($pBase, $pPID, $pOffset, $pType = 'dword')
	Local $iv_PointerCount, $pData
	If IsArray($pOffset) = 1 Then
		Local $iv_PointerCount = UBound($pOffset) - 1
		$pBase = _MemoryRead($pBase, $pPID)
		For $i = 1 To $iv_PointerCount
			$pBase = $pBase + Dec($pOffset[$i])
			$pBase = _MemoryRead($pBase, $pPID, $pType)
		Next
	Else
		$pBase = _MemoryRead($pBase, $pPID)
		$pBase = $pBase + Dec($pOffset)
		$pBase = _MemoryRead($pBase, $pPID, $pType)
	EndIf
	$pData = $pBase
	Return $pData
EndFunc
Func _MemoryOffsetWrite($pBase, $pPID, $pOffset, $pData, $pType = 'dword')
	Local $iv_PointerCount, $i
	If IsArray($pOffset) = 1 Then
		Local $iv_PointerCount = UBound($pOffset) - 1
		$pBase = _MemoryRead($pBase, $pPID)
		For $i = 1 To $iv_PointerCount
			$pBase = $pBase + Dec($pOffset[$i])
			If $i < $iv_PointerCount Then
				$pBase = _MemoryRead($pBase, $pPID)
			EndIf
		Next
		_MemoryWrite($pBase, $pPID, $pData, $pType)
	Else
		$pBase = _MemoryRead($pBase, $pPID)
		$pBase = $pBase + Dec($pOffset)
		_MemoryWrite($pBase, $pPID, $pData, $pType)
	EndIf
EndFunc
 

winstan

Эксплотатор)
Сообщения
406
Репутация
79
рискну предположить что WinGetProcess по какимто причинам возвращает 0, например из-за не правельногр названия окна.
советую для теста на каждую переменную поставить Msgbox при ее заполнении и там уже будет видно где проблема.
 

britanec74

Знающий
Сообщения
22
Репутация
8
Ну что, работает нет чей нибудь вариант? Ответь хоть, мне же интересно)
 
Автор
K

kojidun1

Новичок
Сообщения
11
Репутация
0
Прямой адрес без указателей сканит,как только их добавить (с учетом длл) сразу выдает 0,пытаюсь найти адрес с оффсетом либо без дллки либо с оффсетом процесса,пока что результат печален,после нескольких проходов Pointer Scanner в результатах одни длл.
 

britanec74

Знающий
Сообщения
22
Репутация
8
какой адрес у
NWindow.DLL+002D2288
когда ты это забиваешь в СЕ? Без смещений.

Например, если NWindow.DLL+002D2288 = 102D2288 то попробуй в моем примере заменить $baseADDR

Код:
#include <GUIConstants.au3>
#include <nomadmemory.au3>
global $ProcessID =WinGetProcess("II", "") - Тут
global $offset=  StringSplit("18->3f8->64->34->238", "->", 1)
global $Dll = _MemoryOpen($ProcessID)
global $baseADDR = 0x102D2288 ; тут введи базовый адрес полученный в СЕ при добавлении нового адреса, то есть NWindow.DLL+002D2288
HotKeySet('{F1}','_CurrentHP')

While 1
    Sleep(100)
WEnd

Func _CurrentHP()
$addr = _MemoryOffsetRead($baseADDR, $Dll, $offset)
InputBox('',$addr);$ProcessID,$baseADDR)
EndFunc

Func _MemoryOffsetRead($pBase, $pPID, $pOffset, $pType = 'dword')
    Local $iv_PointerCount, $pData
    If IsArray($pOffset) = 1 Then
        Local $iv_PointerCount = UBound($pOffset) - 1
        $pBase = _MemoryRead($pBase, $pPID)
        For $i = 1 To $iv_PointerCount
            $pBase = $pBase + Dec($pOffset[$i])
            $pBase = _MemoryRead($pBase, $pPID, $pType)
        Next
    Else
        $pBase = _MemoryRead($pBase, $pPID)
        $pBase = $pBase + Dec($pOffset)
        $pBase = _MemoryRead($pBase, $pPID, $pType)
    EndIf
    $pData = $pBase
    Return $pData
EndFunc
Func _MemoryOffsetWrite($pBase, $pPID, $pOffset, $pData, $pType = 'dword')
    Local $iv_PointerCount, $i
    If IsArray($pOffset) = 1 Then
        Local $iv_PointerCount = UBound($pOffset) - 1
        $pBase = _MemoryRead($pBase, $pPID)
        For $i = 1 To $iv_PointerCount
            $pBase = $pBase + Dec($pOffset[$i])
            If $i < $iv_PointerCount Then
                $pBase = _MemoryRead($pBase, $pPID)
            EndIf
        Next
        _MemoryWrite($pBase, $pPID, $pData, $pType)
    Else
        $pBase = _MemoryRead($pBase, $pPID)
        $pBase = $pBase + Dec($pOffset)
        _MemoryWrite($pBase, $pPID, $pData, $pType)
    EndIf
EndFunc
Если не помогает прощу в скайп - britanec_74
Выходные эти я свободен, вроде бы
 
Автор
K

kojidun1

Новичок
Сообщения
11
Репутация
0
Всё,разобрался),нашел адрес без внешних библиотек и прочего,статический и он без проблем подошел,всем спасибо)
 
Автор
K

kojidun1

Новичок
Сообщения
11
Репутация
0
Столкнулся с еще 1 траблой ,надеюсь поможете в этой теме,вообщем суть:как правильно вывести/считать значение текстовое? ,оффсеты и базовый адрес есть, в этой софтине http://autoit-script.ru/index.php/topic,9805.msg64976.html#msg64976 выводит правильное значение в строке WCHAR,надо считать 16 байт с указанного адреса,по этому адресу лежит текст в юникоде (как сказал Cheat engine) кусок кода где скорее всего закралась ошибка :
Код:
$addr=_MemoryRead($baseADDRNick, $DllInformation )
$addr = _MemoryRead($addr+$n[4], $DllInformation )
$addr = _MemoryRead($addr+$n[3], $DllInformation )
$addr = _MemoryRead($addr+$n[2], $DllInformation )
$addr = _MemoryRead($addr+$n[1], $DllInformation )
$addr = _MemoryRead($addr+$n[0], $DllInformation ,'char[16]') ; // ошибка тут,при изменении на ptr выводит значение из поля DWORD,то есть адрес и оффсет правильные,пробовал wchar[16] результат тот же,возвращает 0
WinSetTitle ("II", "", ""+$addr)




Добавлено:
Сообщение автоматически объединено:

Char[16] взят из темы http://autoit-script.ru/index.php/topic,4334.msg42757.html#msg42757
и http://www.autoitscript.com/forum/topic/87057-nomad-memory/ англоязычного форума,никаких подсказок более не нашел :(


Добавлено:
Сообщение автоматически объединено:

Ещё подробности:если изменить значение на цифровое с помощью CE то скрипт возвращает это число,у него проблема только с буквами
 
Верх