LINUX.ORG.RU

Kaitai Struct 0.6

 , , ,


5

3

Вышла новая версия Kaitai Struct — языка спецификации произвольных бинарных форматов файлов, пакетов, протоколов и т. д.

Основная идея проекта в том, что формат бинарного файла описывается один раз на языке .ksy, после чего файлы такого формата можно рассматривать в визуализаторах, получая представление о том, каким байтам соответствуют какие значения элементов формата, сгенерировать человекочитаемую диаграмму формата, а самое главное — сгенерировать готовую библиотеку парсинга такого формата на одном из 8 поддерживаемых целевых языков: C++, C#, Java, JavaScript, Perl, PHP, Python, Ruby.

В новой версии стоит отметить следующие улучшения:

  • поддержка побитового чтения (в том числе для парсинга битовых полей, битовых потоков и т.д.) - type: bXX теперь позволит прочитать XX бит как число, type: b1 прочитает один бит и представит его как boolean
  • масса возможностей добавить метаинформацию о формате в .ksy: ключ doc на уровне типов, а также ключи title, license, ks-version в meta
  • поддержка нестандартных ключей а ля CSS, с минусом в начале; активно используется в Web IDE для задания опций отображения (-webide-representation) и т. д.
  • массивные изменения движка вывода типов: enum теперь тоже ресолвится по единым правилам, даже в языках, где таковой поддержки нет нативно (Python, PHP, Perl, JavaScript и т. д.)
  • идентификатор id для атрибутов последовательности теперь опционален; если его не задать, будет автоматически присвоен уникальный числовой идентификатор, что удобно для быстрого разбора неизвестных полей в форматах
  • поддержка подключения внешних типов (если задать type: foo и foo не определен в текущем файле, будет сгенерирован корректный import / include в предположении, что тип объявлен во внешнем файле)
  • возможность писать целочисленные литералы с разделителями (123_456_789 или 0b0101_1111), а также преобразовывать числа в строки с помощью метода to_s
  • исправление ошибок, оптимизация генерируемого кода

Релиз приурочен к проходящей в эти выходные конференции FOSDEM 2017. 5 февраля будет представлен доклад о парсинге бинарных media-форматов с помощью Kaitai Struct в рамках Open Media devroom. Для интересующихся, но не имеющих возможности посетить доклад лично, организована онлайн-трансляция видео.

>>> Подробности

★★

Проверено: jollheef ()
Последнее исправление: sudopacman (всего исправлений: 4)

Ответ на: комментарий от Linfan

SWord

Забавно, кстати, я про этот проект не знал, спасибо! Чем-то по идеологии очень похоже на OLEToy - вы с ними не сотрудничали?

GreyCat ★★
() автор топика
Ответ на: комментарий от GreyCat

Вот это уже сложно, хотя бы потому, что далеко не во всех языках их можно оставить такими.

Ну это дело такое. В нашем случае это всего лишь имена, по которым резолвятся объекты модели в окне вьювера дерева модели.

Linfan ★★★★★
()
Ответ на: комментарий от GreyCat

OLEToy вырос из нашего CDR Explorer (https://sk1project.net/modules.php?name=Products&product=cdrexplorer), который был классическим дампером. SWord - это следующая генерация, позволяющая разрабатывать in-place код.

Linfan ★★★★★
()
Последнее исправление: Linfan (всего исправлений: 1)
Ответ на: комментарий от Linfan

Как я уже указывал выше, для отладки мы используем отдельное приложение

Насколько я понимаю, у вас чуть проще задача: по сути вся логика у вас строго только на Python, а где не хватает скорости - вы добавляете нативные модули на C, но опять же в основном используемые из Python?

GreyCat ★★
() автор топика
Ответ на: комментарий от GreyCat

Да. И более того, SWord создан для разработки только UniConvertor, поскольку он визуализирует модели форматов UniConvertor'а.

Linfan ★★★★★
()
Ответ на: комментарий от vtq34957

дытэктор мышкоюзера зашкалил

Не каждому суждено делать визуальный анализ в консоли :)

Linfan ★★★★★
()
Ответ на: комментарий от Linfan

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

Или попробовать в SWord добавить поддержку большего числа поддерживаемых форматов (например, бинарники просматривать?) через внешние .ksy?

Или что-то еще? Например, я могу поковырять какие-нибудь еще недоделанные форматы, чтобы их потом добавить в sK1 / UniConvertor?

GreyCat ★★
() автор топика
Ответ на: комментарий от GreyCat

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

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

Linfan ★★★★★
()

Интересная вещь, с одной стороны, казалось бы полная ерунда, такие вещи пишет каждый второй студент, с другой, с детства мечтал о таком процессе: скармливаешь компьютеру команды процессора (с размерами, таймингами), остальное железо, формат файла (скажем JPEG или видеокодек), второй формат файла (PNG или банально буфер на экране), а он уже сам рассчитывает оптимальный по памяти/скорости/кэшам алгоритм, и вот так за пол часа делается что угодно, от видеоплеера и браузера, до 3D RPG.

