Что нового

Чтение и записть в память процесса

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
AutoIT: Не менее 3.3.9.4
Версия: 1.1
Категория: Процессы, Память, WinAPI

Описание: Скрипт для чтения и записи значений в память процесса.

Код:
Код:
#cs ----------------------------------------------------------------------------

	AutoIt Version: 3.3.9.4 (beta)
	Author:         inververs

	Script Function:
	Template AutoIt script.

#ce ----------------------------------------------------------------------------
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ###
$Form1 = GUICreate("http://autoit-script.ru/", 615, 374, 211, 256)
$Group1 = GUICtrlCreateGroup("Процесс", 8, 8, 601, 185)
$Label1 = GUICtrlCreateLabel("1. Открыть процесс", 16, 26, 105, 17)
$Label2 = GUICtrlCreateLabel("ИД процесса", 160, 26, 83, 17)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
$Input1 = GUICtrlCreateInput("", 248, 24, 57, 21, BitOR($GUI_SS_DEFAULT_INPUT,$ES_CENTER,$ES_UPPERCASE,$ES_NUMBER))
$Button1 = GUICtrlCreateButton("Открыть", 312, 24, 75, 25)
$Label3 = GUICtrlCreateLabel("ИД процесса можно посмотреть в диспетчере задач", 392, 24, 212, 34)
$Label4 = GUICtrlCreateLabel("2. Прочитать память", 16, 66, 108, 45)
$Label5 = GUICtrlCreateLabel("Адрес в памяти: 0х", 128, 66, 119, 17, $SS_RIGHT)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
$Input2 = GUICtrlCreateInput("0", 248, 64, 137, 21, BitOR($GUI_SS_DEFAULT_INPUT,$ES_UPPERCASE))
GUICtrlSetLimit(-1, 16)
$Label6 = GUICtrlCreateLabel("Offset: 0х", 128, 90, 119, 17, $SS_RIGHT)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
$Input3 = GUICtrlCreateInput("0", 248, 88, 137, 21, BitOR($GUI_SS_DEFAULT_INPUT,$ES_UPPERCASE))
GUICtrlSetLimit(-1, 16)
$Button2 = GUICtrlCreateButton("Прочитать", 392, 64, 75, 45, $BS_DEFPUSHBUTTON)
GUICtrlSetState(-1, $GUI_DISABLE)
$Label7 = GUICtrlCreateLabel("Адрес + Offset", 472, 68, 132, 17, $SS_CENTER)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
$Input4 = GUICtrlCreateInput("", 472, 88, 129, 21, BitOR($GUI_SS_DEFAULT_INPUT,$ES_CENTER,$ES_UPPERCASE,$ES_READONLY))
$Label8 = GUICtrlCreateLabel("3. Закрыть процесс перед выходом", 16, 146, 186, 17)
$Button3 = GUICtrlCreateButton("Закрыть", 208, 136, 75, 25)
GUICtrlSetState(-1, $GUI_DISABLE)
$Label9 = GUICtrlCreateLabel("", 392, 144, 212, 34)
$Input5 = GUICtrlCreateInput("4", 248, 112, 137, 21, BitOR($GUI_SS_DEFAULT_INPUT,$ES_UPPERCASE,$ES_NUMBER))
$Label10 = GUICtrlCreateLabel("Читать это количество байт: >", 56, 114, 188, 17)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
$Label11 = GUICtrlCreateLabel("* рекомендуется: 1,2,3,4,8 байт", 392, 114, 213, 17)
$Label18 = GUICtrlCreateLabel("IsAdmin:", 16, 168, 44, 17)
$Label19 = GUICtrlCreateLabel("нет", 64, 168, 37, 17)
$Label20 = GUICtrlCreateLabel("SeDebug:", 104, 168, 52, 17)
$Label21 = GUICtrlCreateLabel("нет", 160, 168, 37, 17)
GUICtrlCreateGroup("", -99, -99, 1, 1)
$Group2 = GUICtrlCreateGroup("Данные в памяти", 8, 200, 601, 169)
$Label12 = GUICtrlCreateLabel("INT (4)", 16, 218, 44, 17)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
$Label13 = GUICtrlCreateLabel("BYTE", 16, 242, 36, 17)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
$Label14 = GUICtrlCreateLabel("ANSI", 16, 266, 33, 17)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
$Input6 = GUICtrlCreateInput("0", 72, 216, 457, 21, BitOR($GUI_SS_DEFAULT_INPUT,$ES_NUMBER))
GUICtrlSetLimit(-1, 10)
$Input7 = GUICtrlCreateInput("0x00", 72, 240, 457, 21)
$Input8 = GUICtrlCreateInput("", 72, 264, 457, 21)
$Button4 = GUICtrlCreateButton("Записать", 536, 216, 65, 25)
GUICtrlSetState(-1, $GUI_DISABLE)
$Button5 = GUICtrlCreateButton("Записать", 536, 240, 65, 25)
GUICtrlSetState(-1, $GUI_DISABLE)
$Button6 = GUICtrlCreateButton("Записать", 536, 264, 65, 25)
GUICtrlSetState(-1, $GUI_DISABLE)
$Label15 = GUICtrlCreateLabel("DWORD", 16, 290, 52, 17)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
$Input9 = GUICtrlCreateInput("0", 72, 288, 457, 21)
$Label16 = GUICtrlCreateLabel("TEXT", 16, 314, 36, 17)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
$Input10 = GUICtrlCreateInput("", 72, 312, 457, 21)
$Label17 = GUICtrlCreateLabel("WCHAR", 16, 338, 50, 17)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
$Input11 = GUICtrlCreateInput("", 72, 336, 457, 21)
$Button7 = GUICtrlCreateButton("", 536, 288, 65, 25)
GUICtrlSetState(-1, $GUI_DISABLE)
$Button8 = GUICtrlCreateButton("", 536, 312, 65, 25)
GUICtrlSetState(-1, $GUI_DISABLE)
$Button9 = GUICtrlCreateButton("Записать", 536, 336, 65, 25)
GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlCreateGroup("", -99, -99, 1, 1)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

