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

Для поиска произвольной строки в блоке памяти с использованием бинарной маски я написал следующую процедуру:
; ---------------------------------------------
; Процедура поиска строки в блоке памяти
; (C) ManHunter / PCL
; ---------------------------------------------
; SRCdata - блок памяти в котором выполняется поиск
; SRCsize - размер блока в котором выполняется поиск
; PTRdata - строка для поиска
; PTRsize - длина строки для поиска
; MSKdata - бинарная маска для поиска или 0 если не используется
;
; Возврат: EAX = offset найденной строки
;          EAX = -1 если ничего не найдено
; ---------------------------------------------
 
proc scanmem SRCdata:dword, SRCsize:dword, PTRdata:dword,\
             PTRsize:dword, MSKdata:dword
 
        push    esi edi ebx ecx edx
 
        ; Длина паттерна больше длины данных?
        mov     eax,[PTRsize]
        cmp     eax,[SRCsize]
        ; Да, возврат -1
        ja      .scanmem_not_found
 
        mov     esi,[SRCdata]
        mov     edi,[PTRdata]
        mov     edx,[MSKdata]
        mov     ebx,esi
        add     ebx,[SRCsize]
        sub     ebx,[PTRsize]
.scanmem_loop:
        xor     ecx,ecx
.scanmem_test_char:
        or      edx,edx
        jz      .scanmem_no_mask
        cmp     byte [edx+ecx],0
        jz      .scanmem_char_equal
 
.scanmem_no_mask:
        mov     al,[esi+ecx]
        cmp     al,[edi+ecx]
        jne     .scanmem_next_pattern
.scanmem_char_equal:
        inc     ecx
        cmp     ecx,[PTRsize]
        jb      .scanmem_test_char
        jmp     .scanmem_found
.scanmem_next_pattern:
        inc     esi
        cmp     esi,ebx
        jbe     .scanmem_loop
 
.scanmem_not_found:
        ; Строка не найдена
        mov     eax,-1
        jmp     .scanmem_ret
 
.scanmem_found:
        ; Строка найдена
        mov     eax,esi
 
.scanmem_ret:
        pop    edx ecx ebx edi esi
 
        ret
endp

Пример использования процедуры:
; Сегмент данных
section '.data' data readable writeable
 
str1    db 'This game has no name',0
slen1   = $-str1
str2    db 'name'
slen2   = $-str2
str3    db 'lame'
slen3   = $-str3
 
mask    db 0,1,1,1   ; 0 - совпадение не обязательно, 1 - совпадение обязательно
 
; Сегмент кода
section '.code' code readable executable
...
        ; Поиск с использованием маски
        ; строка поиска = '?ame'
        stdcall scanmem, str1, slen1, str3, slen3, mask
        ; eax => 'game has no name'
 
        ; Поиск без использования маски и такой строки нет
        ; строка поиска = 'lame'
        stdcall scanmem, str1, slen1, str3, slen3, NULL
        ; eax = -1, ничего не найдено
 
        ; Поиск без использования маски (точное совпадение)
        ; строка поиска = 'name'
        stdcall scanmem, str1, slen1, str2, slen2, NULL
        ; eax => 'name'

Длина строки поиска должна быть меньше или равна длине блока памяти, в котором выполняется поиск. Если используется бинарная маска, то ее длина должна в точности совпадать с длиной строки поиска. Значения позиций в маске: 0 - на этой позиции может быть любой символ, 1 - точное совпадение байта в памяти и в строке поиска.
Теги:
Поиск строки
Добавлено: 10 Апреля 2018 20:30:06 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...