anonymous
()
Ответ на: комментарий от Linfan

Ага - хотя я сейчас им уже несколько другие люди занимаются, а почти за последние n лет ничего толком туда не контрибьючу. Ну и, собственно, я наши похождения во время и после LTDL 2009 прекрасно помню :)

GreyCat ★★
() автор топика

Расскажите немного о вот таком workflow, возможно ли анализировать формат сверху вниз, то есть например у меня есть сетевой пакет, я не знаю тип и размер полей, но знаю что следующий известный блок начинается с magic number. То есть, динамический размер чанка.

anonymous
()
Ответ на: комментарий от anonymous

возможно ли анализировать формат сверху вниз

Обычно так и происходит. Собственно, все и заточено ровно под то, что сначала об очередном блоке ничего не известно, кроме, например, размера, а затем он обрастает типом, какими-то полями и т.д.

но знаю что следующий известный блок начинается с magic number

Вот конкретно так сложно на самом деле - KS не умеет обычно делать то, что делают «обычные» парсеры на основе всяких LR/LL/SLR и т.п. грамматик - т.е. «искать» какие-то образцы, бэктрекаться и т.д. Обычно бинарные форматы все равно устроены не так - они почти никогда не оперируют такими высокими материями - там все равно внутри размеры, смещения и т.д.

Зачастую, когда формат неизвестен, можно визуально найти в дампе то, что нужно и начинать с очень простой структуры типа

- size: 165
- size: 180
- size: 2073

а затем каждое из этих полей может начинать обрастать подтипом, какими-то процессингами и т.д.

GreyCat ★★
() автор топика
Ответ на: комментарий от Linfan

Типа того :) Есть какие-то мысли, с чего бы такого можно было начать?

GreyCat ★★
() автор топика

А бывают языки спецификации, на котором можно описать синтаксис C, C++, D, Java, PHP, Perl...

И потом на основании этого написать компилятор, который только на основании спецификации программу на этом языке скомпилирует.

Есть ли языки синтаксис, которых уже описан на таком языке спецификации?

unDEFER ★★★★★
()
Ответ на: комментарий от unDEFER

Haxe внезапно человечество уже придумало.

anonymous
()
Ответ на: комментарий от unDEFER

Можно, но зачем?

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

Например в случае трёх целевых языков Си, Си++ и Java какую схему управления памятью будет подразумевать наш метаязык? Можно ручную, можно подсчёт ссылок, можно mark and sweep сборщик. В результате получим Си код который не работает без Boehm GC или Java с финализаторами по всему коду. Более того очевидно всё это ещё и будет работать по-разному и узкие места могут возникать в совершенно различных местах.

anonymous
()
Ответ на: комментарий от gejzenbug

Тут речь всё же не о создании компилятора, а о том чтобы на основании программы описанной некоторым языком порождать эквивалентную по функциональнсти программу на целевом языке. Это то что делает Haxe.

anonymous
()
Ответ на: комментарий от anonymous

Ну вот хотелось бы, такой «метакомпилятор», чтобы он знал, что бывает и malloc/free как на C и GC на D или Java, и чтобы всё умел..

А потом все эти спецификации языков можно будет как угодно скрещивать :-)

unDEFER ★★★★★
()
Последнее исправление: unDEFER (всего исправлений: 1)
Ответ на: комментарий от anonymous

Да, авторы его собственно и декларируют как DSL. Проект интересный, однако на мой взгляд использование YAML в качестве основы не самый удачный вариант, хотя, когда по работе мне потребовалось сделать нечто подобное сам его использовал, но для pet project'a я бы всё-таки построил грамматику и парсер под задачу вручную, уж больно тяжеловесен спек YAML. На самом деле исопльзуя scala можно было построить такую грамматику, которая являлась бы строгим подмножеством грамматики scala, тогда и парсер писать не надо.

Однако, по большому счёту, проект может спокойно набрать пользовательскую базу, а после этого в зависимости от наличия внятных сценариев использования того факта что валидный ksy это валидный yml, спокойно трансформировать язык как угодно, просто сделав генератор из старого формата в новый, что для декларативных языков не является особой проблемой.

anonymous
()

поддержка побитового чтения

Вот теперь нужно

anonymous
()
Ответ на: комментарий от anonymous

Вообще б да, им бы какой-нибудь синтаксис типа Spicy иметь - цены б не было.

anonymous
()

Можно ли чтение юзертипов описывать в том же ksy чтобы не зависеть от

будет сгенерирован корректный import / include в предположении, что тип объявлен во внешнем файле)

?