#include <WinApiEx.au3>
OnAutoItExitRegister("_CloseProc")

Opt("MustDeclareVars", 1)

If IsAdmin() Then
	GUICtrlSetData($Label19, 'да')
EndIf

Global $hProc, $PID, $ADSS


Local $nMsg
While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		Case $Button1
			_OpenProc()
		Case $Input2
			_GETADSS()
		Case $Input3
			_GETADSS()
		Case $Button2
			_READMEM()
		Case $Button3
			_CloseProc()
		Case $Button4
			_WRITEMEMINT()
		Case $Button5
			_WRITEMEMHEX()
		Case $Button6
			_WRITEMEMTEXT()
		Case $Button7
		Case $Button8
		Case $Button9
			_WRITEMEMWCHAR()
		Case $Label21
			_SEDEBUG()
	EndSwitch
WEnd


Func _WRITEMEM($Buffer)
	GUICtrlSetData($Label9, '')
	Local $test, $iWriten
	Local $pBaseAddress = _GETADSS()
	If Not $pBaseAddress Then Return 0
	$test = _WinAPI_WriteProcessMemory($hProc, $pBaseAddress, DllStructGetPtr($Buffer), DllStructGetSize($Buffer), $iWriten)
	If Not $test Then
		_WinAPI_ShowLastError()
		Return 0
	EndIf
	GUICtrlSetData($Label9, "Записано " & $iWriten & " байт")
	Return 1
EndFunc   ;==>_WRITEMEM

Func _READMEM()
	Local $sReadBytes = GUICtrlRead($Input5)
	If Not StringRegExp($sReadBytes, "\b\d+\b", 0) Then
		GUICtrlSetData($Label9, "!Ошибка ввода. Допускаются только цифры 0-9")
		GUICtrlSetState($Input5, $GUI_FOCUS)
		Return 0
	EndIf

	GUICtrlSetData($Label9, "")

	Local $ReadBytes, $test, $buff, $pBaseAddress
	Local $ByteSize = Number($sReadBytes)

	$buff = DllStructCreate("byte[" & $ByteSize & "]")
	$pBaseAddress = _GETADSS()
	If Not $pBaseAddress Then Return 0

	$test = _WinAPI_ReadProcessMemory($hProc, $pBaseAddress, DllStructGetPtr($buff), DllStructGetSize($buff), $ReadBytes)
	If Not $test Then
		_WinAPI_ShowLastError()
		Return 0
	EndIf

	GUICtrlSetData($Label9, 'Прочитано ' & $ReadBytes & ' байт')
	Local $OutData = DllStructGetData($buff, 1)
	If Not $OutData Then Return 0

	GUICtrlSetData($Input7, $OutData)

	Local $iBuff = DllStructCreate("int", DllStructGetPtr($buff))
	Local $iData = DllStructGetData($iBuff, 1)
	GUICtrlSetData($Input6, $iData)

	GUICtrlSetData($Input8, BinaryToString($OutData))

	Local $dwBuff = DllStructCreate("DWORD", DllStructGetPtr($buff))
	Local $dwData = DllStructGetData($dwBuff, 1)
	GUICtrlSetData($Input9, $dwData)

	Local $chBuff = DllStructCreate("char[" & $ReadBytes & "]", DllStructGetPtr($buff))
	Local $chData = DllStructGetData($chBuff, 1)
	GUICtrlSetData($Input10, $chData)


	Local $wchBuff = DllStructCreate("wchar[" & $ReadBytes & "]", DllStructGetPtr($buff))
	Local $wchData = DllStructGetData($wchBuff, 1)
	GUICtrlSetData($Input11, $wchData)

	$wchBuff = 0
	$chBuff = 0
	$iBuff = 0
	$OutData = 0
	$dwBuff = 0
	$buff = 0
