SlideShare a Scribd company logo
Практический	язык	для	
извлечения	данных	из	
исходных	кодов	и	подготовки	
их	к	анализу
Signed-off-by:	Denis	Efremov efremov@linux.com
ISP	RAS/NRU	HSE	
Yandex Perl	Meetup
June	06,	2018
GPG	Fingerprint:
7654	0336	0294	0DF1	920F
E403	B522	95B0	3350	301F
О	Докладчике
Разработчик	ИСП	РАН (ispras.ru).	Отдел	технологий	
программирования.
Аспирант	НИУ	ВШЭ (hse.ru).
Верификация	программного	обеспечения,	разработка	формальных	
спецификаций,	инструментов	статического	и	динамического	
анализа для	ядра	Linux.
GitHub:	https://github.com/evdenis
KeyBase:	https://keybase.io/efremov
О	чем	речь?
• Стандарты
• Orange	Book:	division	A	(verified	protection)	(A1,	Beyond	A1)
• Common	Criteria	(EAL7)
• DO-178C/DO-333	"Formal	Methods	Supplement	to	DO-178C	and	DO-278A”IEC	
61508	(SIL4)
• ГОСТ	Р	ИСО/МЭК	15408-3-2013	"Методы	и	средства	обеспечения	безопасности.	
Критерии	оценки	безопасности	информационных	технологий"
• Сертификация	ПО	на	соответствие	стандартам
• Исходные	коды
• Формальная,	полу-формальная,	неформальная	документация
• Тесты,	спецификации
• Описание	цикла	разработки
• Программы,	которые	помогают	готовить	сертификационный	пакет
Что	важно	для	чтения	кода
программистом?
• Форматирование
• Документация
• «Понятность»
• Инструменты	навигации
Что	важно	для	анализа	кода	
программистом?
• Форматирование
• Документация
• «Понятность»
• Инструменты	навигации
• Подготовка	кода	для	запуска	тяжеловесных	статических	
инструментов (Frama-C,	VCC,	Isabelle,	CPAChecker,	…)
• Возможность	менять	подготовленный	код	с	возвратом	«назад»
• Карты	кода
Как	работают	инструменты	с	Си
• Запуск	препроцессора
• Убираются	комментарии
• Раскрываются	макросы
• Запуск	компилятора	до	стадии	построения	Control
Flow Graph (CFG)
• Полная	потеря	форматирования
• Исходные	код	на	CFG	уровне	слишком	сильно	
отличается	от	оригинального
Существующие	инструменты: facebook/pfff
• Инструменты	для	анализа	кода,	его	визуализации	
и	трансформаций,	сохраняющих	исходный	стиль	
https://github.com/facebook/pfff (OCaml)
• Парсер:	препроцессор +	Си +	форматирование
• Ошибки парсинга (нужен предварительный сбор
макросов)
• Неполная поддержка языка Си с расширениями
Насколько	критична точность при	
подобном анализе?
• Что	будет	если	пропустить	конструкцию,	которую	не	
удается	распознать?
• Что	будет	если	CFG	не	точно	построить	(например,	будут	
лишние	зависимости)?
• Что	будет	если	сложность	кода	и	его	зависимости	не	
совсем	точно	посчитаются?
• Возможно	ли	запустить	инструменты	на	«неполном»	
наборе	кода?
Why	Not?	(Linux	Kernel	tools/checkpatch.pl)	(1)
our @typeList = (
qr{void},
qr{(?:(?:un)?signeds+)?char},
qr{(?:(?:un)?signeds+)?shorts+int},
qr{(?:(?:un)?signeds+)?short},
qr{(?:(?:un)?signeds+)?int}
);
our $C90_int_types = qr{(?x:
longs+longs+ints+(?:un)?signed|
longs+longs+(?:un)?signeds+int|
longs+longs+(?:un)?signed
)};
Why	Not?	(Linux	Cross	Reference)	(2)
my $_identifier_re = qr(
(?m:^|(?<=[^a-zA-Z0-9_#])) # Non-symbol chars.
(_*[a-zA-Z][a-zA-Z0-9_]*) # The symbol.
b)x;
my $_reserved = { map { $_ => 1 } qw(asm auto break case char const
continue default do double else enum ...)};
sub parsespec {
return ['atom', '.', undef,
'comment', '/*', '*/', 'comment', '//', "$",
'string', '"(?:[^"]*.)*[^"]*"', undef,
'string', "'(?:[^']*.)*[^']*'", undef];
}
Общая	схема	работы	инструмента
Подготовка
• Объединение	исходных	кодов	в	единый	файл
• Раскрытие	директив	условной	компиляции; включение	заголовочных	файлов
• Предобработка	исходного	кода	(макросы,	строки,	комментарии)
Построение	
графа
• Независимые	поиск	элементов	по	типам
• Выделение	меток	и	идентификаторов
• Построение	графа	зависимостей
Анализ
• Сбор	метрик	по	исходному	коду
• Разрешение	циклов
• Вывод	подграфа,	карты	исходных	кодов…
Алгоритм	построения	графа	зависимостей	(1)
• Загрузка	исходного	кода
• Объединяются	все	*.c файлы
• Include директивы	выносятся	на	верхний	уровень	с	
сохранением	порядка
• Запускается препроцессор GCC
• Без раскрытия макросов (флаг –fdirectives-only)
• С учётом только директив условной компиляции и include
• С сохранением комментариев (флаг –С)
Алгоритм	построения	графа	зависимостей	(2)
• Все	комментарии	и	строки	в	коде	заменяется	на	специальные	уникальные	
идентификаторы
• Первым	делом	из	кода	выбираются	определения	макросов.	После	они	также	
заменяются	на	специальные	идентификаторы,	которые	при	дальнейшем	
разборе	рассматриваются	как	пробелы
#define macro_test() ({0;})
some_typedef_t *test(void) {
/* TODO: int main() {return 0;} */
macro_test();
printf("}{{ int test(args) {};");
return NULL;
}
$@1$
some_typedef_t *test(void) {
$%2$
macro_test();
printf($^3$);
return NULL;
}
Алгоритм	построения	графа	зависимостей	(3)
• Осуществляется	поиск	в	исходном	коде	на	элементов	следующих	
типов:	typedef,	enum,	structure,	global,	declaration,	function
• Каждому	элементу	из	этих	множеств	присваивается	уникальный	
идентификатор	(используется	для	обозначения	узла	в	графе)
id:	1idkfa
type:	struct
name:	hell
id:	2iddqd
type:	function
name:	kill
id:	4iddt
type:	global
name:	cyberdaemon
Id:5idfa
type:	declaration
name:	kill_em_all
id:	3idclip
type:	typedef
name:	ptr_to_hell_t
Id:5idmypos
type:	enum
name:	my_kill_list
Алгоритм	построения	графа	зависимостей	(4)
• У	каждого	элемента	выделяется	ряд	атрибутов
• Общие:	имя,	содержимое
• Специфичные:	поля	у	структур,	константы	у	enum
• Множество	идентификаторов (ids)
• Множество	меток (tags)
some_typedef_t *test(void) {
$%2$
macro_test();
printf($^3$);
return NULL;
}
struct security_operations {
void (*skb_owned_by) (struct sk_buff *skb);
int (*key_alloc) (struct key *key);
void (*key_free) (struct cred *cred);
};
Алгоритм	построения	графа	зависимостей	(5)
• Создаётся	глобальные	хеш элементов
• В	ключах	– метки	из	множеств	идентификаторов
• В	значениях	– сами	объекты
• Коллизии
• Создаётся	вложенный	хеш к	типом	элемента	в	качестве	ключа	
(Hash::Ordered)
• Создаётся	пустой	ориентированный	граф,	куда	вносятся	все	
элементы	(изолированные	вершины	могут	быть)	(Graph::Directed)
• На	основе		таблицы	допустимости	вхождений	элементов,	
индекса,	и	множества	меток	строятся	связи	между	вершинами	
графа
Фильтр	
допустимости	
зависимостей	
элементов
Фильтр	
допустимости	
зависимостей	
элементов
Фильтр	
допустимости	
зависимостей	
элементов
Что	можно	реализовать	на	этой	основе (1)
Анализ сложности	функций,	составление	отчетов
Что	можно	реализовать	на	этой	основе (2)
Интерактивная	карта	исходных	кодов	с	собранными	
метриками
LIVE	DEMONSTRATION
https://youtu.be/AuUsaleib9M
Что	можно	реализовать	на	этой	основе (3)
Diff версий	для	графа	вызовов	(callgraph)
Green – added
Red – deleted
Black – unchanged
Что	можно	реализовать	на	этой	основе (4)
Вывод	только	отдельных	функций	с	их	зависимостями	
• Вывод	отдельных	функций	с	их	зависимостями (gcc -c)
• Выделение	подграфа
• Разрешение	циклов
• Функция	<->	Функция,	Структура	<-> Структура,	…
• Топологическая	сортировка	для	вывода
Что	можно	реализовать	на	этой	основе (4)
Вывод	только	отдельных	функций	с	их	зависимостями	
LIVE	DEMONSTRATION
SELinux Callgraph sel_netport_sid_slow function
https://asciinema.org/a/186080
Что	можно	реализовать	на	этой	основе (5)
Обратный	перенос	изменений
LIVE	DEMONSTRATION
SELinux Callgraph sel_netport_sid_slow function
https://asciinema.org/a/186083
Чего	нельзя	реализовать	на	этой	основе
Syntactical	Grep	&&	Semantic	Patch
Использование	макроса	
ARRAY_SIZE
Аллоцирование
очищенного	буфера
Coccinelle:	http://coccinelle.lip6.fr/
Pfff:	https://github.com/facebook/pfff
Сложности	(1)
• Сочетание	макросов	и	кода	на	Си	в	глобальных	объявлениях	
(нужно	явно	добавлять	идентификаторы	в	глобальные	
переменные)
#define GFS2_ATTR(name, mode, show, store) 
static struct gfs2_attr gfs2_attr_##name = 
__ATTR(name, mode, show, store)
GFS2_ATTR(freeze, 0644, freeze_show, freeze_store);
Сложности	(1)
• Сочетание	макросов	и	кода	на	Си	в	глобальных объявлениях	
(нужно	явно	добавлять	идентификаторы	в	глобальные	
переменные)
#define GFS2_ATTR(name, mode, show, store) 
static struct gfs2_attr gfs2_attr_##name = 
__ATTR(name, mode, show, store)
GFS2_ATTR(freeze, 0644, freeze_show, freeze_store);
Сложности	(2)
• Сочетание	макросов	и	кода	на	Си	в	глобальных	объявлениях	
(нужно	явно	добавлять	идентификаторы	в	глобальные	
переменные)
#define FAT_IOCTL_FILLDIR_FUNC(func, dirent_type) 
static int func(const char *name, int name_len, 
unsigned int d_type) 
{...}
FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, __fat_dirent)
Сложности	(3)
• Static функции одинаковыми	именами	в	разных	*.c файлах
• Какое-нибудь	хитрое	использование	препроцессора	…
International	Obfuscated	C	Code	Contest
https://www.ioccc.org/
• Но:
Код,	который	проходит
сертификацию,	должен	быть
читаемым…
Почему	Perl?	Гибкость	языка
Practical	Extraction	and	Report	Language
• Atomic	Patterns:
qr/(?>$fret)/
• Recursive	Patterns:
qr'(?>(?<fbody>{(?:(?>[^{}]+)|(?&
fbody))*}))'
• "Possessive"	Quantifiers	(*+,++,...):
m/^${h}*+Ktypedef/
• Conditional	Expression:
qr/(?($condition)$yes|$no)/
• Look-Ahead,	Look-Behind:
qr/b(?!fmt)${varname}b${ptr}/
• Branch	Reset:
qr/(?|$ids)/
• (*PRUNE),	(*SKIP),	(*FAIL):
qr/(?:;|$fbody(*SKIP)(*FAIL))/
…
Почему	Perl?	Модули
Practical	Extraction	and	Report	Language
• Graph,	Hash::Ordered – построение графа,	управление
зависимостями
• Graph::Directed,	Graph::Reader::Dot,	Graph::Writer::Dot – работа с
графами,	генерация dot	файлов для graphviz
• Algorithm::Diff – для возврата изменений в исходный код
• Class::CSV,	Excel::Writer::XLSL,	Text::ANSITable – генерация отчётов
• Module::Loader – реализация плагинов
• Storable – кеширование графа
• Starman,	Plack,	DBD::SQLite – web	версия
Инструменты
• Forge:	https://forge.ispras.ru/projects/astraver-utils/repository
GitHub:	https://github.com/evdenis/spec-utils
• Docker	для	быстрого	развертывания	демонстрации	web	карты
• Интеграция	с	travis-ci,	coveralls,	kritika.io
• SLOC:	8617	(according	to	SLOCCount)
• Тестирование	на	модулях	ядра	(ramfs,	sysfs …):
• Каждая	функция	выводится	в	отдельный	файл	со	своими	зависимостями
• Проверяется	компилируемость
Где	применяются	инструменты
• Разработка	формальных	спецификаций	для	драйверов	на	языке	ACSL	
(специальные	комментарии)
• Интегрирован	в	цикл	проверки	кода	и	спецификаций	(buildbot)
• Используется	для	предоставления	отчётов	в	сертифицирующие	органы
• Проект	AstraVer:	http://www.ispras.ru/technologies/astraver_toolset/
• “Моделирование	и	верификация	политик	безопасности	управления	
доступом	в	операционных	системах”	П.Н.	Девянин et	al.	
http://www.ispras.ru/publications/2018/security_policy_modeling_and_ve
rification/
Вопросы?