Например, ue(v) и se(v) при реализации https://i.stack.imgur.com/2vi21.png обозначают https://en.wikipedia.org/wiki/Exponential-Golomb_coding и тут выбор между читаемостью и внешними зависимостями

anonymous
()
Ответ на: комментарий от GreyCat

Вот меня и интересует предлагаемый рабочий процесс, если к примеру у меня есть три пакета header-unknownpart-knownpart-checksum, в которых unknownpart имеет разный размер. Предположим, что я пока не обнаружил признак, по которому можно однозначно их различить (а может, я и не хочу их различать, а тупо пересылать дальше, меняя только known+checksum). Предлагается заводить по одному ksy файлу на каждый пакет?

anonymous
()
Ответ на: комментарий от anonymous

Приводи новый

ИМХО, когда рассказывают о новом софте, объяснить на пальцах что это, где может пригодится и как использовать - бесценно ;)

router ★★★★★
()
Ответ на: комментарий от anonymous

которая являлась бы строгим подмножеством грамматики scala, тогда и парсер писать не надо.

Написание парсера в современном мире - задача на полчаса-час. Тем более, что в ksc уже и так парсер языка выражений есть. А использовать парсер Scala - это тут, мягко говоря, из пушки по воробьям. Scala и так не славится тем, чтобы это был особенно приятный (и быстрый) для парсинга язык.

спокойно трансформировать язык как угодно, просто сделав генератор из старого формата в новый

Типа того. Предлагайте варианты.

GreyCat ★★
() автор топика
Ответ на: комментарий от anonymous

Предлагается заводить по одному ksy файлу на каждый пакет?

Можно завести по типу на каждый пакет в одном и том же файле. Какие варианты-то? Вам надо по любому их как-то отличать и указывать для каждого вручную посчитанную длину или что-то такое. Сделайте что-то типа:

types:
  pkt1:
    seq:
      - id: header
        type: header
      - id: unknownpart
        size: 100500
      - id: knownpart
        type: knownpart
      - id: checksum
        type: u4
  pkt2:
    seq:
      - id: header
        type: header
      - id: unknownpart
        size: 1337
      - id: knownpart
        type: knownpart
      - id: checksum
        type: u4
# и т.д.

Дублирования на самом деле минимум, т.к. как раз сложные вещи - типы header и knownpart - описываются один раз.

GreyCat ★★
() автор топика
Ответ на: комментарий от router

Да вроде бы статья Накамуры не то, чтобы сильно устарела. Он же там в первой статье какие-то совсем банально-примитивные вещи показывает. Ну, «unknown» нынче можно вручную не писать, а так вроде бы все актуально. И консольным визуализатором можно новичков не пугать, а показывать сразу Web IDE.

GreyCat ★★
() автор топика
Ответ на: комментарий от anonymous

Мсье, «вырос» не эквивалент «сделан из». OLEToy слеплен по образу и подобию CDR Explorer, с повторением архитектурных ошибок (ну или паттернов, кому как нравится). Собсно в докладе на LGM2012 Strba об этом и говорил. И ничего зазорного в этом нет - это опенсурс, мсье. Для того код и открыт, чтобы им пользовались.

Linfan ★★★★★
()
Ответ на: комментарий от hobbit

Парсер CFB (он же OLE, который в основе всех этих форматов) у нас в целом есть. Описывать MS Office на самом деле не то, чтобы дико сложно, но весьма муторно - когда только официальная спецификация на 800-с-чем-то-там страниц.

GreyCat ★★
() автор топика
Ответ на: комментарий от GreyCat

Ога. А потом огребают проблемы с endianness, byte alignment, #pragma pack, сегфолты и непонятно откуда-то взявшиеся тормоза при обращении к структуре.

Руки надо просто выпрямлять. Или выбрать язык попроще. Благо, в наше время есть из чего.

segfault ★★★★★
()
Ответ на: комментарий от vtq34957

все врерно,на 1 курсе института так и делают,а что дальше?
они начинают писать на джаваскрипте?

Ну кто на жс, кто на джаве, кто на плюсах... А тем некоторым, кто проникся, уже ничего не страшно.

segfault ★★★★★
()

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

А трансляция записывалась?

theNamelessOne ★★★★★
()
Ответ на: комментарий от MATPOCKUH

А писалку бинарного формата потом сложно запилить?

Зависит от формата. Простую писалку я, надеюсь, мы таки скоро сделаем by popular demand. Более сложно сделать писалку, которая, скажем, по такому описанию:

seq:
  - id: len
    type: u4
  - id: str
    type: str
    size: len + 2
    # ...

умеет понимать, что поле len - зависимое от поля str, и когда в поле str будут класть, скажем, строчку «abcde», в поле len надо автоматом выставить длину строки минус 2, т.е. 3.

GreyCat ★★
() автор топика
Последнее исправление: GreyCat (всего исправлений: 1)
Ответ на: комментарий от GreyCat

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

MATPOCKUH
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.