Sig

Тема в разделе "WASM.PROJECTS", создана пользователем HoShiMin, 22 окт 2021.

  1. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.422
    Адрес:
    Россия, Нижний Новгород
    Вы часто ищете сигнатурки в бинарных данных?
    Пишете ли вы поиск вручную или используете готовые решения?
    Какой используете формат сигнатур? Однострочный или паттерн + маска?
    Не важно!
    Теперь всё, и даже больше, в формате одной header-only библиотеки на современном C++ с набором тестов!

    Итак, представляю Sig: https://github.com/HoShiMin/Sig

    Библиотека предоставляет поддержку трёх видов сигнатур:
    1. На шаблонах: конструирует код проверки в компайл-тайме.
    2. Паттерн + маска ("\x11\x22\x00\x44" + "..?.")
    3. Однострочный вариант ("11 22 ? 44")

    И всё - с огромным простором для кастомизации, который ограничен лишь вашей фантазией:
    • Поддержка побитовых сравнений
    • Набор из готовых компараторов
    • Поддержка кастомных компараторов
    • Пользовательские типы
    • Контейнер для сравнений "один из"
    • Поддержка диапазонов (от..до)
    • Контейнер-повторитель
    Код (C++):
    1.  
    2. #include <Sig.hpp>
    3.  
    4. int main()
    5. {
    6.     // Поддержка кастомных типов:
    7.     using RelJmp = Sig::Compound<Sig::Byte<E9>, Sig::Dword<>>;
    8.     using Syscall = Sig::Compound<Sig::Byte<0x0F, 0x05>>;
    9.     using Ret = Sig::Compound<Sig::Byte<0xC3>>;
    10.  
    11.     const void* found = Sig::find<RelJmp, Syscall, Ret>(buf, size);
    12.  
    13.     // Гибкое конструирование шаблонов:
    14.     found = Sig::find<
    15.         Sig::Rep<Sig::Char<'r'>, 5>,  // 'r' повторяется 5 раз
    16.         Sig::Set<Sig::Byte<10>, Sig::Dword<0x11223344>>, // Или 10, или 0x11223344
    17.         Sig::Range<Sig::Byte, 3, 7>,  // 3, 4, 5, 6 или 7
    18.         Sig::Byte<>,                  // Любой байт
    19.         Sig::Char<'t', 'e', 'x', 't'> // Последовательность
    20.     >(buf, size);
    21.  
    22.     // Кастомизация компараторов в шаблоне с маской:
    23.     found = Sig::find<
    24.         Sig::Mask::Eq<'.'>,
    25.         Sig::Mask::Any<'?'>,
    26.         Sig::Mask::OneOf<'o'>
    27.     >(buf, size, "\x11\x22\x00\x44\x55\x66", "..?.o.");
    28.  
    29.     // Однострочные сигнатуры:
    30.     found = Sig::find(buf, size, "11 22 ? 44 ??    aA Bb CC dd");
    31. }
    32.  
    Подробный ReadMe и примеры - на страничке проекта на гитхабе.
     
    M0rg0t нравится это.
  2. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.953
    Однажды окинул взором более-менее распространенные движки, не нашел возможности сделать маску на отдельные биты (кроме наркоманской яры, где этого тоже нет, но таки возможность сделать это через задницу есть) и пришлось делать своё. Ну и как бы опять вижу знакомые технологии:
    Снова байты-ниблы. Что-то типа "\x11\x22\x00\x44" + "\xFF\x7F\x00\x44" как раз выгодно отличало бы твою библиотеку. Просто пожелание.
     
  3. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.422
    Адрес:
    Россия, Нижний Новгород
    Так ведь уже можно. Например, в примере выше есть такой вариант:
    Код (C++):
    1.  
    2.     found = Sig::find<
    3.         Sig::Mask::Eq<'.'>,
    4.         Sig::Mask::Any<'?'>,
    5.         Sig::Mask::OneOf<'o'>
    6.     >(buf, size, "\x11\x22\x00\x44\x55\x66", "..?.o.");
    7.  
    Sig::Mask::OneOf - проверяет, что хотя бы один бит из маски взведён в байте из буфера ((byte & mask) != 0).
    Sig::Mask::AllOf - что все биты из маски взведены в байте из буфера ((byte & mask) == mask).

    Т.е., в данном примере будет операция "(byte & 0x55) != 0".

    Это оно?
     
  4. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.953
    Может быть и оно, но тут такая стена текста. Тупо паттерн и маска в шестнадцатиричном виде куда проще и понятней, не надо каждый раз синтаксис мучительно вспоминать.
     
  5. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.422
    Адрес:
    Россия, Нижний Новгород
    Добавил.
    Теперь целых три варианта:
    - Отдельный метод Sig::bitmask(buf, size, "\x11\x22\x00\x44", "\xFF\x7F\x00\x44", 4).
    - Опциональный компаратор в Sig::find<..., Sig::Mask::BitMask<'m'>>(buf, size, "\x11\x22\x00\x44", "\xFF\x7F\x00\x44", "mm.?")
    - Опциональный компаратор в шаблонную генерацию: Sig::find<Sig::Cmp::BitMask<...>>(buf, size);
     
    f13nd нравится это.
  6. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.422
    Адрес:
    Россия, Нижний Новгород
    ...и ещё немножко сахара: при включенной поддержке C++20 добавил возможность искать строки:
    Код (C++):
    1.  
    2. Sig::find<Sig::StrEq<"sample text">, Sig::StrEqNoCase<L"Case-insensitive UTF-16 text">>(buf, size);
    3.  
     
    Aiks нравится это.