Какова роль неопределенного обработчика исключений (__und_svc) в kprobes?
Я попытался преобразовать kprobe как загружаемый модуль ядра.
Я могу запустить образцы, доступные в samples/kprobes/
папка из дерева ядра.
Если мы настроим kprobes в ядре (CONFIG_KPROBES
), затем svc_entry
макрос будет расширен на 64 байта в __und_svc()
обработчик.
Ссылка: http://lxr.free-electrons.com/source/arch/arm/kernel/entry-armv.S?a=arm#L245
Моя цель не касаясь стороны ядра, сделать kprobe модулем ядра.
поэтому ядро скомпилировано без включения CONFIG_KPROBES. поэтому макрос svc_entry будет расширен на 0 в __und_svc()
Я бы хотел избавиться от этих сомнений.
Если kprobe обрабатывается неопределенное исключение инструкции (только bcos kprobe создан), то почему
__und_svc()
вызывается. какова роль__und_svc()
обработчик по отношению к kprobes??Если 64-байтовая память является обязательной, то как распределить ее без компиляции ядра. т.е. как это сделать динамически.??
Пожалуйста, поделитесь своими знаниями.
1 ответ
Вы можете не получить ответы, так как ваше понимание вещей не очень хорошее, и кому -то из списка linux-arm-kernel потребуется некоторое время, чтобы ответить. Прочитайте kprobes.txt и детально изучите архитектуру ARM.
Если kprobe обрабатывается неопределенное исключение инструкции (только bcos kprobe создан), то почему
__und_svc()
вызывается. какова роль__und_svc()
обработчик по отношению к kprobes?
На ARM, режим 0b11011
это неопределенный режим инструкции. Поток, когда происходит неопределенная инструкция,
- lr_und = ПК инструкции undef + 4
- SPSR_und = CPSR режима, в котором произошла инструкция.
- Измените режим на ARM с отключенным прерыванием.
- ПК = векторная база + 4
Главная векторная таблица четвертого шага находится по адресу __vectors_start
и это просто ветвится vector_und
, Код представляет собой макрос называется vector_stub
, который принимает решение позвонить либо __und_svc
или же __und_usr
, Стек - это страница 4/8 КБ, зарезервированная для каждого процесса. Это страница ядра, которая содержит структуру задачи и стек ядра.
kprobe работает путем размещения неопределенных инструкций по кодовым адресам, которые вы хотите исследовать. Т.е. он включает неопределенный обработчик инструкций. Это должно быть довольно очевидно. Это вызывает две процедуры, call_fpe
или же do_undefinstr()
, Вы заинтересованы во втором случае, который получает код операции и звонки call_undef_hook()
, Добавить хук с помощью register_undef_hook (); который вы можете увидеть arch_init_kprobes()
, Основной обратный звонок kprobe_handler
называется с struct pt_regs *regs
это дополнительная память, зарезервированная в __und_svc
, Обратите внимание, например, kretprobe_trampoline()
, который играет трюки со стеком, который он выполняет в настоящее время.
Если 64-байтовая память является обязательной, то как распределить ее без компиляции ядра. т.е. как это сделать динамически.?
Нет. Вы можете использовать другой механизм, но вам может потребоваться изменить код kprobes. Скорее всего, вам придется ограничить функциональность. Также возможно полностью переписать кадр стека и зарезервировать дополнительные 64 байта после свершившегося факта. Это не распределение, как в kmalloc()
, Это просто добавление / вычитание числа из указателя стека супервизора. Я предполагаю, что код перезаписывает адрес возврата из неопределенного обработчика для выполнения в контексте (ISR, нижняя половина / IRQ потока, work_queue, задача ядра) адреса kprobed. Но есть, вероятно, дополнительные проблемы, с которыми вы еще не сталкивались. Если arch_init_kprobes()
никогда не вызывается, то вы всегда можете сделать заказ в __und_svc
; он просто съедает 64 байта стека, что повышает вероятность переполнения стека ядра. Т.е. поменяй,
__und_svc:
@ Always reserve 64 bytes, even if kprobe is not active.
svc_entry 64
arch_init_kprobes()
это то, что на самом деле устанавливает функцию.