
Este artigo discute o uso incomum dos recursos de modo protegido da arquitetura x86 - para realizar cálculos sem executar instruções, ou seja, devido aos mecanismos internos do processador: troca de tarefas de hardware , gerenciamento de memória inteligente e lógica não trivial de chamar um manipulador de interrupção . Como você sabe , qualquer sistema de qualquer complexidade tem integridade de Turing , então não é surpreendente encontrá-lo em lugares inesperados em um x86 naturalmente evoluído. Eu convido abaixo do corte aqueles interessados em tais perversões de baixo nível.
Esta publicação é baseada em um artigo intitulado "The Page-Fault Weird Machine: Lessons in Instruction-less Computation" . É muito bom saber que um de seus co-autores, Sergey Bratus , é um graduado de longa data da Phystech . Aprendi sobre esse trabalho pela primeira vez no artigo de Gwern Barwen "Surprisingly Turing-Complete" , que contém muitos exemplos incríveis de sistemas Turing-complete. Aliás, parte dela foi traduzida para o Habré , embora apenas três frases estejam alocadas ao fenômeno descrito neste artigo.
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, . -, , , , " " , . — " ", "" , . , , .
( ):
-
Implementação por Krister Walfridsson: repositório Github , descrição geral , alguns detalhes de implementação
Artigo original "The Page-Fault Weird Machine: Lessons in Instruction-less Computation" , repositório Github complementar com implementação do autor
É claro que os manuais do desenvolvedor de software das arquiteturas Intel® 64 e IA-32