More Related Content

PPTX
File input/output in VHDL
PPTX
объектно ориентированная платформа для построения
PDF
JavaScript Базовый. Занятие 02.
PDF
C++ осень 2012 лекция 9
PPTX
New Android NDK & JNI
PDF
JavaScript Базовый. Занятие 04.
PPTX
Современные подходы к SAST
PDF
C# Desktop. Занятие 13.
File input/output in VHDL
объектно ориентированная платформа для построения
JavaScript Базовый. Занятие 02.
C++ осень 2012 лекция 9
New Android NDK & JNI
JavaScript Базовый. Занятие 04.
Современные подходы к SAST
C# Desktop. Занятие 13.

What's hot (20)

PDF
Использование Java Native Interface (JNI) и кросплатформенных C/C++ реализаци...
PDF
Подводные камни System.Security.Cryptography
PPTX
PPTX
Roslyn API : SyntaxTree vs CodeDom, SemanticModel vs Reflection
PDF
Operating Systems Hardening
DOCX
Lecture5
PPTX
Прикладная теория Application Security
PDF
Шишки, набитые за 15 лет использования акторов в C++
PPTX
Философия Application Security
PDF
C++ Базовый. Занятие 02.
PPTX
Bytecode
PPTX
Принципы работы статического анализатора кода PVS-Studio
PDF
C# Desktop. Занятие 04.
PPTX
Статический анализ кода: Что? Как? Зачем?
PDF
C# Desktop. Занятие 01.
PDF
C# Desktop. Занятие 02.
PPTX
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
PDF
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux
PPTX
Поговорим о JavaScript, основы и современные тенденции развития языка
PPTX
«Introduction to malware reverse engineering» by Sergey Kharyuk aka ximerus
Использование Java Native Interface (JNI) и кросплатформенных C/C++ реализаци...
Подводные камни System.Security.Cryptography
Roslyn API : SyntaxTree vs CodeDom, SemanticModel vs Reflection
Operating Systems Hardening
Lecture5
Прикладная теория Application Security
Шишки, набитые за 15 лет использования акторов в C++
Философия Application Security
C++ Базовый. Занятие 02.
Bytecode
Принципы работы статического анализатора кода PVS-Studio
C# Desktop. Занятие 04.
Статический анализ кода: Что? Как? Зачем?
C# Desktop. Занятие 01.
C# Desktop. Занятие 02.
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux
Поговорим о JavaScript, основы и современные тенденции развития языка
«Introduction to malware reverse engineering» by Sergey Kharyuk aka ximerus
Ad

Similar to Practical Language for Extracting Data from Source Codes and Preparing Them for Analysis (20)

PDF
Поиск уязвимостей в программах с помощью анализаторов кода
PDF
Как приручить дракона: введение в LLVM
PDF
Tech Talks @NSU: Как приручить дракона: введение в LLVM
PPTX
Парсим и кодогенерируем для С++ с использованием clang
PDF
Formal verification of operating system kernels
PDF
TMPA-2015: The dynamic Analysis of Executable Code in ELF Format Based on Sta...
PPTX
Эффективный C++
PDF
Лекция 12 (часть 1): Языки программирования семейства PGAS: Cray Chapel
PPTX
Статические анализаторы кода как DevSecOps решение
PDF
static - defcon russia 20
PDF
ОСНОВНЫЕ ПРИНЦИПЫ РЕШЕНИЯ ЗАДАЧИ ПРЕОБРАЗОВАНИЯ ОБЪЕКТНО-ОРИЕНТИРОВАННОГО КОД...
PDF
Максим Лапшин — введение в Erlang
ODP
Intelligent или сделай мне красиво
PDF
Язык параллельного программирования Cray Chapel
PPT
Развитие технологий генерации эксплойтов на основе анализа бинарного кода
PDF
Теория языков программирования некоторые слайды к лекциям
PPTX
Введение в реверс-инжиниринг вредоносного ПО - Сергей Харюк
PPTX
Опыт разработки статического анализатора кода
PPTX
разработка безопасного кода
PPTX
idioms C++
Поиск уязвимостей в программах с помощью анализаторов кода
Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Парсим и кодогенерируем для С++ с использованием clang
Formal verification of operating system kernels
TMPA-2015: The dynamic Analysis of Executable Code in ELF Format Based on Sta...
Эффективный C++
Лекция 12 (часть 1): Языки программирования семейства PGAS: Cray Chapel
Статические анализаторы кода как DevSecOps решение
static - defcon russia 20
ОСНОВНЫЕ ПРИНЦИПЫ РЕШЕНИЯ ЗАДАЧИ ПРЕОБРАЗОВАНИЯ ОБЪЕКТНО-ОРИЕНТИРОВАННОГО КОД...
Максим Лапшин — введение в Erlang
Intelligent или сделай мне красиво
Язык параллельного программирования Cray Chapel
Развитие технологий генерации эксплойтов на основе анализа бинарного кода
Теория языков программирования некоторые слайды к лекциям
Введение в реверс-инжиниринг вредоносного ПО - Сергей Харюк
Опыт разработки статического анализатора кода
разработка безопасного кода
idioms C++
Ad

More from Denis Efremov (8)

PDF
Инструменты тестирования ядра Linux
PDF
CVEhound
PDF
Deductive verification of unmodified Linux kernel library functions
PDF
Health Insurance Support System (Blockchain Based)
PDF
Formal Verification of a Linux Security Module
PDF
Formal verification of C code
PDF
Automation of rule construction for Approof
PDF
How to prove programs
Инструменты тестирования ядра Linux
CVEhound
Deductive verification of unmodified Linux kernel library functions
Health Insurance Support System (Blockchain Based)
Formal Verification of a Linux Security Module
Formal verification of C code
Automation of rule construction for Approof
How to prove programs

Practical Language for Extracting Data from Source Codes and Preparing Them for Analysis