Что нового

[Процессы] Помогите оптимизировать функцию чтения памяти [NT-API]

zerobot

Новичок
Сообщения
78
Репутация
0
Добрый день!

Есть функция:
Код:
Func _NtReadVirtualMemory($i_BaseAddress, $h_Process, $s_Type, $i_Read = 1)
	Local $a_Res, $t_Buff, $i_Size, $p_Buff

	$t_Buff = DllStructCreate($s_Type & '[' & $i_Read & ']')
	$i_Size = DllStructGetSize($t_Buff)
	$p_Buff = DllStructGetPtr($t_Buff)
	$a_Res = DllCall($DllSoftware, 'int', 'NtReadVirtualMemory', 'handle', $h_Process, 'ptr', $i_BaseAddress, 'ptr', $p_Buff, 'ulong', $i_Size, 'int*', 0)
	If(@error) Or($a_Res[0]) Then Return SetError(1, 0, '')
	Return SetExtended($a_Res[5], DllStructGetData($t_Buff, 1))
EndFunc


Как можно ускорить её работу, может есть способы оптимизировать? Или может быть можно как-то перевести её в машинный код/asm? Делаю сверх-быстрый бот...
И ещё, делал тестирование её скорости через TimeDiff/Init и обнаружил проседания по скорости с 0.01 млс. до 3-4 млс. в случайные (вроде бы) моменты, с чем это может быть связано?
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
zerobot
1. Для каждого чтения вы выделяете память (DllStructCreate).
2. Какой смысл в вашем коде представляет параметр $i_Read? Подскажу - его нет.
3. Проседания в скорости могут быть из-за некорректного значения $i_BaseAddress / других причин, которые вы не в состоянии обойти.

Как можно ускорить её работу
1. Создайте все возможные структуры заранее и заполняйте их по мере чтения процесса (функция должна принимать адрес памяти, указатель и размер структуры).
2. Чтение блока из 3*4 байт быстрее, чем два чтения по 4 байта. Старайтесь считывать все за один раз. Наглядно:
Код:
0x10: INT
0x28: INT
Правильно: 
ReadMemory( 0x10, pStruct, ( 0x28 - 0x10 ) + 0x04 )

Не правильно:
ReadMemory( 0x10, pStruct, 0x04 )
ReadMemory( 0x28, pStruct, 0x04 )
3. Не писать на AutoIt.

*Касательно второго пункта: цифры произвольные (однако речь не идет о мегабайтах).
 
Автор
Z

zerobot

Новичок
Сообщения
78
Репутация
0
Под
Код:
0x10: INT
0x28: INT

Вы подразумеваете адреса?
Т.е как бы за раз читать некий участок памяти, а уже в нём находить всё необходимое?

Вы можете дать пример с моей функцией, для чтения предположим 3 адресов в которых разница в 4 байта за раз (что-то вроде 0x000000 0x000004 0x000008) и выведения результата?
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
zerobot
Вы меня правильно поняли. Если наглядно относительно вашего кода, то:
Код:
Global $g_hDll = DllOpen( 'ntdll.dll' ), _
	$g_hProcess = ...

; ~~~
$tMyStruct = DllStructCreate( 'int One; int Two; int Three;' )
$_pMyStruct = DllStructGetPtr( $tMyStruct )
$_iMyStruct = DllStructGetSize( $tMyStruct )

While 1
	;~~~

	If _NtReadVirtualMemory( 0x000000, $_pMyStruct, $_iMyStruct ) Then
		ConsoleWrite( $tMyStruct.One & @CRLF)
		ConsoleWrite( $tMyStruct.Two & @CRLF)
		ConsoleWrite( $tMyStruct.Three & @CRLF)
	EndIf
	;~~~
WEnd

Func _NtReadVirtualMemory($i_BaseAddress, $p_Buffer, $i_Size)
    Local $a_Res = DllCall($g_hDll, 'int', 'NtReadVirtualMemory', 'handle', $g_hProcess, 'ptr', $i_BaseAddress, 'ptr', $p_Buff, 'ulong', $i_Size, 'int*', 0)
	; -
	If @Error Or $a_Res[0] Then _
		Return False

	Return True
EndFunc


Можете ознакомиться с этим: http://pastebin.com/fMPPDzwc

Как и в вашем случае уделял внимание только оптимизации. К слову - проект работал быстрее, чем аналоги на компилируемых ЯП( из-за наилучшей организации чтения памяти ).
 
Автор
Z

zerobot

Новичок
Сообщения
78
Репутация
0
Идите ка сюда, я вас расцелую :smile:
Спасибо огромное, действительно ооочень помогли :beer:
Удачи вам в ваших проектах :smile:
 
Верх