Blog. Just Blog

Поиск строки в памяти с использованием маски

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Для поиска произвольной строки в блоке памяти с использованием бинарной маски я написал следующую процедуру:
  1. ; ---------------------------------------------
  2. ; Процедура поиска строки в блоке памяти
  3. ; (C) ManHunter / PCL
  4. ; ---------------------------------------------
  5. ; SRCdata - блок памяти в котором выполняется поиск
  6. ; SRCsize - размер блока в котором выполняется поиск
  7. ; PTRdata - строка для поиска
  8. ; PTRsize - длина строки для поиска
  9. ; MSKdata - бинарная маска для поиска или 0 если не используется
  10. ;
  11. ; Возврат: EAX = offset найденной строки
  12. ;          EAX = -1 если ничего не найдено
  13. ; ---------------------------------------------
  14.  
  15. proc scanmem SRCdata:dword, SRCsize:dword, PTRdata:dword,\
  16.              PTRsize:dword, MSKdata:dword
  17.  
  18.         push    esi edi ebx ecx edx
  19.  
  20.         ; Длина паттерна больше длины данных?
  21.         mov     eax,[PTRsize]
  22.         cmp     eax,[SRCsize]
  23.         ; Да, возврат -1
  24.         ja      .scanmem_not_found
  25.  
  26.         mov     esi,[SRCdata]
  27.         mov     edi,[PTRdata]
  28.         mov     edx,[MSKdata]
  29.         mov     ebx,esi
  30.         add     ebx,[SRCsize]
  31.         sub     ebx,[PTRsize]
  32. .scanmem_loop:
  33.         xor     ecx,ecx
  34. .scanmem_test_char:
  35.         or      edx,edx
  36.         jz      .scanmem_no_mask
  37.         cmp     byte [edx+ecx],0
  38.         jz      .scanmem_char_equal
  39.  
  40. .scanmem_no_mask:
  41.         mov     al,[esi+ecx]
  42.         cmp     al,[edi+ecx]
  43.         jne     .scanmem_next_pattern
  44. .scanmem_char_equal:
  45.         inc     ecx
  46.         cmp     ecx,[PTRsize]
  47.         jb      .scanmem_test_char
  48.         jmp     .scanmem_found
  49. .scanmem_next_pattern:
  50.         inc     esi
  51.         cmp     esi,ebx
  52.         jbe     .scanmem_loop
  53.  
  54. .scanmem_not_found:
  55.         ; Строка не найдена
  56.         mov     eax,-1
  57.         jmp     .scanmem_ret
  58.  
  59. .scanmem_found:
  60.         ; Строка найдена
  61.         mov     eax,esi
  62.  
  63. .scanmem_ret:
  64.         pop    edx ecx ebx edi esi
  65.  
  66.         ret
  67. endp
Пример использования процедуры:
  1. ; Сегмент данных
  2. section '.data' data readable writeable
  3.  
  4. str1    db 'This game has no name',0
  5. slen1   = $-str1
  6. str2    db 'name'
  7. slen2   = $-str2
  8. str3    db 'lame'
  9. slen3   = $-str3
  10.  
  11. mask    db 0,1,1,1   ; 0 - совпадение не обязательно, 1 - совпадение обязательно
  12.  
  13. ; Сегмент кода
  14. section '.code' code readable executable
  15. ...
  16.         ; Поиск с использованием маски
  17.         ; строка поиска = '?ame'
  18.         stdcall scanmem, str1, slen1, str3, slen3, mask
  19.         ; eax => 'game has no name'
  20.  
  21.         ; Поиск без использования маски и такой строки нет
  22.         ; строка поиска = 'lame'
  23.         stdcall scanmem, str1, slen1, str3, slen3, NULL
  24.         ; eax = -1, ничего не найдено
  25.  
  26.         ; Поиск без использования маски (точное совпадение)
  27.         ; строка поиска = 'name'
  28.         stdcall scanmem, str1, slen1, str2, slen2, NULL
  29.         ; eax => 'name'
Длина строки поиска должна быть меньше или равна длине блока памяти, в котором выполняется поиск. Если используется бинарная маска, то ее длина должна в точности совпадать с длиной строки поиска. Значения позиций в маске: 0 - на этой позиции может быть любой символ, 1 - точное совпадение байта в памяти и в строке поиска.

Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 5566 | Комментариев: 5

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
SendMessageA (05.02.2017 в 05:37):
Красота!
Alex (19.03.2014 в 22:44):
Отлично! А как бы этот код использовать в Delphi?
ManHunter (04.05.2011 в 10:42):
Дык, драйвер в руки и с вперед с песней :) API тут не используются, ничего стороннего дергать не надо.
Xanta (03.05.2011 в 20:48):
Еще бы на нулевой уровень да по чужим адресам)
Eugeny (02.01.2011 в 18:18):
Браво!!! Но для простых смертных хорошо бы экзетничек?

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2018
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0028 сек.) / Память: 4.75 Mb
Наверх