LINUX.ORG.RU

Парсер бинарных структур


0

1

А нет ли такого парсера, чтобы ему задать структуру хидера (8 байт сигнатура, два байта число X, 4 байта смещение таблицы Y), вот отсюда взять смещение и там массив других структур, длина каждой в первом байте... Ну типа такого. И чтобы он файл распарсил и показал всё это.

★★★★★

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

Ну это ж генератор кода. А мне надо для просмотра структур. Т.е. генерация HTML/PDF, или просто на экран.

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

вот отсюда взять смещение

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

см. bitstring — в erlang и ocaml — самое мощное из того, что я знаю.

http://www.erlang.org/doc/programming_examples/bit_syntax.html

http://code.google.com/p/bitstring/

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

Похоже! Причём интерактивненько, а не статическое текстовое определение. Но

The ocaml-bitstring project adds Erlang-style

... мда. Почему парсинг низкоуровневых структур сделан на высокоуровневых языках? Загадка.

Насчёт произвольных, это понятно, совершенство не обязательно. Хотя бы приблизительно на куски разбить, в которых проще ориентироваться.

Проблемы две:
1. Распаршенное хотелось бы вывести сразу или кусками на экран, а не printf-ами полей. Но, думаю, ocaml что-нибудь для этого предоставляет.
2. Совершенно не знаю ни окамла, ни эрланга.

Впрочем, второе это уже моя проблема.

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

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

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

Почему парсинг низкоуровневых структур сделан на высокоуровневых языках? Загадка.

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

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

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

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

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

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

лучше, по-моему, взять что-нибудь менее интеллектуальное, но более исполняемое — например, просто библиотечку для любого языка, позволяющую удобно читать битики («прочти мне 32 бита и проинтерпретируй их как signed int»), а остальное писать уже просто на целевом языке.

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

Нет, я не совсем знаю, что хочу. Просто по проекту сейчас парсинг замороченных бинфайлов, вот и мысли разные в голову лезут. Есть ведь онлайн парсеры regex, base64, json, xml-ные валидаторы разные, наконец, всякие jsfiddle и ideone. Есть какая-то утилита со своим языком для описания формата текстовых файлов и автоматического парсинга (т.е. любого, хоть .ini хоть .csv), прикольная, но не помню точно её.

А для бинарных данных - глухо. Я хотел сначала найти онлайн парсеры бинарных файлов, но максимум, что есть - это простые хекс вьюверы. Потом подумал найти оффлайн вьюверы, вот и спросил. Но, видно, ничего такого нет. Прямо-таки отличная идея для стартапа! Фичи: загрузка и парсинг по базе готовых форматов (заполняется пользователями), обработка и вывод на основе текстового определения (т.е. bistring), ну а графический редактор с рычажками это баловство. Хватит и текстового редактора типа jsfiddle, добавил поле и сервер автоматом переформатировал. Это ж для программистов, кому ещё нужны бинарные форматы.

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

Насчёт рисовалки, рисовать было бы хорошо в хекс дампе разными цветами области, с тултипами «это хидер, это сегмент X»... с переключением hex/parsed.

Эх, жаль, такой интересный проект был бы.

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

Э, нет, писать парсер языка определения структуры нафиг надо. Меня ж не на C прочитать структуру интересует, а именно динамически определять, юзером. В том же http://code.google.com/p/bitstring/ уже есть определение подходящего формата, даже по сигнатуре если делать - то уже неплохо. Пробежаться по всем «битстрингам» и проверить их, и не надо никакие битики читать. Я ж так понимаю, в ocaml-е обязан быть какой-нибудь eval, которому можно подсунуть строку, введённую пользователем.

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

ну а графический редактор с рычажками это баловство

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

см. там всякое типа http://corte.si/posts/visualisation/binvis/index.html про то, почему я именно видеть хочу, причем сразу же последствия применения моих гипотез.

а идея у тебя отличная, я бы уже давно это сделал, если бы понимал, как. :-)

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

bitstring и для питона есть

я тоже сначала купился на созвучное название.

bitstring-то (т.е. бит-вектор) есть, а bitmatch-то (т.е. встроенный язык для описания грамматик на bitstrings) нет.

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

Я ж так понимаю, в ocaml-е обязан быть какой-нибудь eval, которому можно подсунуть строку, введённую пользователем.

что-то тебя не в ту степь унесло.

во-первых, окамль — комилируемый язык, в стиле модулы (если не застал, то d или go).

