Ищем способ перехватить инструкции CPUID

Я ищу аккуратный способ ловушки и возни с инструкцией CPUID процессов Linux. Поиграл с ptrace() и исправил все коды операций cpuid во всех исполняемых областях mmap'ed, созданных процессом, заменив их на int3. Не очень хорошо сработало, поскольку байты кода операции CPUID довольно часто появляются как части других более длинных кодов операций.

Итак, в основном я ищу способ, который позволит мне установить точку останова не на конкретный адрес памяти, а вместо этого на каждый вызов кода операции. У кого-нибудь есть хорошая идея, как это сделать?


person user175104    schedule 17.09.2009    source источник
comment
Для записей (насколько не нужен ответ OP), поскольку процессор IvyBridge Intel на самом деле поддерживает CPUID неисправность.   -  person mirh    schedule 24.03.2020


Ответы (2)


В общем, единственный способ сделать это в произвольном коде x86 и уловить все угловые случаи:

  • пошагово и проверять каждую инструкцию перед ее выполнением (PTRACE_SINGLESTEP, см. ниже); или
  • полностью эмулировать набор инструкций x86.

Первый способ, пожалуй, лучше.

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

Чтобы реализовать пошаговый метод, каждый раз, когда трассируемый процесс останавливается, вы должны использовать PTRACE_GETREGS для получения дочерних регистров, а затем использовать значение дочернего регистра %eip в качестве адреса для передачи в PTRACE_PEEKTEXT, получая следующее слово для выполнения. Изучите это слово, чтобы увидеть, является ли оно инструкцией CPUID. Если это так, эмулируйте инструкцию, изменив набор дочерних регистров (включая продвижение %eip за инструкцией CPUID). Затем вызовите PTRACE_SINGLESTEP, чтобы продолжить процесс.

person caf    schedule 18.09.2009
comment
Intel SDE в основном делает для вас первый метод ( а с другой стороны, он также может эмулировать более или менее все из SSE3 и далее). - person mirh; 24.03.2020

Нет простого хорошего способа сделать это, о котором я знаю.

Неприятный способ может состоять в том, чтобы использовать API сценариев GDB на языке python для автоматического пошагового выполнения программы, проверяя каждую инструкцию перед ее выполнением.

Еще один неприятный способ — взять исходный код чего-то вроде Bochs, эмулятора x86 с открытым исходным кодом, и изменить это делает то, что вы хотите, когда выполняются инструкции, которые вас интересуют.

person moonshadow    schedule 17.09.2009