Что нового

Перевод кода работы с памятью с PureBasic на AutoIt

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Большую часть уже перевёл, есть нативные функции в PureBasic которые я не могу подобрать на AutoIt'e, данный скрипт ищет в памяти процесса базовый адрес искомой строки (данных).

PureBasic
Код:
EnableExplicit 

Global NewList VA() 

Procedure ScanMemory(hWnd.i, FindString$, Method=#PB_Ascii, Address.i=0, MaxAddress.i=$7FFFFFFF) 
  Define.i PID, hProcess, Buffer_Len, Result, BytesRead, RES, I 
  Define *Str_Buffer, *Region_Buff 
  Define MBI.MEMORY_BASIC_INFORMATION 
  
  ;Узнали PID процесса 
  GetWindowThreadProcessId_(hWnd, @PID) 
  If PID 
    
    ;Открыли процесс для полного доступа (НЕ ВСЕГДА МОЖНО) 
    hProcess = OpenProcess_(#PROCESS_ALL_ACCESS|#PROCESS_VM_WRITE|#PROCESS_VM_OPERATION, #False, PID) 
    If hProcess 
      
      ;Преобразовали строку в нужный формат 
      Buffer_Len=StringByteLength(FindString$,Method) 
      Debug Buffer_Len
      *Str_Buffer=AllocateMemory(Buffer_Len) 
      PokeS(*Str_Buffer,FindString$,-1, Method) 
      
      ;Сканируем память 
      Repeat 
        Result=VirtualQueryEx_(hProcess, Address, @MBI.MEMORY_BASIC_INFORMATION, SizeOf(MEMORY_BASIC_INFORMATION)) 
        If Result 
          If MBI\State = #MEM_COMMIT 
            ;Перечисляем доступ, чтобы нам не выдавало адреса которые мы не сможем править потом 
            If MBI\Protect <> #PAGE_READONLY And MBI\Protect <> #PAGE_EXECUTE_READ And MBI\Protect <> #PAGE_GUARD And MBI\Protect <> #PAGE_NOACCESS 
              *Region_Buff=AllocateMemory(MBI\RegionSize) 
              RES=ReadProcessMemory_(hProcess, Address, *Region_Buff, MBI\RegionSize, @BytesRead) 
              If BytesRead > 0 
                For I = 0 To BytesRead 
                  If CompareMemory(*Region_Buff + I, *Str_Buffer, Buffer_Len) 
                    AddElement(VA()) 
                    VA() = MBI\BaseAddress+I 
                  EndIf 
                Next 
              EndIf 
              FreeMemory(*Region_Buff) 
            EndIf 
          EndIf 
          Address=MBI\BaseAddress+MBI\RegionSize 
        Else 
          Break 
        EndIf 
      Until  Address >= MaxAddress 
      FreeMemory(*Str_Buffer) 
      CloseHandle_(hProcess) 
    Else 
      MessageRequester("Error","Не удалось открыть процесс") 
    EndIf 
  Else 
    MessageRequester("Error","Не удалось получить PID") 
  EndIf 
EndProcedure 

ProcedureDLL.s MemoryScan(Title.s, Text.s)
  Define Result.s = ""
  Define hWnd=FindWindow_(#Null, Title) 
  If hWnd 
    ScanMemory(hWnd,Text,#PB_Unicode) 
    ForEach VA()
      Result = Result + Hex(VA(),#PB_Integer) + "|"
    Next  
  EndIf 
  ProcedureReturn Result
EndProcedure  

Debug MemoryScan("Текстовый документ (2) - Блокнот", "Hello")

AutoIt
Код:
#Include <WinAPIEx.au3>
#Include <ProcessConstants.au3>
#Include <Memory.au3>
#Include <MemoryConstants.au3>
#Include <Array.au3>

$hWnd = WinGetHandle('Текстовый документ (2) - Блокнот')
If $hWnd Then
    $Address = ScanMemory($hWnd, "Hello", 0, 0x7FFFFFFF)
	If IsArray($Address) Then
		_ArrayDisplay($Address)
	EndIf
EndIf

Func ScanMemory($hWnd, $String, $MinAddress, $MaxAddress)
	Local $GetAddres[1] = [0]
	Local $iPid, $tMBI = DllStructCreate("Ptr BaseAddress; Ptr AllocationBase;  DWORD AllocationProtect; DWORD RegionSize; DWORD State; DWORD Protect;  DWORD Type;")
	Local $hProc, $hData, $Result, $BitRead
	_WinAPI_GetWindowThreadProcessId($hWnd, $iPid)

    If $iPid Then
		$hProc = _WinAPI_OpenProcess(BitOR($PROCESS_ALL_ACCESS, $PROCESS_VM_WRITE, $PROCESS_VM_OPERATION), False, $iPid)
		If $hProc Then
			$iLen = StringLen($String)
			$hData = _MemGlobalAlloc($iLen * 2)
            ; Здесь не знаю что вставлять

			Do
				$Result = DllCall("Kernel32.dll", 'int', 'VirtualQueryEx', 'int', $hProc, 'ptr', $MinAddress, 'ptr', DllStructGetPtr($tMBI), 'int', DllStructGetSize($tMBI))
				If $Result[0] Then
					If DllStructGetData($tMBI, 'State') = $MEM_COMMIT Then
						$Protect = DllStructGetData($tMBI, 'Protect')
						If (($Protect <> $PAGE_READONLY) And ($Protect <> $PAGE_EXECUTE_READ) And ($Protect <> $PAGE_GUARD) And ($Protect <> $PAGE_NOACCESS)) Then
							$Region = _MemGlobalAlloc(DllStructGetData($tMBI, 'RegionSize')) ; C этими функциями вообще не понимаю как работать
							
							$Res = _WinAPI_ReadProcessMemory($hProc, $MinAddress, $Region, DllStructGetData($tMBI, 'RegionSize'), $BitRead)
							If $BitRead > 0 Then
								For $i = 0 To $BitRead ; Здесь тоже не пойму
									ReDim $GetAddres[$GetAddres[0] + 1]
									$GetAddres[$GetAddres[0]] = DllStructGetData($tMBI, 'BaseAddress')
								Next
							EndIf
                            _MemGlobalFree($Region)
						EndIf
					EndIf
					Return $GetAddres
				Else
					ContinueLoop
				EndIf
			Until $MinAddress >= $MaxAddress
			_MemGlobalFree($hData)
			_WinAPI_CloseHandle($hProc)
		Else
            Return 'No Process'
		EndIf
	Else
        Return 'No Pid'
	EndIf
EndFunc
 
Верх