В рамках священной борьбы с разнообразием взор непременно обращается к форматам файлов. На моем винте около 5000 разных расширений файлов, 800 из которых встречаются 10 и чаще раз. Часть из них созданы неизвестно кем, часть непонятно для чего, еще часть неведомо как читать
(
Read more... )
Такое ощущение, что разработчики ни разу не видели реального формата данных (не искуственного, который сделан для длгосрочного промежуточного хранения и interoperability, а реального, повседневно используемого).
И вообще, декларативный подход к описанию форматов - работает только на совсем-совсем синтетике.
Пока, единственный практичный способ описания форматов - это шаблоны 010. (Если интересно, могу привести несколько примеров из реальной жизни). Да, оно ужасно - но работает.
Аналогично, в реальной жизни не работает FLIRT, уже лет шесть как. Да, можно что-то определить с его помощью, если в .exe вкомпилена статическая библиотека без модификаций. На практике, такое происходит очень редко. Даже простое включение link-time code generation делает половину библиотечных функций нераспознаваемыми. Так что, если хочется результатов - приходится писать .idc, который матчит не коды команд, а куски CFG и call graph
Reply
Reply
Я в качестве примера самого сложного формата для своих велосипедов использовал PE. Вроде бы DFDL его парсит, если я ничего не пропустил. Знаете формат сложнее или что не распарсит DFDL?
Почему именно 6 лет?
Не согласен с вашим мнением о декларативном подходе. Мой велосипед создавался из си-кода преобразованием в несколько облегченный AST (что делаем в этой точке парсинга, в каком виде данные, куда их кладем), вполне декларативное описание парсера файла, более удобное, чем собственно си-код, возможностью остановок по требованию и проверок, возможностью подключения вместо компиляции.
Reply
Reply
Игровые ресурсы это еще одна причина, для которой я строил велосипед. Скажем, в парсере из этого поста я старался писать в стиле, который было бы просто переделывать в описание
animinfos = boost::iterator_range
((psa_animinfo *) ptr, (psa_animinfo *) ptr + header.data_count);
psa_animinfo& animinfo = ((psa_animinfo *) ptr)[i];
ptr += header.data_count * header.data_size;и все такое ( ... )
Reply
Вообще, это старый шаблон. Он писался тогда, когда в описания структур еще нельзя было передавать параметры (в данном случае - childCount). Поэтому, вместо указателя, пришлось городить все по месту.
В целом, что .bt, что сам 010 - тот еще не подарок. К сожалению, штука единственная в своем роде.
Reply
Reply
Reply
Reply
Т.е., во-первых, большинство мелких функций либо инлайнится, либо генерируется линкером по первому вхождению. Т.е., даже стандартные библиотеки, в этом случае, оказываются размазанными по всему сегменту .code.
Во-вторых, мелкие функции реюзаются. Например функция вида { return NULL; } объявляется в одном месте и используется, типично, из нескольких тысяч мест.
В-третьих, для релиза все библиотеки для которых есть исходники, обычно компилируют из исходников. Найти в этом паттерн, совпадающий с тем, что был в библиотеке, скомпилированной отдельно - это, скорее, счастливый случай.
С учетом этого, на каждую найденную FLIRT функцию, приходится 10-20 false positive.
С учетом того, что я люблю, чтобы у меня в базах был порядок - проще не пользоваться FLIRT совсем, благо код основных функций стандартной библиотеки, я, более-менее, помню.
Reply
Leave a comment