во-вторых, bitstring там — просто синтаксический сахар (а именно, навороченные макросы, подставляющиеся при компиляции) для последовательности (грубо говоря) read() и check().

так что, так или иначе, а ты предлагаешь своим пользователям писать парсеры руками. я за то и агитирую, в общем-то ;-)

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

anonymous
()

Emacs Lisp:

(require 'bindat)

(defvar my-structure-bindat-spec 
  '((:string-len u8) 
    (:string str (:string-len))))

(bindat-unpack '((:singature u8) 
		 (:x u16)
		 (:offset vec 4 u8)
		 (align 2)
		 (:structs repeat 2 (struct my-structure-bindat-spec)))
	       "\x01\x01\x02\x04\x05\x06\x07\x00\x03\x4c\x4f\x52\x05\x52\x55\x4c\x45\x5a")

=> ((:structs ((:string . "LOR") (:string-len . 3)) ((:string . "RULEZ") (:string-len . 5))) (:offset . [4 5 6 7]) (:x . 258) (:singature . 1))

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

Посмотри в сторону libmagic, на которой работает file,
там есть привязка для python-а.

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

C:

#include <stdio.h>
 
int u8(char **p){int r=**p;(*p)++;return r;}
int u16(char **p){int r=**p;r|=*p[1]<<8;*p+=2;return r;}
char *align(char *p, int n){return ((unsigned)p+(n-1))&~(n-1);}
char *skip(char *p, int n){return p+n;}
 
char *mesg(char *p){
        int len = u8(&p);
        printf("[%i]%.*s", len, len, p);
        return p+len;
}
 
char *struc(char *p){
        int sig = u8(&p);
        int x = u16(&p);
        p = skip(p, 4);
        p = align(p, 2);
        p = mesg(p); p = mesg(p);
        return p;
}
 
int main(){
        char data[] __attribute__((aligned(2))) = "\x01\x01\x02\x04\x05\x06\x07\x00\x03\x4c\x4f\x52\x05\x52\x55\x4c\x45\x5a";
        struc(data);
        return 0;
}
anonymous
()
Ответ на: комментарий от anonymous

Ну раз уж мне ответили, а не топикстартеру...

А динамически переопределять или конструировать в процессе выполнения программы спецификации структур без перекомпиляции? А быстро переделать отображение структуры? А в Emacs Lisp можно не только по этой же спецификации распаковать, но и запаковать в бинарное представление из значений, переданных пользователем. :)

Так что это все-таки две разные программы. У них разные возможности, свои достоинства и недостатки. Единственное достоинство программы на Си - очень высокая скорость.

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

+100500

А еще всякие математические пакеты так умеют. Тот же Octave.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от queen3

Ага, подходит. Похоже, структуры определять умеет только функциональщина.

А в каком смысле определять? Разве в Си нет структур? Или что имеется в виду? :)

Если будут вопросы по bindat, то кастуй. Я успел дописать этот модуль для парсинга знаковых целых i8, i16..., а также для float32 (только преобразует представление IEEE 754 к double, так как Emacs только в double работает) и float64 (double). Обрати внимание на ограничения Emacs (32-битных) на разрядность целых чисел - для u32 есть ремарка в документации. Лучше всего, чтобы не потерять первые три бита, распарсивать u32 как «vec 2 u16», а потом через float выводить (+ (* 65536.0 (aref 0...)) (aref 1 ...). Жопа там с bignums. Заранее предупреждаю.

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

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

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от anonymous

В зависимости от языка. Возможно protobuf подойдет.

ну у protobuf надо чтобы сама структура была сформирована им же, т.е. protobuf-ом

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

Не ленюсь я на работе, а это всё-таки на интерес. Просто изучаю возможности.

queen3 ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

Парсер-то не структур надо, а парсер языка определения структур. А потом ещё и интерпретатор.

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

самое интересное, когда у тебя в файле могут быть различные структуры, у которых только общий заголовок, вида [RECV,SEND]_SIZE_OPCODE_тут_пошла_структура

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

Парсер-то не структур надо, а парсер языка определения структур. А потом ещё и интерпретатор.

Классический конечный автомат и простенький язык для его описания. Любой формат файлов/структур/пакетов - можно представить как последовательность символов на ленте так или иначе меняющий состояние читающего автомата (парсера).

Простых языков КА мягко говоря много..какой удобнее и красивее надо наверное спрашивать студентов :)

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