2015-06-19 2 views
1

Я хочу перехватить функцию load_elf_binary в файле fs/binfmt_elf.c, прочитать несколько пользовательских заголовков разделов из файла, переданного ему через аргумент, и установить несколько регистров (eax, ebx, ecx, edx) перед возвратом из функции.Kprobe/Jprobe в середине функции

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

+0

Почему вы пытаетесь сменить регистр здесь? – bdonlan

+0

Я не буду говорить, изменение именно, мне нужно выполнить следующий фрагмент кода '__asm__ __volatile__ (» .byte 0xF1" \t \t \t \t \t \t \t: \t \t \t \t \t \t \t: "а" (е), «b» (ebx), «c» (ecx), «d» (edx), «D» (edi), «S» (esi)), 'чтобы CPU знал, что некоторые файлы ELF должны следует рассматривать как специальные файлы для функции безопасности, над которой я работаю. – bawejakunal

+0

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

ответ

2

Итак, позвольте мне понять, понимаю ли вы, что вы делаете правильно.

Вы изменили процессор (работает в эмуляторе?), Так что инструкция 0xF1 делает какую-то криптографическую вещь. Вы хотите, чтобы load_elf_binary вызывал эту команду при возврате, при этом регистры правильно устанавливали эту инструкцию для выполнения своей магии. Используются некоторые пользовательские разделы.

Это будет очень сложно сделать так, как вы заявляете. Есть несколько основных проблем:

  1. Я не уверен, что ваша модель угрозы, но если ваша магия инструкция CPU просто расшифровывает отображенные данные непосредственно вам изменять страницы в кэше Linux страницы, и дешифрованный код или данные будут видны другим процессам, которые mmap эти страницы.
  2. Кроме того, если ядро ​​освобождает страницы позже, зашифрованные данные будут перезагружены в память, что приведет к сбоям в непредсказуемое время.
  3. Если какой-то процесс замаскирует эти страницы, дешифрованные данные будут сброшены на диск, оставив на диске смешанные дешифрованные и зашифрованные данные.
  4. Если вы используете JProbe, ваш обратный вызов вызывается при входе в функцию, что слишком рано в любом случае.

В целом, это не будет работать слишком хорошо, как вы заявите это.

Лучшим подходом может быть определение вашего собственного binfmt (или замена обратного вызова load_binary в elf_format). Затем binfmt может загружать двоичный файл любым способом. Если вы хотите использовать существующий загрузчик ELF, вы можете делегировать load_elf_binary, а при возврате делать все, что вам нужно, чтобы манипулировать загруженным процессом, без какого-либо из этих файлов JProbe.

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

+0

Это часть исследовательский проект, предлагающий новую архитектуру как расширение существующей архитектуры архитектуры x86, все проблемы обработки страниц, о которых вы упомянули, уже позаботились, на самом деле логика изменения самой загрузки ELF также работала при реализации в 'fs/binfmt_elf.c', просто так, поскольку в ядре было всего около 300 строк кода, я изучаю его как модуль ядра, так что пользователю не нужно перекомпилировать все ядро ​​для таких небольших изменений. Суть в том, чтобы оставить ядро ​​как можно более неизменным. – bawejakunal

+0

@bawejakunal честно, когда вы говорите о введении новых архитектурных примитивов, подобных этому, вам, вероятно, стоит подумать о патче ядра, а не о коде ядра ядра, например:/Но в этом случае подумайте о регистрации нового двоичного формата в качестве модуля – bdonlan

+0

. слишком глубоко в этом, но ваши усилия действительно заметны, и да, как вы предположили, что мы изначально перешли на патч ядра (изменяя load_elf_binary минимально), но во время одного из обзоров статей мы получили комментарий, который перекомпилирует все ядро ​​только для пара сотен строк кода - это слишком много усилий: | В любом случае, я как бы отбросил прочь, я реализовал эту вещь, используя вчерашние обработчики ввода и возврата kprobes. – bawejakunal