Este artículo analiza el uso inusual de las características del modo protegido de la arquitectura x86, para realizar cálculos sin ejecutar instrucciones, es decir, debido a los mecanismos internos del procesador: conmutación de tareas de hardware , administración inteligente de la memoria y lógica no trivial de llamar a un controlador de interrupciones . Como saben , cualquier sistema de cualquier complejidad tiene la completitud de Turing , por lo que no es sorprendente encontrarlo en lugares inesperados en un x86 de evolución natural. Invito bajo el corte a aquellos interesados en perversiones de tan bajo nivel.
Esta publicación se basa en un artículo titulado "La máquina extraña con fallas de página: lecciones de computación sin instrucciones" . Calienta el alma que uno de sus coautores, Sergey Bratus , sea un graduado de Phystech desde hace mucho tiempo . Me enteré de este trabajo por primera vez en el artículo de Gwern Barwen "Sorprendentemente Turing-Complete" , que contiene muchos ejemplos asombrosos de sistemas Turing-complete. Por cierto, parte de él se ha traducido al Habré , aunque solo se asignan tres frases al fenómeno descrito en este artículo.
2013 , x86-64, long mode, . x86 .
, , , " ", . , : -, , , — ( QEMU, ). -, , . , , red pill, , . red pills , "", , , . red pill , , , "" . , , . , . : Neutrino(2016 .), Conficker(2008 .), Rebhip(2011 .), IRC : Phatbot(2008 .), Rbot, SDbot/Reptile, Mechbot, SpyBot ( ). -, . "" unikernel.
"" , , - ? , x86.
IA-32 , . call gates , , . , , — , ; . x86-64 .
, ( , , ), — 32-bit Linux ( ) double fault, , . Double fault , - ; , . , , double fault , , , , Linux , double fault , kernel panic "" . double fault - , triple fault, .
x86 , task-state segment(TSS). , , . EIP
(instruction pointer) — , ESP
(stack pointer) — , CR3
— ( , page directory), EAX
ECX
, .
, , . , , GDT(Global Descriptor Table) — IDT(Interrupt Descriptor Table) — . , , : memory segment descriptor — (, ), TSS descriptor — task-state segment, interrupt-gate descriptor — , , — far call. , — , — .
-
, , , -? , , page fault double fault, 4- . , , ( , x86 ) ESP
4. , ESP
, ? , 32 , double fault-.
. , , EIP
, , 0xFFFFFFFF
. page fault, . , page fault :
if (esp == 0) {
goto double_fault_handler;
} else {
esp -= 4;
goto page_fault_handler;
}
- , … - . , "" . ( IDT GDT) TSS, CR3
, , , , (, TSS, ). IDTR GDTR ( TSS, ) IDT GDT, , "" ⇒ ⇒ ⇒ CR3
⇒ IDT GDT, . IDT TSS, .
movdbz-
, "" :
, "". IDT GDT, .
TSS, , . , TSS
EIP
,ESP
,CR3
.
"" TSS , ( ),
ESP > 0
,ESP
4,ESP
.
CR3
2 ,ESP
TSS, GDT (. Task Register) .
3 , ,
EIP
, , page fault; double fault.
, : rsrc
— ESP
, TSS; rdest
— ESP
, TSS, GDT CR3
TSS. label_zero
— , double fault, label_nonzero
— page fault. ESP
, 4, , .
if (rsrc == 0) {
rdest = rsrc;
goto label_zero;
} else {
rdest = rsrc - 1;
goto label_nonzero;
}
— , movdbz
, move-branch-if-zero-or-decrement (-----). , subtract-and-branch-if-negative (-----), movdbz
( ), - . , , — - Brainfuck movdbz
-.
, movdbz
:
movdbz rdest, rsrc, label_nonzero, label_zero
real-mode A20 high memory, , . , Intel , , , . , ESP
( #SS
— stack-segment fault), . ESP
, 4 "" , 0 1023, 0 4095 ( 4 ). , , .
,
: 4 "destination TSS" ESP
, CR3
. , , ESP
, TSS, -- , . CR3
, , CR3
IDT
, , — "". TSS — , ; , movdbz
. "" TSS ECX
EDX
( TSS ). , TSS ESP
, CR3
TSS c rdest
, .
Busy bit
busy bit, TSS GDT , . , , 5 . , , . , , . , , , , , 8 10, .
: GDT , TSS! GDT 16 , 8 — , , TSS, EAX
ECX
. , TSS EAX
ECX
TSS ( , TSS) busy bit-. , TSS 4 busy bit TSS GDT . IDT GDT — , 8 16 .
, " "? -, , , — red pill, . -, x86, . -, , , , " " , . — " ", "" , . , , .
( ):
-
Implementación por Krister Walfridsson: repositorio Github , descripción general , algunos detalles de implementación
Artículo original "The Page-Fault Weird Machine: Lessons in Instruction-less Computation" , repositorio complementario de Github con implementación del autor
Por supuesto, manuales para desarrolladores de software de arquitecturas Intel® 64 e IA-32