Доступен (http://kaitai.io/news/2017-03-22.html) релиз декларативного языка описания бинарных форматов файлов и протоколов Kaitai Struct 0.7 (http://kaitai.io/). Язык позволяет описывать произвольные бинарные форматы (сетевые пакеты, архивы, контейнерные форматы, файловые системы, форматы изображений, видео и т.д.) в декларативном виде. Полученное описание с помощью компилятора ksc можно:- Транслировать в готовый парсер на любом из 8 поддерживаемых целевых языков программирования (C++, C#, Java, JavaScript, Perl, PHP, Python, Ruby),
- Визуально исследовать с помощью предлагаемой IDE (https://ide.kaitai.io/) любой файл в описанном формате:
- Представить в виде наглядной диаграммыВ новой версии языка доступны:
- Импорт .ksy-файлов друг в друга для создания масштабных многофайловых проектов - см. "meta/import" - в том числе с обращением к атрибутам типов из других файлов. Используемый для этого ранее механизм opaque типов отключен по умолчанию (можно включить опцией "--opaque-types").- Структуры неопределенной длины, терминируемые байтом (ранее такое поддерживалось только для строк) - см. "terminator", "include", "consume".- "pad-right" для более удобной обработки структур с паддингом справа (например, строк, помещенных в область фиксированного размера и дополненных справа нулями или пробелами)- Гибкое управление отношением parent-child: с помощью "parent" можно форсировать родителя для дочернего объекта, отличного от текущего объекта по умолчанию- Вычислимые instances теперь могут использовать "_parent"- Новый атрибут "doc-ref" в типах и атрибутах может использоваться для представления ссылок на внешнюю документацию (удобно, если описание формата соответствует какому-то формальному документу)- Процесс компиляции четко разделен на 3 фазы: парсинг YAML, прекомпиляция (единая для всех целевых языков) и компиляция (в конкретный целевой язык); такое решение позволило унифицировать обработку ошибок и значительно упростить сами компиляторы.- Существенно переработан механизм определения ошибок: теперь все рапортуемые компилятором ошибки должны содержать четкое указание на место проявления ошибки; добавлено более 50 тестов с неверными .ksy-файлами специально для тестирования этого сообщений об ошибках.- Генерируемый код теперь содержит проверки на соответствие версии компилятора и runtime-библиотеки.- Переработана система логирования поведения компилятора ("--verbose"): теперь можно гибко включать логирование по отдельным подсистемам.- Новые возможности языка выражений: полноценная поддержка строк с двойными кавычками (с escape characters), type casting, методы для работы с массивами и различные преобразования типов.
Ввиду большого количества внутренних изменений, существенно изменен API runtime-библиотеки: код, сгенерированный ksc 0.7, будет работать только с runtime соответствующей версии. Благодаря введению механизма импорта, начаты работы по созданию библиотеки часто используемых структур данных и форматов. С версией 0.7 впервые эта библиотека поставляется в комплекте дистрибутива и на момент выпуска составляет 60 описаний.URL: http://kaitai.io/news/2017-03-22.html
Новость: http://www.opennet.ru/opennews/art.shtml?num=46244
Отличный проект, пользуемся, радуемся.
> Отличный проект, пользуемся, радуемся.Спасибо! Для чего, если не секрет?
> Спасибо! Для чего, если не секрет?В основном для описания бинарных форматов.
А оно умеет разбирать очень большие файлы, которые невозможно полностью загрузить в память?А может разобрать файл с битым концом, не зафейлив всю операцию разбора, а зафейлив только битую часть?
> А оно умеет разбирать очень большие файлы, которые невозможно полностью загрузить в память?YMMV. Файловые системы разбираются без загрузки в память всех файлов - потому что там есть индекс и можно сделать lazy-доступ к объектам, когда программа обращается только к тем веткам, которые ей нужны (и, соответственно, грузит в память только их).
С другой стороны, если речь о разборе какого-нибудь дикого лога из одинаковых пакетов без индекса - если задать тупо массив пакетов с "repeat: eos" - то эту операцию нельзя выполнить, не зачитав все пакеты в память. Если нужна такая пакетная обработка - как вариант, можно описать структуру пакета, а командовать зачитыванием очередного пакета из потока уже из приложения.
> А может разобрать файл с битым концом, не зафейлив всю операцию разбора, а зафейлив только битую часть?
Да, в debug mode - может. Этим, собственно, все визуализаторы пользуются.
> С другой стороны, если речь о разборе какого-нибудь дикого лога из одинаковых
> пакетов без индекса - если задать тупо массив пакетов с "repeat:
> eos" - то эту операцию нельзя выполнить, не зачитав все пакеты
> в память. Если нужна такая пакетная обработка - как вариант, можно
> описать структуру пакета, а командовать зачитыванием очередного пакета из потока уже
> из приложения.Спасибо за разъяснения, как раз интересовал парсинг потока с "repeat: eos". Ну, нельзя так нельзя. Не сильно страшно.
Всё равно проект очень полезный, спасибо, что разрабатываете его.
> Спасибо за разъяснения, как раз интересовал парсинг потока с "repeat: eos". Ну,
> нельзя так нельзя. Не сильно страшно.Не так давно завели https://github.com/kaitai-io/kaitai_struct/issues/133 - это примерно про это. В некоторых случаях, понятно, что поток разбирать в lazy-режиме можно, например, если известно, что пакеты все одинаковой длины и можно тогда вычислить, куда сделать seek из индекса массива. Но, опять же, далеко не везде все пакеты одинаковой длины.
> Всё равно проект очень полезный, спасибо, что разрабатываете его.
Вам спасибо ;)
Ух ты, какая прелесть! Не знал о таком. Пригодится, вот прямо сейчас даже. Спасибо разработчикам.
Есть похожий Synalyze It (macOS) и hexinator (Wine/Windows)
Мы разбираем ими InnoDB .ibd файлы
Не, мне немного для другого. У меня типа протобуфов, только не протобуфы, и хочется это дело слать прямо веб-клиентам по вебсокетам.
https://hexinator.com/hexinator-linux/
А слабо парсить C-ные хедеры и строить формат данных из них?
Как правило при разборе дампов памяти или файловой системы, структура данных известна, но находится с *.h соответствующего проекта.
имхо, парсинг *.h - это первое, чему надо учить подобную программу.
Кому как, мне лично видится функцией номер 1 генерация бинарников.
Парсинг это конечно здорово, но часто при написании парсеров бинарных протоколов нужен и обратный процесс.
> Кому как, мне лично видится функцией номер 1 генерация бинарников.
> Парсинг это конечно здорово, но часто при написании парсеров бинарных протоколов нужен
> и обратный процесс.Только вчера закоммитил кое-что: https://github.com/kaitai-io/kaitai_struct/issues/27#issueco...
Супер. Крайне важная фича, без которой например в моих проектах просто никак.
> А слабо парсить C-ные хедеры и строить формат данных из них?Набросал за 15 минут на двух-с-половиной регэкспах: https://gist.github.com/GreyCat/9dba530b0d2cb8ccec4e1d6e90a0...
Выдает полуфабрикат ksy, который можно доработать руками, попереименовать поля, дорасставить типы и т.д.
> Как правило при разборе дампов памяти или файловой системы, структура данных известна,
> но находится с *.h соответствующего проекта.
> имхо, парсинг *.h - это первое, чему надо учить подобную программу.Конвертер .h -> .ksy вполне может быть отдельной программой, компилятор .ksy -> целевой язык тут вроде как не при чем. Да и, если честно, все по-разному. Даже если .h есть, то зачастую комментарии и документация по поводу полей лежит отдельно и все равно надо все это допиливать до ума.
Есть поддержка бинарных шаблонов от 010 Editor?
> Есть поддержка бинарных шаблонов от 010 Editor?Нет, и вряд ли будет. 010 - почти чисто императивный язык, с циклами for, while и т.д. У нас - декларативный язык.
А где находится компонент, который позволяет "представить в виде наглядной диаграммы"?
В компиляторе. "ksc -t graphviz foo.ksy" и на выходе будет .dot-файл с диаграммой. Соответственно, чтобы получить картинку - что-то типа "dot -Tsvg foo.dot >foo.svg".
Спасибо
И еще вопрос - есть формат, где одним элементом является строка A (strz) и два числа B и C (u4), которые повторяются пока не встретится нулевой байт (u1 = 0x1), т.е. что-то вроде: ABCABCABC0...тут другие данные....
Вы не подскажете как такое можно выразить в терминах kaitai? Я пробовал циклы, но они вроде подразумевают, что структура считывается полностью.
> И еще вопрос - есть формат, где одним элементом является строка A
> (strz) и два числа B и C (u4), которые повторяются пока
> не встретится нулевой байт (u1 = 0x1), т.е. что-то вроде: ABCABCABC0...тут
> другие данные....
> Вы не подскажете как такое можно выразить в терминах kaitai?Стандартный подход - что-то типа:
seq:
- id: structures
type: entries
terminator: 0x1
# такое объявление создает подпоток,
# до байта-терминатор = 0x1, в котором
# будет зачитываться тип entries
types:
entries:
seq:
- id: entries
type: entry
repeat: eos
# зачитывается до конца потока,
# т.е. до байта-терминатора
entry:
seq:
- id: a
type: strz
- id: b
type: u4
- id: c
type: u4Разумеется, это означает, что если встречается "нулевой байт" (который на самом деле единичный) где-то внутри a-b-c - то все будет закончено на нем.
> Я пробовал циклы, но они вроде подразумевают, что структура считывается полностью.
Эм, а еще предполагается, что может быть не всегда ABCABC0, а может быть, например ABCA0?
"Эм, а еще предполагается, что может быть не всегда ABCABC0, а может быть, например ABCA0?"
Вот именно что ABCA0 быть не может, может быть только
* ABC0
* ABCABC0
* ABCABCABC0
и т.д.
> "Эм, а еще предполагается, что может быть не всегда ABCABC0, а может
> быть, например ABCA0?"
> Вот именно что ABCA0 быть не может, может быть только
> * ABC0
> * ABCABC0
> * ABCABCABC0
> и т.д.Тогда вышеописанный подход с подпотоком в целом решает вопрос.