Инструкции cmpxchg esp, eax совпадают с инструкциями icebp? - PullRequest
0 голосов
/ 07 февраля 2020

После этого вопроса мы знаем, что icebp инструкция похожа на int1 инструкцию.

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

global _start
section .text

_start:

cmpxchg esp, eax

Сборка с: nasm -f elf example.asm && ld -o example example.o

Когда я выполню отладку, инструкция выполнит инструкцию icebp

% gdb -q cmpxchg
Reading symbols from cmpxchg...(no debugging symbols found)...done.
gdb-peda$ r
Starting program: /home/user/assembly/cmpxchg 

Program received signal SIGTRAP, Trace/breakpoint trap.

[----------------------------------registers-----------------------------------]
EAX: 0xbfffee18 --> 0x3fffcc2b 
EBX: 0x0 
ECX: 0x0 
EDX: 0x0 
ESI: 0x0 
EDI: 0x0 
EBP: 0x0 
ESP: 0xbfffee00 --> 0x1 
EIP: 0x8048093 --> 0x12ff
EFLAGS: 0x206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x804808e:   add    BYTE PTR [eax],al
   0x8048090:   add    al,0x0
   0x8048092:   icebp  
=> 0x8048093:   call   DWORD PTR [edx]
   0x8048095:   add    BYTE PTR [eax],al
   0x8048097:   add    BYTE PTR [eax],al
   0x8048099:   add    BYTE PTR [eax],al
   0x804809b:   add    BYTE PTR [eax],al
No argument
[------------------------------------stack-------------------------------------]
0000| 0xbfffee00 --> 0x1 
0004| 0xbfffee04 --> 0xbffff013 ("/home/user/assembly/cmpxchg")
0008| 0xbfffee08 --> 0x10 
0012| 0xbfffee0c --> 0xbffff044 ("XDG_SEAT=seat0")
0016| 0xbfffee10 --> 0xbffff053 ("XDG_SESSION_ID=c2")
0020| 0xbfffee14 --> 0xbffff065 ("LC_IDENTIFICATION=id_ID.UTF-8")
0024| 0xbfffee18 --> 0x3fffcc2b 
0028| 0xbfffee1c --> 0xbffff0a6 ("DISPLAY=:0")
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGTRAP
0x08048093 in ?? ()
gdb-peda$

My вопрос, как это случилось?

1 Ответ

1 голос
/ 07 февраля 2020

Вы забыли выполнить один шаг, чтобы увидеть выполнение инструкции cmpxchg esp, eax. Выполнение шло намного дальше, пока не случилось, что он набрал опкод f1.

Используйте starti, чтобы начать с первой инструкции в пользовательском пространстве, затем si.

Обычно ваш процесс будет зависать, если вы позволите выполнению попасть в набор 00 00 байтов, потому что он декодируется как add [eax], al и EAX = 0 в начале Linux stati c исполняемого файла. (Вы не удосужились сделать системный вызов _exit со своего _start.)

Но cmpxchg esp, eax устанавливает EAX в качестве допустимого указателя. (Неявный операнд EAX изначально не был равен ESP, поэтому происходит « очистка ZF и загрузка r / m32 в EAX ». Тот факт, что EAX был задан как явный исходный операнд, не имеет значения, кстати.)

Выполнение продолжается с помощью набора 00 инструкций, которые декодируются как 00 00 add. Затем он попадает в показанный вами блок, где первой ошибочной инструкцией оказывается байт f1, который находился там в исполняемом файле где-то после конца раздела .text.


Конечно cmpxchg не выполняется как icebp / int1. И ваша разборка даже невозможна, если вы были на самом деле по инструкции cmpxchg. Длина cmpxchg составляет 3 байта, но расстояние между адресами для смежных инструкций составляет всего 1 байт. Так что, возможно, GDB не расшифровывает его.

...