Дизасм длин и тестирование

Тема в разделе "WASM.RESEARCH", создана пользователем shchetinin, 2 сен 2011.

  1. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    Зачем нужен дизасм длин ? обсуждать не будем.
    Вопрос в том как его лучше протестировать? (брать готовые или у меня есть кум который был моим хорошим другом, а в детстве он решал крутые задачи и написал крутой LDE - не принимаются )
    Вообще два рода тестов:
    - Правильность
    - Скорость


    Правильность :
    1) Как вариант сгенирировать большую таблицу со всеми инструкциями и сообственно говоря и сделать тест , но во первых не из чего генерировать а во вторых очень долгий тест.
    2) Из каждой группы взять по N инструкций и проверять(можно забыть про какуету группу (( )
    Какие буду варианты?

    Скорость:
    Зачекать время, но проблема будет в том какие инструкции будут дизасмится, ( с префиксом или без, 1 или двух байтовые) вообщем сдесь как понимаю нужна статистика используемых инструкций для задач в которым юзается дизасм длин , или ошибаюсь?


    П.С.
    Я не претендую что мои мысли основаны на здравом смысле, и кому то может показатся отсутствия смысла воовсе..
    В данном конексте интересна теория. спасибо.
     
  2. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    1) Это нетрудно, сгенерировать все инструкции. 1, 2, 3 байтные опкоды перебрать в простом цикле. Используя уже известный отлаженный дизассемблер длин. Кстати такой вот дизассемблер длин отлаженный уже имеется в каждом процессоре.
    А да так как опкодов всего чучуть то длина такого теста будет всего несколько килобайт около 10-20кбайт.
     
  3. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    Pavia
    Сгенирить таблицу байт без проблем, вот только как сверять с ответами? То и есть после генерации мы ведь не знаем сколько байт инструкция, а остальное мусор?:)
     
  4. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    shchetinin
    Используй сторонней дизассемблер длин для проверки своего. В конце концов можно включить режим трассировки и смотреть разницу ip.
     
  5. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    Pavia
    Разницу ипов можно посмотреть если код валидный, в смысле сепшенов нет ... Сторонний канечно можно но хотелось бы как то изящней.
     
  6. s_d_f

    s_d_f New Member

    Публикаций:
    0
    Регистрация:
    15 май 2008
    Сообщения:
    342
    Если сторонний взять не вариант, тогда возможно пошаговая трасировка из Debug API подойдёт. Пример лежит здесь http://wasm.ru/article.php?article=1001030.
     
  7. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    s_d_f
    Зачем сдесь пошагавая трасировка? вы на угад пишете?
     
  8. s_d_f

    s_d_f New Member

    Публикаций:
    0
    Регистрация:
    15 май 2008
    Сообщения:
    342
    Можно получать аддресса исполняемых инструкций и дальше вычислять их длину.
    Похоже Pavia уже писал про это, только я не заметил.
     
  9. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    s_d_f
    Вот вопрос в том на сколько правильно вычисляется длинна инструкций , а остальное не надо:)
     
  10. deLight

    deLight New Member

    Публикаций:
    0
    Регистрация:
    26 май 2008
    Сообщения:
    879
    shchetinin
    Корявенько, но с сепшенами можно придумать.

    EIP EIP+0Fh (max_len)
    V V
    xx xx xx ... xx xx xx cc cc cc cc ...

    Выполнили. Сепшен выбрасывается или в одной из инструкций, или на нашем int3 по eip+0fh.
    В хендлере сохранили весь контекст и ExceptionRecord. После дизасма оставляем только
    кусок предполагаемой длины:

    EIP EIP+expected_len
    V V
    xx xx ... xx cc cc cc cc ...

    Выполняем снова. Сравниваем контекст и сепшенинфо с предыдущими. Совпало - отдизасмили
    корректно. Ветвления, наверное, обрабатываем руками, тк с ними лишний геммор и двусмысленности.
     
  11. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.348
    shchetinin
    Pavia
    :)
    для интереса сгенерировал все инструкции (32-х битный режим; без префиксов, только опкод, modr/m и смещение, где нужно) для опкодов
    Код (Text):
    1. xxxxxxdw : modr/m
    2. xxxxxxxx : modr/m
    3. xxxxxxxw : modr/m
    (3 группы из 28)

    итого 286664 инструкции, 1370984 байт.

    http://depositfiles.com/files/98dq1zt1o
     
  12. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    deLight
    0xCD 0x01
    Или
    0xFF 0x15 0x00 0x00 0x00 0x06
    Уже не отработает, это то что по памяти:)
     
  13. deLight

    deLight New Member

    Публикаций:
    0
    Регистрация:
    26 май 2008
    Сообщения:
    879
    shchetinin
    Угу. Нее6а6ельный вариант, совсем.
     
  14. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    deLight
    :)


    Воощем вывод надо брать Distrom или Beaengine и генерить, генерить ... :)
     
  15. slesh

    slesh New Member

    Публикаций:
    0
    Регистрация:
    6 фев 2009
    Сообщения:
    214
    все варианты сгенерить нереально. по этому всё равно надо будет разбирать инструкцию по частям. А то так выходит что для mov eax, Z будет 4 миллиарда комбинаций.

    Так то проще взять официальную интеловскую (и амд) доку и посмотреть как генерятся все инструкции.
    Затем на основе этого уже генерировать таблицу всевозможных комбинаций убрав значения и адреса. Не забывая про оптимизированные опкоды (в частности для работы с регистром eax для одинаковых команд есть 2 разных опкода (стандартный и короткий))
     
  16. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    slesh
    Генерировать таблицу с изменениями первых трех байт этого будет достаточно(остальные байты nop)
     
  17. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.348
    как вариант, родилась утиль:

    [​IMG]

    пока генерит только инструкции для 32-битного режима без префиксов,
    весь набор общего назначения (xx) и расширенные (0f xx).
    Проверяется как правильность декодирования валидных инструкций, так
    и неправильность декодирования инвалидных.

    Тестируемый дизассемблер оформляется в виде dll с интерфейсом
    Код (Text):
    1. extern "C"
    2. {
    3.     const char    _declspec(dllexport) * Name();
    4.     const char    _declspec(dllexport) * Description();
    5.     unsigned int  _declspec(dllexport) Version();
    6.     void          _declspec(dllexport) * AllocStruct();
    7.     void          _declspec(dllexport) FreeStruct(void*);
    8.     int           _declspec(dllexport) Disassemble(unsigned char*, int, bool, void*);
    9.     bool          _declspec(dllexport) FormatMnemonic(void*, char*, int);
    10. };
    (все функции в экспорте должны быть без манглинга, _cdecl)
    (пример dll в аттаче)

    Name()
    возвращает указатель на строку с именем дизассемблера

    Description()
    >> >> с описанием

    Version()
    версия движка (hiword - major version, loword - minor version)

    AllocStruct()
    многие движки возвращают результат декодирования в какой-либо структуре.
    Эту структуру и выделяет функция. Формат структуры не имеет значения -
    генератор ее не использует. Этот указатель будет передаваться в Disassemble()
    и FormatMnemonic()

    FreeStruct()
    в описании не нуждается :)

    Disassemble()
    декодирует переданную инструкцию.
    первый параметр - указатель на массив unsigned char[15] с кодом
    второй - длина инструкции
    третий - true, если инструкция корректна
    четвертый - указатель на структуру, возвращенный AllocStruct()

    возвращаемые значения:
    -1 - внутренняя ошибка движка (неверный параметр, не хватает памяти, etc.)
    0 - инструкция некорректна
    иначе, длина инструкции

    FormatMnemonic()
    генератором пока не используется.


    если есть желание, тестируйте...