The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

Релиз системы разбора бинарных файлов Kaitai Struct 0.6

04.02.2017 18:20

Вышел очередной релиз языка разбора произвольных бинарных файлов Kaitai Struct 0.6, приуроченный к конференции FOSDEM 2017. Язык позволяет создавать спецификации произвольных бинарные форматы файлов / пакетов / протоколов, после чего можно:

  • Визуализировать данные в этом формате в виде интерактивного дерева объектов, наблюдая каким байтам в дампе соответствуют какие значения:
  • Получить наглядную диаграмму формата с помощью GraphViz
  • Скомпилировать спецификацию формата в готовую библиотеку парсинга формата на языках C++, C#, Java, JavaScript, Perl, PHP, Python, Ruby

Среди основных нововведений версии 0.6 можно выделить:

  • Поддержка невыравненного (unaligned) побитового чтения (удобно поддерживать битовые поля, можно читать потоки битов и т.д.)
  • Мощная поддержка метаинформации в .ksy (добавлены поля "title", "license", "ks-version", "ks-debug"), поддержка "doc" на уровне типов
  • Enum'ы выведены на уровень типов - т.е. теперь они корректно раскрываются, их можно использовать между разными уровнями вложенности типов (даже если поддержки такой области видимости нет в целевом языке - например, в Python, PHP или JavaScript)
  • Идентификатор (id) в атрибутах в seq теперь опционален; если его не указывать, будет автоматически сгенерирован численный идентификатор - это удобно для быстрой разметки неизвестных форматов
  • Вычислимые instances теперь могут использовать "if" и "enum"
  • Поддержка ссылок на внешние типы данных - можно использовать "type: xxx", где xxx не объявлен в текущем .ksy-файле - это создаст правильные инструкции import / include в предположении, что тип xxx описан в каком-то другом .ksy файле, который будет также собран вместе с этим проектом
  • В языке выражений теперь можно использовать числовые литералы с визуальными разделителями (например, "123_456_789" или "0b0101_0011"), а также метод "to_s" у целочисленных типов для преобразования к строке
  • Множество других исправлений ошибок и оптимизаций (как по проекту в целом, например, в механизме выведения типов, так и по компиляторам конкретных целевых языков)


  1. Главная ссылка к новости (http://kaitai.io/news/2017-02-...)
  2. OpenNews: Вышел язык спецификации бинарных форматов Kaitai Struct 0.5
  3. OpenNews: Релиз системы разбора произвольных бинарных файлов Kaitai Struct 0.4
  4. OpenNews: Kaitai Struct запустил веб-версию компилятора
  5. OpenNews: Декларативная спецификация парсинга бинарных файлов Kaitai Struct
Автор новости: GreyCat
Тип: Программы
Ключевые слова: kaitai
При перепечатке указание ссылки на opennet.ru обязательно
Обсуждение (20) Ajax | 1 уровень | Линейный | +/- | Раскрыть всё | RSS
 
  • 2.5, saahriktu (ok), 01:43, 05/02/2017 [ответить]  
  • +/
    Слакбилд уже есть: https://github.com/saahriktu/saahriktu-slackbuilds/tree/master/kaitai-struct-c .

    Только без рантайма оно не очень полезно. Надо ещё рантайм притащить.

     
     
  • 3.10, GreyCat (ok), 03:18, 05/02/2017 [^] [^^] [^^^] [ответить]  
  • +/
    > Слакбилд уже есть: https://github.com/saahriktu/saahriktu-slackbuilds/tree/master/kaitai-struct-c

    Спасибо! В Arch, кстати, тоже кто-то пакет сделал: https://aur.archlinux.org/packages/kaitai-struct-compiler/ - да еще и весьма оперативно его обновляет. Надо, что ли, список неофициальных пакетов завести?..

    > Только без рантайма оно не очень полезно. Надо ещё рантайм притащить.

    Какой из? Все 8? Рантайм в норме обычно приносится пакетной системой целевого языка, обычно его незачем паковать (а для C++ еще и довольно вредно - типично его лучше статически линковать, чтобы все однострочные функции инлайнить, но некоторые все равно динамически хотят).

     
     
  • 4.21, Michael Shigorin (ok), 22:50, 05/02/2017 [^] [^^] [^^^] [ответить]  
  • –2 +/
    > Надо, что ли, список неофициальных пакетов завести?..

    А эт твоё, Миш? :)

     
     
  • 5.23, GreyCat (ok), 23:55, 05/02/2017 [^] [^^] [^^^] [ответить]  
  • +1 +/
    >> Надо, что ли, список неофициальных пакетов завести?..
    > А эт твоё, Миш? :)

    Ну теперь уже командное ;) А так - начинал несколько лет назад я, да и до сих пор, наверное, процентов 80 кода написано мной.

     
  • 1.6, Pilat (ok), 01:51, 05/02/2017 [ответить] [﹢﹢﹢] [ · · · ]  
  • +2 +/
    Биты это интересно. Вот примеров маловато, и в документации мышь повесилась... Но всё равно спасибо.
     
     
  • 2.7, GreyCat (ok), 02:38, 05/02/2017 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Документация потихоньку новая пишется в районе https://github.com/kaitai-io/kaitai_struct_doc/blob/master/user_guide.adoc
     

  • 1.12, Аноним (-), 11:20, 05/02/2017 [ответить] [﹢﹢﹢] [ · · · ]  
  • –1 +/
    средство для реверс-инжиниринга?
     
     
  • 2.14, GreyCat (ok), 12:24, 05/02/2017 [^] [^^] [^^^] [ответить]  
  • +2 +/
    Не обязательно, но в том числе. Позволяет быстро проверять тучу гипотез при black-box-style реверсинге, чем сильно упрощает жизнь.
     
     
  • 3.15, Stax (ok), 14:22, 05/02/2017 [^] [^^] [^^^] [ответить]  
  • +/
    А насколько оно удобно для разбора битых данных? Т.е. позволяет с легкостью вклинивать логику, когда что-то не сходится (и этой самой логикой, те кодом на обычном языке переместится на нужное смещение, обходя проблему)?

    Ну то есть, например, написать на нем средство для извлечения максимума корректных данных из битой postgresql-базы (просто в качестве абстрактного примера). Т.е. чего-то, где в середине потока "едут" заголовки и нужно на внешнюю логику отдавать неразобранные битые куски и просить ее синхронизировать до следующего осмысленного заголовка.

    Просто реально горит :) написать такую штуку, парзер со всеми нюансами с нуля писать очень лень (= нет возможности выделить на это время), да и декларативное описание очень бы помогло, т.к. формат может меняться и совершенствоваться. Побитости - реальность (ведется он так, в append-only режиме, и возможны куски с мусором. Основная реализация при считывании этих данных умеет умно обходить этот мусор), но мне ее использовать не выйдет, т.к. она слишком объединена с логикой того продукта.

    Читал https://github.com/kaitai-io/kaitai_struct/issues/49 но это не то, нужно именно "если что-то идет не так, отдавать в руки внешней логики, пусть она получает весь битый бинарный блок до следующего заголовка и принимает от нее информацию, что вот тут следующий заголовок". (там возможны разного вида и под-заголовки, и "большие" заголовки, и описать синхронизацию декларативно сложновато).
    Да и кусок нужен предыдущий (т.е. корректный заголовок показал, что дальше 2 МБ данных, считали, вернули в приложение, а следующего заголовка не нашлось - значит битость именно в заголовке, который "2 МБ" сообщил была, а следующий кусок - когда найдем заголовок - может и нормальный. Но битые данные все равно нужны).

    Меня пока интересует просто оценка, можно ли малой кровью такое сделать или лучше не пытаться и писать сразу весь разбор с нуля.

     
     
  • 4.16, GreyCat (ok), 15:03, 05/02/2017 [^] [^^] [^^^] [ответить]  
  • +/
    Вопрос про "разбор битых данных" задают примерно с регулярностью пару раз за релиз ;)

    Проблема в том, что это в целом достаточно комплексная задача, которую надо делить на части:

    1. Определять ситуацию, что данные "битые". Это в ближайшее время появится, можно будет поувешивать все всевозможными проверками, чтобы точно гарантировать общую вменяемость читаемого.

    2. Реагировать на провалившиеся проверки. Это сложнее, тут надо думать. Самое тупое решение в лоб - провалившаяся проверка выкидывает exception - дальше вызывавший его код ловит и делает какие-то действия по восстановлению, если сочтет нужным, сам. Например, двигается куда-то по стриму и вызывает парсинг повторно. Варианты автоматизации и реализации таких действий внутри ksy надо продумывать. Очевидные варианты типа "сдвинуться на +1, +n, (+n) % m байт и попробовать заново" в принципе можно описать, но иногда бывают и куда более хитрые алгоритмы восстановления, синхронизации и realingment. Например, с откатом назад и особенно противно - с полноценным backtracking, когда надо перепарсить все на несколько уровней вверх, приняв альтернативную парадигму.

    Я бы на вашем месте попробовал - вызывать парсинг по кусочкам по идее несложно, никто ж не требует прямо одним вызовом все сделать на автомате. Ресинхронизацию и пропуск при exception'е сделать во внешней вызывающей программе по идее должно быть не так сложно, если я правильно понимаю схему бинарного лога PgSql. В самом крайнем случае никто не мешает взять сгенерированный код и что-то в нем поправить руками. Все лучше, чем совсем вслепую копаться по старинке, без автоматической визуализации и т.д.

     
     
  • 5.17, Stax (ok), 16:45, 05/02/2017 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Поднимается, потому что задач таких много, а KS штука вкусная, судя по описаниям, и хочется совместить :)

    1 - сигнатуры следующего заголовка нет в нужном месте, значит битые. С точки зрения автоматического анализа - в том-то и фишка, что тут нужно передать всю бинарщину в "умный" код (не декларативный). А от него в итоге получить в ответ, где следующий заголовок

    2 - да, именно это и хочется. Чтобы выкинули и можно было самостоятельно сдвинуться, потом вернуть управление. Все равно "весь" объект разом разбирать не надо (он может быть длиной и в терабайт, и вообще быть живым дописываемом в процессе обработки потоком). Т.е. так сейчас можно?
    Условно говоря, иметь внешний алгоритм синхронизации и хук в него. Зачем мучаться и описывать декларативно возможные ошибки, если в обычный код эвристику впихнуть намного проще?

    3 - pgsql это просто был пример для обрисовывания картины, реально речь идет про другую значительно менее известную штуку (хотя тоже что-то типа БД).

    Про поправить код руками я, конечно, понимаю, но вот именно для этого и хотелось бы использовать Kaitai Struct. Там время от времени формат файла меняется, и есть необходимость поддерживать разные версии. Если бы не этот факт, можно было и не брать декларативные описания.. а в текущих реалиях без них просто будет некрасиво. И, конечно, хотелось бы использовать сколько-либо готовое решение, я не писать с нуля автомат. А если код менять руками, то как потом менять описание?.. Поменяешь и опять вручную на этот код накатывать изменения.. брр.

     
     
  • 6.18, GreyCat (ok), 17:26, 05/02/2017 [^] [^^] [^^^] [ответить]  
  • +/
    Ну, в самом тупом виде, в управляющей программе что-то типа while io eof ... текст свёрнут, показать
     
     
  • 7.20, Stax (ok), 22:45, 05/02/2017 [^] [^^] [^^^] [ответить]  
  • +/
    Ага, спасибо. Ну мне, как человеку, еще не работавшему с этим - не очевидно было, что можно сделать внешний seek() и оно продолжит работать, т.е. оно не хранит кучу внутренних состояний и позволяет вот так просто вмешиваться в обработку. Если позволяет, то все ок. Надо попробовать.
     
     
  • 8.22, GreyCat (ok), 22:56, 05/02/2017 [^] [^^] [^^^] [ответить]  
  • +/
    Ну, там все банально io в данном случае - это нативный стрим-объект языка, об... текст свёрнут, показать
     
  • 4.19, аноним2 (?), 19:31, 05/02/2017 [^] [^^] [^^^] [ответить]  
  • +/
    Попробуй еще construct https://github.com/construct/construct

    Правда, когда приходится крутиться со всякими сложными условиями: например вставить свой код, для вычисления какой-либо хитрой штуки - хочется выйти в окно автора за то, что он не придумал более легкого способа.

     
     
  • 5.24, Stax (ok), 13:42, 06/02/2017 [^] [^^] [^^^] [ответить]  
  • +/
    > Попробуй еще construct https://github.com/construct/construct
    > Правда, когда приходится крутиться со всякими сложными условиями: например вставить свой
    > код, для вычисления какой-либо хитрой штуки - хочется выйти в окно
    > автора за то, что он не придумал более легкого способа.

    Спасибо. Тоже, вероятно, годно. Хотя синтаксис там несколько шизоидный :) https://github.com/construct/construct/blob/master/construct/examples/protocol - тот еще "питон". Но с ExprAdapter фокусы прикольные.

     
     
  • 6.25, GreyCat (ok), 21:09, 06/02/2017 [^] [^^] [^^^] [ответить]  
  • +/
    Реально шизоидный - это в Construct3, они там кучу всего накрутили с syntactic sugar ;)

    А так - инструмент как инструмент для своих задач. Если нужно оставаться строго в рамках одного языка - таких как раз масса. Вот человек тут коллекционирует: https://github.com/dloss/binary-parsing

     

  • 1.26, hhg (ok), 22:22, 10/02/2017 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    документация краткая, предлагаю первым пунктом вставить ссылку на тесты, несущие куда больше знаний:
    https://github.com/kaitai-io/kaitai_struct_tests/tree/master/formats

    а в визуализаторе нет вывода текущего атрибута "doc" в нижнюю строку терминала.

     
     
  • 2.27, GreyCat (ok), 22:23, 10/02/2017 [^] [^^] [^^^] [ответить]  
  • +/
    > документация краткая, предлагаю первым пунктом вставить ссылку на тесты, несущие куда больше
    > знаний:
    > https://github.com/kaitai-io/kaitai_struct_tests/tree/master/formats

    Более полная есть пока тут:
    https://github.com/kaitai-io/kaitai_struct_doc/blob/master/user_guide.adoc

    > а в визуализаторе нет вывода текущего атрибута "doc" в нижнюю строку терминала.

    Сделаем...

     
     
  • 3.28, hhg (ok), 22:41, 10/02/2017 [^] [^^] [^^^] [ответить]  
  • +/
    где-то видел список поддерживаемых кодировок для строк, теперь найти не могу.

    для строк можно будет вызывать внешний перекодировщик-дешифровщик? или свою таблицу как-нибудь впилить?
    КОИ-7Н2 не поддерживается :(

     
     
  • 4.29, GreyCat (ok), 00:09, 11/02/2017 [^] [^^] [^^^] [ответить]  
  • +/
    > где-то видел список поддерживаемых кодировок для строк, теперь найти не могу.

    Нет общего списка, есть далекое желание его создать и медленно рихтуемая табличка https://docs.google.com/spreadsheets/d/1l87kGi9_U4Xrgaw2CGaTc9-_f5UEf1nf-68Dk_

    Сейчас строчка передается в поддержку кодировок целевого языка как есть - строчкой.

    > для строк можно будет вызывать внешний перекодировщик-дешифровщик? или свою таблицу как-нибудь
    > впилить?

    Если целевой язык поддерживает - то все будет работать. Если нет - то, соответственно, нет. Большинство языков опираются на iconv → нужна поддержка в glibc.

    С другой стороны - кто вам мешает забрать строчку в ASCII или просто как массив байт и что-то с ней потом сделать самостоятельно?

    > КОИ-7Н2 не поддерживается :(

    Честно говоря, сомневаюсь, что оно хоть где-то когда-то будет поддерживается. Стандартизующей организации нет, формальных документов нет, отвечать некому.

     
     
  • 5.30, Michael Shigorin (ok), 00:14, 11/02/2017 [^] [^^] [^^^] [ответить]  
  • +/
    >> где-то видел список поддерживаемых кодировок для строк, теперь найти не могу.
    > Нет общего списка, есть далекое желание его создать и медленно рихтуемая табличка

    Ещё есть {lib,}{recode,enca,rcd}...

     
     
  • 6.31, GreyCat (ok), 00:17, 11/02/2017 [^] [^^] [^^^] [ответить]  
  • +/
    >>> где-то видел список поддерживаемых кодировок для строк, теперь найти не могу.
    >> Нет общего списка, есть далекое желание его создать и медленно рихтуемая табличка
    > Ещё есть {lib,}{recode,enca,rcd}...

    Есть, но (1) к счастью, большинство языков таки используют реализацию из iconv, (2) пока хоть это бы к чему-нибудь более-менее стандартному свести.

    Пока общим знаменателем, кажется, получается система codepages в Windows - она вроде бы меньше всех, правда, там встречается местами какая-то дикая экзотика. Сам по себе современный iconv совершенно гигантский - см. табличку.

     

     Добавить комментарий
    Имя:
    E-Mail:
    Текст:



    Спонсоры:
    Слёрм
    Inferno Solutions
    Hosting by Ihor
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2019 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру