Поиск в массиве байтов по маске

Тема в разделе "WASM.A&O", создана пользователем koderr, 23 янв 2007.

  1. koderr

    koderr New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    205
    Как сие реализовать? Маска типа "EB 00 00 ?? ?? 68 33 C0 ??". Пробовал сам написать, но что-то ужасное выходило (особенно с вопросительными знаками).
     
  2. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    что-то типа:
    Код (Text):
    1. UCHAR mask[] = {0xEB, 0x00, 0x00, 0x00, 0x00, 0x68, 0x33, 0xC0, 0x00};
    2. UCHAR skip[] = {0, 0, 0, 1, 1, 0, 0, 0, 1};
    3.  
    4. int CompareMask(UCHAR *b, int masklen){
    5.   for (int i = 0; i < masklen; i++)
    6.     if ((!skip[i]) && (mask[i] != b[i]))
    7.       return 0;
    8.   return 1;
    9. }
     
  3. koderr

    koderr New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    205
    n0name
    Нехорошо держать два массива, и функция должна возвращать указатель на найденную последовательность байтов.
     
  4. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    А как иначе. Можешь объеденить в один, но USHORT. Памяти столько-же, но код объёмнее и медленнее.
    Это функция сравнения с маской.
    Код (Text):
    1. UCHAR *SearchMask(UCHAR *data){
    2.   UCHAR *ret = data;
    3.   while (!CompareMask(ret++, 9)) ;
    4.   return ret;
    5. }
     
  5. koderr

    koderr New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    205
    n0name
    А если возьмем маску "EB0000????6833C0??"
    и вот так поступим?

    Код (Text):
    1. int CompareMask(UCHAR *b, int masklen){
    2.   for (int i = 0; i < masklen; i++)
    3.   {
    4.      if (mask[i*2] == mask[i*2+1] == '?') continue;
    5.      if (hex2byte(mask[i*2]) == b[i])
    6.       return 0;
    7.   }
    8.   return 1;
    9. }
     
  6. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    koderr
    Опять же, выйгрыша по памяти нет, падение в скорости, причём значительное.
     
  7. koderr

    koderr New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    205
    n0name
    Ну, файлы будут размером << 1 Mb :) Тем более поиск только по секции кода.
     
  8. LazzY

    LazzY New Member

    Публикаций:
    0
    Регистрация:
    6 мар 2006
    Сообщения:
    123
    koderr
    сорцы snr из дупа открыты =\
     
  9. DelExe

    DelExe New Member

    Публикаций:
    0
    Регистрация:
    22 авг 2005
    Сообщения:
    165
    Можно так:
    EB 00 00 ?? ?? 68 33 C0 ??

    char code[] = "\xEB\x00\x00\xFF\xFF\x68\x33\xC0\xFF";
    void *s = CODEUTIL::SearchCode((HINSTANCE)lpMappedFile, (LPBYTE)code, sizeof(code)-1, (LPBYTE)"111001110");

    Остаётся файл мапнуть в память: CreateFile, CreateFileMapping, MapViewOfFile
     
  10. koderr

    koderr New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    205
    DelExe
    Мапать-то мы умеем :)
     
  11. koderr

    koderr New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    205
    Спасибо всем, кто помогал.
    Проблему решил просто - т.к. маска короткая (15 байт, а значащих всего 3), сделал просто что-то типа этого в цикле
    Код (Text):
    1. .if byte ptr [eax] == 68h && byte ptr [eax + 5] == 68h && byte ptr [eax + 10] == 0E8h
    2.     ;....
    3. .endif