EndFunc   ;==>_READMEM

Func _WRITEMEMINT()
	Local $sINT = GUICtrlRead($Input6)
	If Not StringRegExp($sINT, "\b\d+\b", 0) Then
		GUICtrlSetData($Label9, "!Ошибка ввода. Допускаются только цифры 0-9")
		GUICtrlSetState($Input6, $GUI_FOCUS)
		Return 0
	EndIf
	GUICtrlSetData($Label9, "")
	Local $dInt = Number($sINT)
	Local $v_Buffer = DllStructCreate("dword")
	DllStructSetData($v_Buffer, 1, $dInt)
	_WRITEMEM($v_Buffer)
	$v_Buffer = 0
EndFunc   ;==>_WRITEMEMINT

Func _WRITEMEMHEX()
	Local $sHEX = GUICtrlRead($Input7)
	If Not StringRegExp($sHEX, '\b0[xX][0-9a-fA-F]+\b', 0) Then
		GUICtrlSetData($Label9, "!Ошибка ввода. Должно начинаться с 0x и допускаютс цифры 0-9 и ABCDEF")
		GUICtrlSetState($Input7, $GUI_FOCUS)
		Return 0
	EndIf
	GUICtrlSetData($Label9, "")
	Local $bHex = Binary($sHEX)
	Local $v_Buffer = DllStructCreate("byte[" & BinaryLen($bHex) & "]")
	DllStructSetData($v_Buffer, 1, $bHex)
	Local $data = DllStructGetData($v_Buffer, 1)
	_WRITEMEM($v_Buffer)
	$v_Buffer = 0
EndFunc   ;==>_WRITEMEMHEX

Func _WRITEMEMTEXT()
	Local $sText = GUICtrlRead($Input8)
	Local $v_Buffer = DllStructCreate("char[" & StringLen($sText) + 1 & "]")
	DllStructSetData($v_Buffer, 1, $sText)
	_WRITEMEM($v_Buffer)
	$v_Buffer = 0
EndFunc   ;==>_WRITEMEMTEXT

Func _WRITEMEMWCHAR()
	Local $sText = GUICtrlRead($Input11)
	Local $v_Buffer = DllStructCreate("wchar[" & StringLen($sText) + 1 & "]")
	DllStructSetData($v_Buffer, 1, $sText)
	_WRITEMEM($v_Buffer)
	$v_Buffer = 0
EndFunc   ;==>_WRITEMEMWCHAR

Func _OpenProc()
	$PID = GUICtrlRead($Input1)
	If StringRegExp($PID, "\b\d+\b", 0) Then
		$hProc = _WinAPI_OpenProcess( __Iif($__WINVER < 0x0600, 0x00000410 + 0x0020 + 0x0008, 0x00001010 + 0x0020 + 0x0008), 0, $PID)
;~ 		$hProc = _WinAPI_OpenProcess(0x1F0FFF, 0, $PID)
		If @error Or Not $hProc Then
			_WinAPI_ShowLastError()
			Return 0
		EndIf
		__EnableControls()
	Else
		GUICtrlSetData($Label3, "ИД процесса - это число!")
		GUICtrlSetState($Input1, $GUI_FOCUS)
		Return 0
	EndIf
	_GETADSS()
	Return 1
EndFunc   ;==>_OpenProc

Func _CloseProc()
	If $hProc Then
		_WinAPI_CloseHandle($hProc)
		$hProc = 0
	EndIf
	__DisableControls()
	__DisableControlsMem()
EndFunc   ;==>_CloseProc

Func _GETADSS()
	Local $sAdds = GUICtrlRead($Input2)
	Local $sOffs = GUICtrlRead($Input3)

	If Not StringRegExp($sAdds, '\b[0-9a-fA-F]+\b', 0) Then
		GUICtrlSetData($Label9, "!Ошибка ввода. Допускаются только цифры 0-9 и буквы ABCDEF")
		GUICtrlSetState($Input2, $GUI_FOCUS)
		__DisableControlsMem()
		Return 0
	EndIf

	If Not StringRegExp($sOffs, '\b[0-9a-fA-F]+\b', 0) Then
		GUICtrlSetData($Label9, "!Ошибка ввода. Допускаются только цифры 0-9 и буквы ABCDEF")
		GUICtrlSetState($Input3, $GUI_FOCUS)
		__DisableControlsMem()
		Return 0
	EndIf
	__EnableControlsMem()
	GUICtrlSetData($Label9, "")

	Local $dAdds = Number("0x" & $sAdds)
	Local $dOffs = Number("0x" & $sOffs)

	Local $ADSS = $dAdds + $dOffs
	GUICtrlSetData($Input4, Hex($ADSS))

	Return $ADSS
