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