Я хотел бы узнать больше о функциях ptrace с двоичными файлами x86_64, инструкциях по разборке.Цель состоит в том, чтобы проверить, является ли байт одним из префиксов инструкций.
Я нашел некоторую информацию в Руководстве разработчика программного обеспечения для архитектур Intel® 64 и IA-32 * (том 2, глава 2).
В разделе 2.1.1 INSTRUCTION PREFIXES
показаны следующие префиксы:
- [
0x26
] Переопределение сегмента ES - [
0x36
] Префикс переопределения сегмента SS - [
0x2E
] Префикс переопределения сегмента CS или Ветвь не занята - [
0x3E
] Префикс переопределения сегмента DS или Взятая ветвь - [
0x64
] Префикс переопределения сегмента FS - [
0x65
] Префикс переопределения сегмента GS - [
0x66
] Префикс переопределения размера операнда - [
0x67
] Префикс переопределения размера адреса - [
0xF0
] Префикс LOCK - [
0xF2
] Префикс REPNE / REPNZ или Префикс BND - [
0xF3
] Префикс REP или REPE / REPZ
Визуально, этот график показывает префиксы желтым цветом.
Если я хочу знать, еслибайт это префикс, попробуючтобы быть эффективным и проверить, можно ли выполнять двоичные операции.
Если я беру 0x26
, 0x36
, 0x2E
и 0x3E
в качестве группы.Эти числа в базе 2 (00100110
, 00110110
, 00101110
и 00111110
) показывают общую часть: 001XX110
.
Двоичная операция 11100111
(0xE7
)) можно найти, если мой байт находится в этой группе.
Отлично.Теперь, если я возьму вторую группу, которая содержит 0x64
, 0x65
, 0x66
и 0x67
(01100100
, 01100101
, 01100110
, 01100111
), я найду другую общую часть:011001XX
.
Затем можно найти двоичную операцию 11111100
(0xFC
), если байт находится во второй группе.
Проблема возникает из-за оставшихся префиксов инструкций(0xF0
, 0xF2
и 0xF3
): здесь нет общей части.Операция and 11111100
(0xFC
) позволила бы байту 0xF1
.
Одним из решений было бы проверить, не является ли байт 0xF1
.
Итак, возможная реализация в C будет выглядеть следующим образом:
if ((byte & 0xE7) == 0x26) {
/* This `byte` is a ES, SS, CS or DS segment override prefix */
}
if ((byte & 0xFC) == 0x64) {
/* This `byte` is a FS, GS, Operand-size or address-size override prefix */
}
if ((byte & 0xFC) == 0xF0) {
if (byte != 0xF1) {
/* This `byte` is a LOCK, REPN(E/Z) or REP(_/E/Z) prefix */
}
}
Исходя из Intel, я хотел бы, за исключением того, что в этой последней группе можно будет проверить только одну операцию.
Затем, окончательнаявопрос: могу ли я проверить за одну операцию, если байт равен 0xF0, 0xF2 или 0xF3?