EndFunc   ;==>_GETADSS

Func __EnableControls()
	GUICtrlSetData($Label3, "Процесс с ИД " & $PID & " открыт")
	GUICtrlSetState($Button1, $GUI_DISABLE)
	GUICtrlSetState($Button3, $GUI_ENABLE)
EndFunc   ;==>__EnableControls


Func __DisableControls()
	GUICtrlSetData($Label3, "Процесс с ИД " & $PID & " закрыт")
	GUICtrlSetState($Button1, $GUI_ENABLE)
	GUICtrlSetState($Button3, $GUI_DISABLE)
EndFunc   ;==>__DisableControls


Func __EnableControlsMem()
	GUICtrlSetState($Button2, $GUI_ENABLE)
	GUICtrlSetState($Button4, $GUI_ENABLE)
	GUICtrlSetState($Button5, $GUI_ENABLE)
	GUICtrlSetState($Button6, $GUI_ENABLE)
	GUICtrlSetState($Button9, $GUI_ENABLE)
EndFunc   ;==>__EnableControlsMem

Func __DisableControlsMem()
	GUICtrlSetState($Button2, $GUI_DISABLE)
	GUICtrlSetState($Button4, $GUI_DISABLE)
	GUICtrlSetState($Button5, $GUI_DISABLE)
	GUICtrlSetState($Button6, $GUI_DISABLE)
	GUICtrlSetState($Button9, $GUI_DISABLE)
EndFunc   ;==>__DisableControlsMem

Func _SEDEBUG()
	If _GetPrivilege_SEDEBUG() Then
		GUICtrlSetData($Label21, 'да')
	Else
		GUICtrlSetData($Label21, ':(')
	EndIf
EndFunc   ;==>_SEDEBUG

Func _GetPrivilege_SEDEBUG()
	Local $tagLUIDANDATTRIB = "int64 Luid;dword Attributes"
	Local $count = 1
	Local $tagTOKENPRIVILEGES = "dword PrivilegeCount;byte LUIDandATTRIB[" & $count * 12 & "]" ; count of LUID structs * sizeof LUID struct
	Local $TOKEN_ADJUST_PRIVILEGES = 0x20
	Local $call = DllCall("advapi32.dll", "int", "OpenProcessToken", "ptr", _WinAPI_GetCurrentProcess(), "dword", $TOKEN_ADJUST_PRIVILEGES, "ptr*", "")
	Local $hToken = $call[3]
	$call = DllCall("advapi32.dll", "int", "LookupPrivilegeValue", "str", Chr(0), "str", "SeDebugPrivilege", "int64*", "")
;~     msgbox(0,"",$call[3] & " " & _WinAPI_GetLastErrorMessage())
	Local $iLuid = $call[3]
	Local $TP = DllStructCreate($tagTOKENPRIVILEGES)
	Local $LUID = DllStructCreate($tagLUIDANDATTRIB, DllStructGetPtr($TP, "LUIDandATTRIB"))
	DllStructSetData($TP, "PrivilegeCount", $count)
	DllStructSetData($LUID, "Luid", $iLuid)
	DllStructSetData($LUID, "Attributes", $SE_PRIVILEGE_ENABLED)
	$call = DllCall("advapi32.dll", "int", "AdjustTokenPrivileges", "ptr", $hToken, "int", 0, "ptr", DllStructGetPtr($TP), "dword", 0, "ptr", Chr(0), "ptr", Chr(0))
	Return ($call[0] <> 0) ; $call[0] <> 0 is success
EndFunc   ;==>_GetPrivilege_SEDEBUG

Файл: Нет

Скприншот:


История версий:
v1.1
----------------
1. Код более менее продуман. Есть вещи которые я до конца не понимаю, в частности работа со структурами, поэтому код связанный со структурами может быть неоптимизирован.
2. ИД процесса (PID) можно посмотреть в диспетчере задач, на закладке процессы.
3. Адрес в памяти это не базовый адрес процесса/модуля - тут это адрес с которого необходимо считывать байты (В artmoney - это колонка Адрес)
4. Offset - это приращение к адресу, смещение.
5. Количество байт для чтения здесь не ограничено, поэтому при вводе больших значений может возникнуть ошибка частичного чтения/записи (Если по данному адресу находится строка, то установите значение байт равное или больше длинне строки).
6. Некоторые кнопки не активны, это не глюк
7. Скрипт не проверяет активность процесса, и если последний закроется, то никакого уведомления не будет.
8. + Посхалка: Можно включить привелегии дебагера 8)

Требуется: WinAPIEx UDF

Источник: autoit-script.ru
Автор(ы): inververs
 
Верх