purebasic.info

PureBasic forum
Текущее время: Сб сен 22, 2018 10:41 am

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 15 ] 
Автор Сообщение
 Заголовок сообщения: Поиск в памяти процесса
СообщениеДобавлено: Пн фев 07, 2011 11:36 pm 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Ср фев 02, 2011 10:44 am
Сообщений: 382
Откуда: :адуктО
Благодарил (а): 6 раз.
Поблагодарили: 1 раз.
Пункты репутации: 0
Есть пример кода:
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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)
      *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
 
;Ищем дескриптор окна
Define hWnd=FindWindow_(#Null, "Безымянный - Блокнот")
If hWnd
  ScanMemory(hWnd,"Hello",#PB_Unicode)
Else
  MessageRequester("Error","Окно не найдено")
EndIf
 
;Выводим адресса
ForEach VA()
  Debug Hex(VA(),#PB_Integer)
Next


Который позволяет найти значение в памяти процесса (в данном случае ищется "Hello" в памяти блокнота с вписанным в него "Hello").
Изображение
Находится верное значение 9Е008
Как переделать данный код, чтобы в памяти поиск вёлся не по слову"Hello", а по hex значению "48 00 65 00 6C 00 6C 00 6F" (см скрин) ???


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн фев 07, 2011 11:55 pm 
Не в сети
МОДЕРАТОР

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6382
Благодарил (а): 20 раз.
Поблагодарили: 198 раз.
Пункты репутации: 48
kosjachok писал(а):
;Преобразовали строку в нужный формат
Buffer_Len=StringByteLength(FindString$,Method)
*Str_Buffer=AllocateMemory(Buffer_Len)
PokeS(*Str_Buffer,FindString$,-1, Method)

Этот код надо изменить.Выделять память в соответствии с реальными данными и вместо PokeS соответственно PokeB и побайтно из секции данных свои значения "48 00 65 00 6C 00 6C 00 6F". Собственно способ каким будут записаны данные в отведенную память не важен - главное записать - ведь сравнение CompareMemory производиться именно по значению.

_________________
read-only


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт фев 08, 2011 12:59 am 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Ср фев 02, 2011 10:44 am
Сообщений: 382
Откуда: :адуктО
Благодарил (а): 6 раз.
Поблагодарили: 1 раз.
Пункты репутации: 0
А каким макаром в *Str_Buffer
с помощью PokeB() - побайтово записать значение 48 00 65 00 6C 00 6C 00 6F ???
Разбивать строку по пробелам на байты :?:


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт фев 08, 2011 1:27 am 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11255
Благодарил (а): 4 раз.
Поблагодарили: 429 раз.
kosjachok писал(а):
А каким макаром в *Str_Buffer с помощью PokeB()
Выполняй задачу "в лоб"
Код:
1
2
3
4
5
6
7
8
9
10
MemPos=0
PokeB(*Str_Buffer+MemPos, $48) : MemPos+1
PokeB(*Str_Buffer+MemPos, $00) : MemPos+1
PokeB(*Str_Buffer+MemPos, $65) : MemPos+1
PokeB(*Str_Buffer+MemPos, $00) : MemPos+1
PokeB(*Str_Buffer+MemPos, $6C) : MemPos+1
PokeB(*Str_Buffer+MemPos, $00) : MemPos+1
PokeB(*Str_Buffer+MemPos, $6C) : MemPos+1
PokeB(*Str_Buffer+MemPos, $00) : MemPos+1
PokeB(*Str_Buffer+MemPos, $6F) : MemPos+1



PS.
Это случаем не юникодная строка?
Ну да так и есть
Код:
1
2
3
4
5
6
7
8
9
10
11
12
MemPos=0
*Str_Buffer=AllocateMemory(100)
PokeB(*Str_Buffer+MemPos, $48) : MemPos+1
PokeB(*Str_Buffer+MemPos, $00) : MemPos+1
PokeB(*Str_Buffer+MemPos, $65) : MemPos+1
PokeB(*Str_Buffer+MemPos, $00) : MemPos+1
PokeB(*Str_Buffer+MemPos, $6C) : MemPos+1
PokeB(*Str_Buffer+MemPos, $00) : MemPos+1
PokeB(*Str_Buffer+MemPos, $6C) : MemPos+1
PokeB(*Str_Buffer+MemPos, $00) : MemPos+1
PokeB(*Str_Buffer+MemPos, $6F) : MemPos+1
Debug PeekS(*Str_Buffer, -1, #PB_Unicode)


Тогда зачем эти танцы с бубном с работой с отдельными байтами?

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт фев 08, 2011 8:38 am 
Не в сети
МОДЕРАТОР

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6382
Благодарил (а): 20 раз.
Поблагодарили: 198 раз.
Пункты репутации: 48
kosjachok писал(а):
Разбивать строку по пробелам на байты

Можно и проще - преобразовать байты в строку, а дальше как и задумано по коду.
Можно ввести в процедуру поиска ещё один параметр - поиск по HEX значению. Вот что у меня вышло:
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
 
EnableExplicit
 
Global NewList VA()
Global SearchHEX=0
Procedure ScanMemory(hWnd.i, FindString$,SearchHEX, Method=#PB_Ascii, Address.i=0, MaxAddress.i=$7FFFFFFF)
  Define.i PID, hProcess, Buffer_Len, Result, BytesRead, RES, I,StLen
  Define *Str_Buffer, *Region_Buff
  Define MBI.MEMORY_BASIC_INFORMATION
  Define  Simv$, FString$
  ;Узнали PID процесса
  GetWindowThreadProcessId_(hWnd, @PID)
  If PID
   
    ;Открыли процесс для полного доступа (НЕ ВСЕГДА МОЖНО)
    hProcess = OpenProcess_(#PROCESS_ALL_ACCESS|#PROCESS_VM_WRITE|#PROCESS_VM_OPERATION, #False, PID)
    If hProcess
     
      ;Преобразовали строку в нужный формат
      If SearchHEX =#True ; если ищем по HEX значению
         StLen=Len(FindString$)
        For i=1 To StLen Step 2
           Simv$="$"+Mid(FindString$, i, 2)
           FString$=FString$+Chr(Val(Simv$))
        Next
        FindString$=FString$
        EndIf
       Debug FindString$
       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
 
;Ищем дескриптор окна
Define hWnd=FindWindow_(#Null, "Безымянный - Блокнот")
If hWnd
  ScanMemory(hWnd,"480065006C006C006F",#True,#PB_Unicode)
Else
  MessageRequester("Error","Окно не найдено")
EndIf
 
;Выводим адресса
ForEach VA()
  Debug Hex(VA(),#PB_Integer)
Next



Т.о. если мы ищем по hex значению, то выставляем параметр с запросе :
Код:
1
ScanMemory(hWnd,"480065006C006C006F",#True,#PB_Unicode)


#True или 1, а если как обычно словом, то #False или 0.

_________________
read-only


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт фев 08, 2011 12:25 pm 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Ср фев 02, 2011 10:44 am
Сообщений: 382
Откуда: :адуктО
Благодарил (а): 6 раз.
Поблагодарили: 1 раз.
Пункты репутации: 0
kvitaliy
В процедуре только Method=#PB_Ascii - лишнее
А так работает, спасибо!


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт фев 08, 2011 3:14 pm 
Не в сети
профессор

Зарегистрирован: Вт янв 13, 2009 2:41 pm
Сообщений: 370
Благодарил (а): 3 раз.
Поблагодарили: 17 раз.
Пункты репутации: 8
Я делал примерно так:
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
Procedure FindByMask(hProcess.l, StartAddress.l, Mask.s, OffsetAddress.l = 0) ; OffsetAddres - смещение для возврата адреса нужных данных из маски
  Find = #False
  Mask = ReplaceString(Mask, " ", "")
  MaskLen = Len(Mask)/2-1
  If MaskLen > 0
    Dim v.s(MaskLen)
    For i = 0 To (MaskLen)
      v(i) = Mid(Mask, i*2+1, 2)
    Next i
    *buffer = AllocateMemory(1)
    Repeat
      *Address = StartAddress + Offset
      ReadStatus = ReadProcessMemory_(hProcess, *Address, *buffer, 1, #Null)
      If ReadStatus
       
        ;If PeekB(*buffer) = Val("$"+v(0)) ; Если нашли совпадение с первым байтом
        v1.b = PeekB(*buffer)
        v2.b = Val("$"+v(0))
        If v1=v2
          For i = 1 To (MaskLen) ; Тогда сравниваем остальные байты
            If v(i) <> "??" ; Если это не пропуск, тогда читаем данные
              ReadStatus = ReadProcessMemory_(hProcess, *Address + i, *buffer, 1, #Null)
              If ReadStatus
                ;If PeekB(*buffer) = Val("$"+v(i))
                v1.b = PeekB(*buffer)
                v2.b = Val("$"+v(i))
                If v1=v2
                  Find = #True
                Else
                  Find = #False
                  Break
                EndIf
              EndIf
            EndIf
          Next i
        EndIf
      EndIf
        Offset + 1
    Until ReadStatus = 0 Or Find = #True ; Читаем данные, пока они читаются, или пока не найденны нужные данные
    FreeMemory(*buffer)
  EndIf
  If Find = #True
    ProcedureReturn (StartAddress + (Offset-1) + OffsetAddress) ; (Offset-1) так как в конце цикла в любом случае добавится единица
  EndIf
  If ReadStatus = 0
    MessageRequester("Error!", "Access violation when reading to ["+Hex(StartAddress + (Offset-1))+"]", #MB_ICONERROR)
  EndIf
  ProcedureReturn 0
EndProcedure
 
file.s = OpenFileRequester("","","EXE|*.exe",0)
If file
  name.s = GetFilePart(file)
  dir.s = GetPathPart(file)
  size.l = FileSize(file)
  hProcess = RunProgram(file, "",dir,#PB_Program_Open |#PB_Program_Read)
  pid=ProgramID(hProcess)
  hProcess = OpenProcess_(#PROCESS_ALL_ACCESS, #False, pid)
  delay(1000) ; Ждём загрузки процесса
  Mask.s = "E8F8????00E88617????E84C160000E885"
  Debug Hex(FindByMask(hProcess, $401000, Mask, 0))
EndIf


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


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт фев 08, 2011 10:51 pm 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Ср фев 02, 2011 10:44 am
Сообщений: 382
Откуда: :адуктО
Благодарил (а): 6 раз.
Поблагодарили: 1 раз.
Пункты репутации: 0
В блокноте находит, а в процессе игры значения не находит ... ,хотя Cheat Engine в игре находит 9 значений...
что не так?


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт фев 08, 2011 11:09 pm 
Не в сети
профессор

Зарегистрирован: Вт янв 13, 2009 2:41 pm
Сообщений: 370
Благодарил (а): 3 раз.
Поблагодарили: 17 раз.
Пункты репутации: 8
kosjachok писал(а):
В блокноте находит, а в процессе игры значения не находит ... ,хотя Cheat Engine в игре находит 9 значений...
что не так?

Если мой код :?: , то всё очень просто, писалось на скорую руку - если память не может быть прочитана, процедура возвращает 0. Я просто показал свой пример с использованием массива, и, как бонус, возможность игнорирования нужных байтов ("??")


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт фев 08, 2011 11:23 pm 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Ср фев 02, 2011 10:44 am
Сообщений: 382
Откуда: :адуктО
Благодарил (а): 6 раз.
Поблагодарили: 1 раз.
Пункты репутации: 0
Fox
пробовал и твой код - постоянно выдает Access violation when reading to...
в первом варианте вроде тоже есть проверка на
If MBI\Protect <> #PAGE_READONLY ....и т.д
но ошибок не выдает, сканит долго - но результат - 0


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср фев 20, 2013 6:31 pm 
Не в сети
доцент
Аватар пользователя

Зарегистрирован: Пн окт 25, 2010 12:59 pm
Сообщений: 46
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
kosjachok, kvitaliy
Офигенно, как раз это и искал!
Пётр писал(а):
PokeB(*Str_Buffer+MemPos, ...) : MemPos+1

даже не догадывался что так можно, спасибо.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Чт фев 21, 2013 1:42 am 
Не в сети
доцент
Аватар пользователя

Зарегистрирован: Пн окт 25, 2010 12:59 pm
Сообщений: 46
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
Используя любой код из приведённых здесь, поиск работает раз в 20 медленнее чем поиск в хекс-редакторе по памяти процесса. Есть ли другой алгоритм? Слишком уж долго если к примеру игра занимает 200 мегабайт памяти и выше.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Чт фев 21, 2013 9:54 pm 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Вс ноя 07, 2010 12:19 pm
Сообщений: 281
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
osg
Тогда выполняйте поиск без копирований, тоесть инжектите код в целевой процесс и сканите память непосредственно камнем.

_________________
Materia Lucida


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт фев 26, 2013 4:24 pm 
Не в сети
доцент
Аватар пользователя

Зарегистрирован: Пн окт 25, 2010 12:59 pm
Сообщений: 46
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
Indy
Не знаю как это сделать, если можно набросайте пример.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re:
СообщениеДобавлено: Сб фев 17, 2018 9:53 pm 
Не в сети
профессор

Зарегистрирован: Сб фев 06, 2016 6:18 pm
Сообщений: 271
Благодарил (а): 14 раз.
Поблагодарили: 32 раз.
Пункты репутации: 0
Indy писал(а):
сканите память непосредственно камнем.
Дайте ссылку что почитать :)

Надо же:
С выключенным отладчиком работает норм :)


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 15 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group (блог о phpBB)
Сборка создана CMSart Studio
Русская поддержка phpBB