Трассировка вызовов и поведения
Чтобы понять, что делает программа, не обязательно читать каждую её инструкцию — достаточно посмотреть, о чём она просит операционную систему.
Трассировка (tracing) — наблюдение за программой по её внешним вызовам: какие системные вызовы к ядру и какие функции библиотек она дёргает, с какими аргументами и что получает в ответ. Это поведенческий портрет бинарника, снятый «снаружи».
Программа почти ничего не может сделать в одиночку: открыть файл, прочитать сеть, запустить процесс, получить время — для всего этого она обращается к ядру ОС через системные вызовы и пользуется функциями стандартных библиотек. Эти обращения — узкое горлышко, через которое видно намерения программы. Поймав их поток, аналитик понимает поведение целиком, даже не разбирая логику по ассемблеру. Для разбора подозрительного образца это часто первый шаг: быстро увидеть «что трогает на диске, куда ходит по сети, что запускает».
Зачем это знать защитнику
Поведенческий анализ — основа разбора вредоносного ПО и threat hunting. Сигнатуры можно обойти, но поведение выдаёт суть: программа, которая массово шифрует файлы пользователя, ведёт себя как вымогатель независимо от того, как написан её код. Понимая, какие системные вызовы соответствуют опасным действиям (запись в автозагрузку, обращение к чужой памяти, исходящие соединения), защитник строит детектирование и правила EDR. Трассировка в лаборатории — способ заранее узнать «индикаторы компрометации» образца.
Два уровня наблюдения: strace и ltrace
На Linux есть два классических инструмента. strace показывает системные вызовы — общение программы с ядром (открытие файлов, чтение/запись, сеть, процессы). ltrace показывает вызовы библиотечных функций — уровень выше, ближе к логике программы (например, обращения к функциям работы со строками или шифрованием). Вместе они дают картину и «что просит у системы», и «какими готовыми кирпичами пользуется».
# Концептуально: запустить программу под наблюдением вызовов
strace ./demo # системные вызовы к ядру
ltrace ./demo # вызовы функций библиотек
strace -f -e trace=network ./demo # только сетевые вызовы, с дочерними процессами
Под Windows прямого аналога нет, но идея та же: поведение наблюдают мониторами активности (файловой, реестровой, сетевой) и средствами sandbox-анализа, которые перехватывают вызовы Windows API. Полезно и фильтровать вывод: реальная программа делает тысячи вызовов, и без фокуса на нужном классе (файлы, сеть, запуск процессов) лента превращается в нечитаемый поток — поэтому опытный аналитик сразу сужает наблюдение до интересующей категории.
Как читать вывод трассировки
Вывод — это лента вызовов с аргументами и результатами. Каждая строка отвечает на вопрос «что программа попросила и что получила». Условный пример того, как это выглядит:
openat(AT_FDCWD, "/etc/passwd", O_RDONLY) = 3
read(3, "root:x:0:0:...", 4096) = 1234
connect(4, {sa_family=AF_INET, ...}) = -1 ECONNREFUSED
execve("/bin/sh", ["sh", "-c", "..."], ) = 0
Даже не зная внутренностей программы, по такой ленте видно сюжет: открыла файл с учётками, попыталась куда-то подключиться (отказано), запустила оболочку. Для аналитика это готовые зацепки: какие файлы важны, есть ли сетевая активность, порождает ли процессы.
Своя мини-трассировка как пример мышления
Чтобы прочувствовать принцип, не нужен strace — идею «перехвати вызов, залогируй аргументы, передай дальше» легко показать в Python через декоратор. Точно так же концептуально работают перехватчики вызовов:
def trace(func):
def wrapper(*args):
print(f"-> {func.__name__}{args}")
result = func(*args)
print(f"<- {func.__name__} = {result}")
return result
return wrapper
@trace
def add(a, b):
return a + b
add(2, 3)
Вывод:
-> add(2, 3) <- add = 5
Реальные трассировщики делают то же на уровне ОС: становятся «прослойкой» между программой и системой, записывая каждый вызов с аргументами и результатом. Принцип идентичен — отличается лишь то, что перехватывается не функция Python, а граница процесс/ядро.
Как это работает под капотом
strace опирается на уже знакомый механизм ptrace: ядро уведомляет трассировщик на каждом системном вызове отлаживаемого процесса — до и после, — и тот читает номер вызова и аргументы из регистров. ltrace перехватывает вызовы динамических библиотек, подменяя записи в таблице переходов (PLT/GOT) так, чтобы управление сначала шло в логирующую обёртку. В обоих случаях программа выполняется как обычно, но каждый её «выход наружу» становится видимым. Цена — заметное замедление и, опять же, наблюдаемые следы: программа может догадаться, что её трассируют.
Как защититься
Для аналитика правила те же, что и с отладчиком: трассировать незнакомый бинарник только в изолированной ВМ без сети (или с контролируемой, перехватываемой сетью) и с откатом из снапшота — иначе образец может реально навредить или «позвонить домой». Для защитника инфраструктуры поведенческая телеметрия (аудит системных вызовов через auditd, Sysmon, EDR) — это рабочий слой обороны: подозрительные последовательности вызовов (массовое чтение и перезапись файлов, запись в автозагрузку, неожиданные исходящие соединения) превращаются в правила оповещения. Для разработчика вывод трезвый: раз поведение наблюдаемо, нельзя прятать секреты в «незаметных» вызовах — что программа делает с системой, всегда можно увидеть.
Юридическое напоминание: запускать и трассировать чужой исполняемый файл, особенно подозрительный, допустимо только в собственной изолированной лаборатории и в рамках законного исследования. Распространение и запуск вредоносного ПО вне таких рамок наказуемы (УК РФ ст. 273).
Итоги
- Трассировка раскрывает поведение программы по её внешним вызовам, не требуя разбора всего кода.
- strace показывает системные вызовы (общение с ядром), ltrace — вызовы библиотечных функций (ближе к логике).
- Лента вызовов с аргументами и результатами читается как сюжет: какие файлы, какая сеть, какие запуски процессов.
- Под капотом — ptrace для системных вызовов и подмена PLT/GOT для библиотечных; программа работает как обычно, но «видна».
- Поведенческая телеметрия (auditd/Sysmon/EDR) — основа детектирования; анализ незнакомого образца — только в изолированной ВМ.