Автор: Энди Ли

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

При проверке кода мне нужно помнить о взаимосвязях между различными частями кода. Когда этих отношений слишком много, я не могу легко их запомнить. Вот почему я разработал Call Map — чтобы помочь вам понять смысл кода, отражая его естественную структуру.

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

Для IDE и редакторов характерно иметь возможность переходить к определениям и использованиям; несмотря на это, граф вызовов остается невидимым и неявным. Эти IDE и редакторы часто сосредотачивают явное представление кода только на дереве каталогов и тексте. Если кто-то хочет отслеживать путь через граф вызовов, он должен вручную записывать каждый переход. Это медленно, поэтому я не делаю этого, если у меня нет веской причины. Но затем, когда я нахожу интересный путь, я часто лишь частично помню этот путь и должен возвращаться по своим следам. С Call Map я обнаружил, что больше не теряюсь (каламбур).

Установка

Чтобы использовать Call Map, вам понадобится Python 3.5 с установленным PyQt5.

Вы можете получить Call Map на https://github.com/nccgroup/call_map.

Чтобы установить его, запустите:

# from the directory where you want to put the call_map source code
git clone https://github.com/nccgroup/call_map
cd call_map
pip3 install -e .

Начиная

В следующем примере я буду использовать библиотеку toolz 1 в качестве цели для исследования, так как это то, что вы установили как зависимость от Call Map.

Перейдите в новый каталог для экспериментов и запустите Call Map в первый раз, выполнив:

# -d -- project directory (will be created if it does not exist)
# -m -- modules to inspect
call_map -d cm_proj -m toolz

Это запускает call_map, загружает модуль, указанный в командной строке, и сохраняет состояние проекта Call Map в каталоге cm_proj. Вы должны увидеть пакет toolz в правом верхнем углу виджета карты.

Если вы закроете карту вызовов, вы можете снова открыть проект с помощью:

call_map -d cm_proj

Те же модули и скрипты будут готовы к проверке. Другие настройки также будут сохранены.

Для получения дополнительной справки и сведений о других параметрах, например о том, как проверить пакеты, которые не установлены в вашей среде Python (возможно, нацелены на другую версию Python), выполните:

call_map -h

Навигация по диаграмме вызовов

Виджет карты в левом верхнем углу представляет график вызовов. Первый крайний левый столбец — это список модулей и скриптов, которыми может управлять пользователь. Продолжая пример из предыдущего раздела, нажмите toolz, затем functoolz, затем compose. Теперь вы должны увидеть:

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

Вызывающие объекты отмечены , подэлементы отмечены , а вызываемые объекты не отмечены. Классы обозначаются префиксом c:, модули обозначаются префиксом m:, а функции не имеют префикса.

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

Если вы выберете вызов, местоположение вызова будет выделено. После выбора вызова, если вы хотите увидеть соответствующее определение, выберите элемент [sig] в следующем столбце.

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

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

Закладки

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

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

На вкладке закладки (json) ваши закладки отображаются в виде объекта JSON, поэтому вы можете легко копировать их и делиться ими.

Рабочий процесс

Карта вызовов предназначена для использования в сочетании с редактором. Текстовое представление задумано как простое средство предварительного просмотра и не имеет функций навигации и поиска, которые можно ожидать от текстового редактора. Вы можете нажать одну из кнопок Открыть в информационном виджете в левом нижнем углу, чтобы открыть соответствующий путь в редакторе. Поведение настраивается пользователем. Популярные редакторы, такие как Vim и Emacs, можно запускать как серверы, и вы можете настроить Call Map для отправки им команды на открытие файлов с определенными номерами строк.

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

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

Дорожная карта

На данный момент карта вызовов поддерживает только анализ кода Python. Я хотел бы добавить поддержку других языков, вероятно, через Language Server Protocol.

Я надеюсь, что Call Map может стать надежной платформой для более глубокого анализа. Я планирую добавить функции запросов, чтобы помочь обнаружить проблемы безопасности в коде, начиная с простых функций поиска и фильтрации и заканчивая более сложными уровнями. Например, запрос может быть указан для путей графа вызовов, которые начинаются с процедуры, принимающей пользовательский ввод, и заканчиваются определенной конфиденциальной функцией, с ограничением, что ввод не проходит через конкретную функцию очистки.

  1. Библиотека функционального программирования. См. https://github.com/pytoolz/toolz.

Первоначально опубликовано на www.nccgroup.trust.