Пример конфигурационного файла module.cfg:
# module.cfg
[Image1]
type=KERNEL
host_path=vmlinux
coverage=False
map=System.map
textstart=0xffffffff81000000
[Image2]
type=USER
host_path=exe/dpkg
coverage=True
debuginfo=exe/dpkg.dbg
[Image3]
type=USER
host_path=exe/apt-get
coverage=True
[Image4]
type=USER
host_path=exe/cat
coverage=True
debuginfo=exe/cat-8.32-31.fc35.x86_64.debug
tieddebug=exe/dwp
vmidb=vmidb/Image4.bin
[Image5]
type= PYTHON
host_path=lib/python3.9
guest_path=/usr/bin/python3.9
coverage=False
debuginfo=lib/02f8a561c3abdb9c8d8c859d4243bd8c3f928f.debug
vmidb=vmidb/Image5.binКонфигурационный файл содержит набор секций с префиксом Image.
В каждой такой секции описывается отдельный бинарный файл.
В этой секции могут быть объявлены следующие поля: type, host_path, guest_path, coverage, map, textstart, debuginfo, tieddebug, vmidb.
Поле type
Для каждого раздела типа Image обязательно нужно указать его тип, который может быть одним из следующих:
USER: пользовательский модульKERNEL-- модуль ядраPYTHON-- модуль PythonJAVA-- модуль JavaCSHARP-- модуль C#SHARED_LIBRARY-- модуль разделяемой библиотеки
Обычно это поле заполняется автоматически либо при создании конфигурационного файла, либо при загрузке отладочной информации.
Поля host_path и guest_path
Каждый раздел типа Image обязательно должен содержать хотя бы одно из полей host_path или guest_path.
host_path-- путь к бинарному файлу в хостовой системеguest_path-- путь к бинарному файлу в гостевой системе
Рекомендуется использовать guest_path, так как указание host_path требует дополнительного этапа анализа -- поиска модуля в гостевом образе.
Поле coverage
Для каждого раздела типа Image обязательно должен быть указать флаг coverage, который отвечает за попытку выгрузки исходного кода
для данного бинарного файла (необходима для дальнейшего сбора покрытия кода). По умолчанию coverage установлен в значение "истина"
для всех пользовательских модулей.
Поля map, debuginfo и tieddebug
-
map-- содержит путь к файлу с символьной информацией, сгенерированной компилятором или дизассемблером IDA (при использовании IDA для генерации map файлов нужно выставлять галочку Segmentation information). -
debuginfo-- указывает путь к ELF-файлу, содержащему основную отладочную информацию. (Получить информацию о местоположении этого файла можно с помощью командыreadelf -wk <ваш путь к бинарному файлу>) -
tieddebug-- указывает путь к ELF-файлу, который содержит альтернативные отладочные символы, дополнительно к тем, что указаны вdebuginfo. (Получить информацию о местоположении этого файла можно с помощью командыreadelf -wk <ваш путь к файлу с основной отладочной информацией>)
Эти поля следует использовать, если вы предоставляете бинарный файл без отладочной информации и хотите получить более качественный анализ, например, для отображения имен функций в SNatch.
Поле textstart
При указании поля map может быть задано поле textstart.
Как правило, нет необходимости определять textstart вручную, потому что это просходит автоматически.
В случае, если Natch не сможет определить смещение, будет выведено сообщение.
Поле textstart используется, если адреса в символьном файле абсолютные, а в исполняемом файле нет.
Так как модуль может загружаться в разные места памяти, необходимо вычислить смещение каждой функции от начала секции .text.
В поле textstart как раз и указывается адрес начала секции .text.
Это поле нужно в редких случаях, например, для ядерных модулей (см. ниже). В остальных случаях можно ничего не указывать.
Чтобы получить информацию о секциях в исполняемом файле, можно использовать утилиту readelf:
readelf -S <config_name>Пример, когда textstart необходимо указывать:
map-файл:
ffffffffa0000bed t cleanup_module
ffffffffa00008c2 t logring_syslog_write_raw
ffffffffa0000a4b t init_module
ffffffffa000098d t logring_syslog_write
вывод утилиты readelf:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000000000000 00000040
0000000000000c8c 0000000000000000 AX 0 0 4
Нас интересуют секции типа PROGBITS. Если у них указан нулевой адрес, то их не получится
сопоставить с map-файлом при его загрузке в Natch.
Поэтому необходимо вручную определить адрес секции .text.
Пример, когда textstart не нужен:
map-файл:
00000006:000000000000C000 .init_proc
00000007:000000000000C030 .wget_netrc_db_free
00000007:000000000000C040 .wget_bar_update
00000007:000000000000C050 .seteuid
00000007:000000000000C060 .chdir
00000007:000000000000C070 .fileno
00000007:000000000000C080 .wget_list_free
00000007:000000000000C090 .dup2
00000007:000000000000C0A0 .printf
вывод утилиты readelf:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[11] .init PROGBITS 000000000000c000 0000c000
0000000000000017 0000000000000000 AX 0 0 4
Адрес секции здесь указан и он соответствует адресам, записанным в map-файле,
поэтому параметр textstart можно не указывать.
Поле vmidb
Отладочная и символьная информация из исполняемых файлов может быть заранее разобрана и сохранена
во время работы конфигурационных скриптов. Путь к полученному хранилищу записывается в поле vmidb.
Данное поле заполняется автоматически и не требует ручного вмешательства или корректировки.